#1.背景
興味本位でKerasを使った画像認識を実装してみたところ、思いの外簡単だったので、より高精度なモデルを実装したく友人のススメでVGG16を使ってみることにした。
初学者なので、詳しいことは調べながらやってみる。
今回はりんごの王林の画像を使用して、品種まで当てられるのか評価を行う。
あくまでもメモ。
#2.そもそもVGG16ってなに?
VGG16というのは,「ImageNet」と呼ばれる大規模画像データセットで学習された,16層からなるCNNモデルのことです.2014年に発表されました.様々な研究で利用されている,有名な学習済みモデルの1つです.ImageNetで学習されたモデルには他にAlexNet,GoogLeNet,ResNetがあります.
https://www.y-shinno.com/keras-vgg16/
ここででているAlexNet,GoogLeNet,ResNetとの比較は以下が参考になる。
(引用元:http://thunders1028.hatenablog.com/entry/2017/11/01/035609)
2014年のILSVRCで2位になった、オックスフォード大学のVGGチームのネットワーク。AlexNetをより深くした、畳み込み層とプーリング層から成るどノーマルなCNNで、重みがある層(畳み込み層や全結合層)を16層、もしくは19層重ねたもの。それぞれVGG16やVGG19と呼ばれる。
小さいフィルターを持つ畳み込み層を2〜4つ連続して重ね、それをプーリング層でサイズを半分にするというのを繰り返し行う構造が特徴。大きいフィルターで画像を一気に畳み込むよりも小さいフィルターを何個も畳み込む(=層を深くする)方が特徴をより良く抽出できるらしい。(理由はよくわかってないが、活性化関数を通る回数が増えるため、表現力が増す?)[2]
GoogleNetのほうが強そうではあるが、わかりやすさ重視でVGGをやってみる。(難しそうなものは次回以降)
#3.VGG16の導入(GoogleColab使用)
早速コードを書いていく。
まずはKerasのimport
!pip install keras
次に必要なライブラリをインポートしていく。
VGG16はKerasの中に含まれている。
以下の3行目で重みを指定している。
#モデルをimportしてサマリー表示してみる
import numpy as np
from keras.applications.vgg16 import VGG16, preprocess_input, decode_predictions
model = VGG16(include_top=True, weights='imagenet', input_tensor=None, input_shape=None)
model.summary()
#画像の読み取り
from PIL import Image
#import glob
url = '/content/drive/My Drive/Colab Notebooks/img'
files=url+"/apple_orin.jpg"
image =Image.open(files)
image=image.convert('RGB')
image=image.resize((224,224))
# 読み込んだPIL形式の画像をarrayに変換
data = np.asarray(image)
#評価
from keras.preprocessing import image
#サンプル数の次元を1つ増やし四次元テンソルに
data = np.expand_dims(data, axis=0)
#上位5を出力
preds = model.predict(preprocess_input(data))
results = decode_predictions(preds, top=5)[0]
for result in results:
print(result)
('n07742313', 'Granny_Smith', 0.9861995)
('n02948072', 'candle', 0.0040857443)
('n07747607', 'orange', 0.001778649)
('n03887697', 'paper_towel', 0.0016588464)
('n07693725', 'bagel', 0.0012920648)
となった。
#4.結果
1位の「Granny_Smith」ってなに?
ラニースミス (英語:Granny Smith) はリンゴの栽培品種である。1868年にオーストラリアで、名前の由来ともなったマリア・アン・スミスにより、偶発実生で開発された
と、いうことで、画像自体はかなり近いので精度は高いとみてもよさそう。ImageNetに王林のデータがないのだろう。
ImageNetの1000クラス分の順番とラベル、クラス名の情報は以下のJSONファイルにまとめられている。
以下にGranny_Smithあり。
https://storage.googleapis.com/download.tensorflow.org/data/imagenet_class_index.json
品種まで判定する画像認識を行うには別途学習させる必要があるため、次回以降にやる。
今回はあくまでも使ってみることが目的だったのでOK。
次回以降は品種まで当てられるモデルを作成する。
#5.考察
VGG16のモデルを使用するにあたって、キーとなるのは以下の箇所。
model = VGG16(include_top=True, weights='imagenet', input_tensor=None, input_shape=None)
##詳細
引数 | 説明 |
---|---|
include_top | 1000クラスに分類するフル結合層を含むかどうか. |
True:含む(元の1000分類に使う場合はこちら) | |
False:含まない(カスタマイズする場合はこちら) | |
weights | 重みの種類 |
imagenet:ImageNetを使って学習した重み | |
None:ランダム | |
input_tensor | モデル画像を入力する場合に使用 |
任意の画像データ:それを使用 | |
None:使用しない | |
input_shape | 入力画像の形状を指定 |
任意の形状:それを使用 | |
None:(224, 224, 3)が使用される |
include_topをFalseにしてVGG16を特徴量抽出に使用してファインチューニングする。(次回)
参考(にしようとしているもの)
http://aidiary.hatenablog.com/entry/20170131/1485864665