はい、part5でございます。
-- 目次 --
まずは2値分類してみる。
ここから主要キャラの分類
- part5 主要キャラで分類問題(未知データに適用するよ編) <--- イマココ
- part5.5 主要キャラで分類問題(改良編)
- part6 主要キャラで分類問題(GPU使ったよ編)
- part7 新規データをFasterRCNNを使って分類させる(むしろ全てはこれのため)
今回は前回の2値分類に少し手を加えて、多値分類をします。
ネトワークなどの根本的な部分は変更ありません。
最終的な出力が10通りになるように変更したくらいです。
あと撫子とか月火とか画像がすごい少なかったので、ガウスノイズとペッパーノイズを加えることにより、
2000枚程度まで、水増ししました。
学習枚数は、
負例: 15000枚
主要キャラたち: 1800枚
です。
ちょっと画像が少ないかな〜。
学習の過程はこんな感じ。
epoch: 1 2016-03-22 00:39:43.913570 train mean loss=1.18005131154, accuracy=0.610652140454 test mean loss=1.80967427409, accuracy=0.540751492506 epoch: 2 2016-03-22 00:46:17.604887 train mean loss=0.766596870978, accuracy=0.741430833116 test mean loss=2.25404204469, accuracy=0.588366806568 epoch: 3 2016-03-22 00:52:58.503691 train mean loss=0.640313144716, accuracy=0.784847951602 test mean loss=1.97074703021, accuracy=0.581267653004 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ epoch: 28 2016-03-22 07:30:14.651147 train mean loss=0.105090085609, accuracy=0.966426435842 test mean loss=4.66628507105, accuracy=0.63786476721 epoch: 29 2016-03-22 07:36:30.702969 train mean loss=0.0999042894729, accuracy=0.968184216734 test mean loss=5.14881660291, accuracy=0.640139633662 epoch: 30 2016-03-22 07:42:46.231465 train mean loss=0.0866300846959, accuracy=0.970117772395 test mean loss=4.49815036958, accuracy=0.648925326096
三時間でスリープに入るよう設定してたら、午前5時くらいに止まってやがった。
そんなことは置いといて・・・
う〜ん。微妙ですね・・・。やはり4層のネットワークではこれくらいが限界なのかな?
とりあえず学習済みモデルを使って未知データに適用させてみます。
おっ!?
前回、暦扱いされていたひたぎさんがちゃんと識別されています!
ちょっと今回はここまでにしといて、part5.5を設けます。
そっちでもっとディープに書き換えたネットワークで学習させる!
なんなら、そっちがメインってことで!目指せAccuracy90%!
3/24追記:
ちょっと待ってくれ!!コード見返したらtrainとtestの枚数が逆になってやがった・・・。
なんだよこのくそみたいなミス。情けない・・・
ってことでそこを修正し、どうせならってことで画像を増やして再学習させます。
負例:訓練用=18000枚、テスト用=4000枚
主要キャラたち:訓練用=3600枚、テスト用=400枚
いつか指摘がいただけるようコードも載せますね。
#coding: utf-8 #必要なライブラリのインポート import cv2 import os import six import datetime import chainer from chainer import optimizers import chainer.functions as F import chainer.links as L import chainer.serializers as S from clf_bake_model import clf_bake import numpy as np #その1 ------データセット作成------ #フォルダは整数で名前が付いています。 #今回0が負例で、1が暦フォルダになっております。 def getDataSet(): #リストの作成 X_train = [] X_test = [] y_train = [] y_test = [] for i in range(0,10): path = "/Users/kentowatanabe/Desktop/bake_detection/img/train/" if i == 0: #othersは15000枚用意します。テスト用には3000枚 cutNum = 22000 cutNum2 = 18000 else: #主要キャラたちは1800枚ずつ。テスト用には300枚 cutNum = 4000 cutNum2 = 3600 imgList = os.listdir(path+str(i)) imgNum = len(imgList) for j in range(cutNum): imgSrc = cv2.imread(path+str(i)+"/"+imgList[j]) #imreadはゴミを吸い込んでも、エラーで止まらずNoneを返してくれます。 #ですので読み込み結果がNoneでしたらスキップしてもらいます。 if imgSrc is None:continue if j < cutNum2: X_train.append(imgSrc) y_train.append(i) else: X_test.append(imgSrc) y_test.append(i) return X_train,y_train,X_test,y_test #その3 ---------学習させる------- def train(): #上で作った関数でデータセットを用意します。 X_train,y_train,X_test,y_test = getDataSet() #このままだとchainerで読み込んでもらえないので、array型にします。 X_train = np.array(X_train).astype(np.float32).reshape((len(X_train),3, 50, 50)) / 255 y_train = np.array(y_train).astype(np.int32) X_test = np.array(X_test).astype(np.float32).reshape((len(X_test),3, 50, 50)) / 255 y_test = np.array(y_test).astype(np.int32) # 諸々の初期設定 model = clf_bake() optimizer = optimizers.Adam() optimizer.setup(model) epochNum = 30 batchNum = 50 epoch = 1 # 学習とテスト while epoch <= epochNum: print("epoch: {}".format(epoch)) print(datetime.datetime.now()) trainImgNum = len(y_train) testImgNum = len(y_test) #---学習--- sumAcr = 0 sumLoss = 0 perm = np.random.permutation(trainImgNum) for i in six.moves.range(0, trainImgNum, batchNum): #ランダムにbatchNumの数だけ抽出する X_batch = X_train[perm[i:i+batchNum]] y_batch = y_train[perm[i:i+batchNum]] optimizer.zero_grads() loss, acc = model.forward(X_batch, y_batch) loss.backward() optimizer.update() sumLoss += float(loss.data) * len(y_batch) sumAcr += float(acc.data) * len(y_batch) print('train mean loss={}, accuracy={}'.format(sumLoss / trainImgNum, sumAcr / trainImgNum)) #---テスト--- sumAcr = 0 sumLoss = 0 perm = np.random.permutation(testImgNum) for i in six.moves.range(0, testImgNum, batchNum): X_batch = X_test[perm[i:i+batchNum]] y_batch = y_test[perm[i:i+batchNum]] loss, acc = model.forward(X_batch, y_batch, train=False) sumLoss += float(loss.data) * len(y_batch) sumAcr += float(acc.data) * len(y_batch) print('test mean loss={}, accuracy={}'.format( sumLoss / testImgNum, sumAcr / testImgNum)) epoch += 1 #モデルの保存 S.save_hdf5('model'+str(epoch+1), model) train()
枚数増やしたからかなり時間かかりそうです。
学習終わったら、また記事更新します。
-- 目次 --
まずは2値分類してみる。
ここから主要キャラの分類
- part5 主要キャラで分類問題(未知データに適用するよ編) <--- イマココ
- part5.5 主要キャラで分類問題(改良編)
- part6 主要キャラで分類問題(GPU使ったよ編)
- part7 新規データをFasterRCNNを使って分類させる(むしろ全てはこれのため)
p.s. ってことでしばしお待ちを。