自分で集めたデータを使った画像認識
はじめに
あけましておめでとうございます.
前回までに、Flickrを使ってPC上のフォルダに自分で画像データをダウンロードし、それを学習で使えるデータに変換することを行いました.
今回は、これら学習データを使った画像認識を行いたいと思います.前提として、画像データは学習用のデータに変換が済んでいるとします.
学習データの概要:
- 用意した画像データはFlickrから集めたネコ科の動物の画像(8クラス、各280枚)
- 用意した画像データのうち75%を訓練用データ(X_trainおよびy_train)、25%をテストデータ(X_testおよびy_test)とする
- 入力データXは、正規化済
- ラベルデータyはone-hot vecrot化済
前回、前々回の記事
shirakonotempura.hatenablog.com
shirakonotempura.hatenablog.com
ネットワークの構築と学習
では、早速Kerasを用いて畳み込みニューラルネットワーク(CNN)の構築を行っていきます. KerasによるCNNの構築は、以前行いましたのでそれをほぼそのまま転用していきます.
ネットワークの構築
以前コチラの記事で書いたのとほぼ同じなのですが、最初の畳み込み層の定義のところで、input_shape = X.shape[1:]
として入力の配列サイズから直接データサイズを読むようにしています.
コンパイル時の各設定も以下のように特に変更していません.
- 損失関数はcategorilca_crossentropy
- 最適化手法はAdadelta
- 評価関数はaccuracy
# CNNの構築(model_s) model = Sequential() model.add(Conv2D(32, kernel_size=(3, 3), padding="same",activation='relu', input_shape=X.shape[1:])) model.add(Conv2D(64, (3, 3), padding="same",activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(128, activation='relu')) model.add(Dropout(0.5)) model.add(Dense(num_classes, activation='softmax')) # modeのコンパイル model.compile(loss="categorical_crossentropy", optimizer=keras.optimizers.Adadelta(), metrics=['accuracy'])
学習および結果
これまでどおり、model.fit()を使って学習を行います.
訓練データのうち、20%を検証用データとし、エポック数(epochs)は100としています.
log = model.fit(X_train, y_train, batch_size=50, epochs=epochs, verbose=1, validation_split = 0.2)
結果ですが学習後のテストデータに対する精度は、44.8%と惨敗.
グラフからも途中から検証データの精度は上がっていないし、Loss関数も上がっており学習がうまくいっていないことが明らかです.一方訓練データに対する精度はほぼ100%に近くなっていることから、おそらくこれが過学習(Over Fitting)というやつなのでしょう.
まとめ
今回は、自分で作成した学習用データを使った画像識別を行いました.得られた結果に関しては散々なものなのですが、とりあえずこのやり方がスマートかどうかは別として.『自分で画像を集める→画像を学習用データに変換する→DLで学習を行う』という一連の流れを行うことができました.
coraboratory上のnoteは コチラに載せています.
今回の結果が過学習となった原因として単純に思いつくものとしては、画像の枚数が少ないことが挙げられます.けっこう集めたつもりですが、MNISTの合計70000枚の学習データに比べれば少ないと言わざるを得ません.この対策として画像の水増しという方法が既に用意されています.またモデルの設計が良くないということも考えられるのですが、それについては既存の学習済モデルを利用する転移学習なるテクニックがあるようです.次回以降、そのあたりを順に整理しながら、精度の向上を図っていきたいと思います.