LoginSignup
3
5

More than 3 years have passed since last update.

VGG16を使ったフルーツの画像認識

Last updated at Posted at 2020-05-31

1.背景

興味本位でKerasを使った画像認識を実装してみたところ、思いの外簡単だったので、より高精度なモデルを実装したく友人のススメでVGG16を使ってみることにした。
初学者なので、詳しいことは調べながらやってみる。
今回はりんごの王林の画像を使用して、品種まで当てられるのか評価を行う。
あくまでもメモ。

2.そもそもVGG16ってなに?:thinking:

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

vgg16_fluits.py
!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()


model.summary()結果
Model: "vgg16"

Layer (type) Output Shape Param #

input_3 (InputLayer) (None, 224, 224, 3) 0


block1_conv1 (Conv2D) (None, 224, 224, 64) 1792


block1_conv2 (Conv2D) (None, 224, 224, 64) 36928


block1_pool (MaxPooling2D) (None, 112, 112, 64) 0


block2_conv1 (Conv2D) (None, 112, 112, 128) 73856


block2_conv2 (Conv2D) (None, 112, 112, 128) 147584


block2_pool (MaxPooling2D) (None, 56, 56, 128) 0


block3_conv1 (Conv2D) (None, 56, 56, 256) 295168


block3_conv2 (Conv2D) (None, 56, 56, 256) 590080


block3_conv3 (Conv2D) (None, 56, 56, 256) 590080


block3_pool (MaxPooling2D) (None, 28, 28, 256) 0


block4_conv1 (Conv2D) (None, 28, 28, 512) 1180160


block4_conv2 (Conv2D) (None, 28, 28, 512) 2359808


block4_conv3 (Conv2D) (None, 28, 28, 512) 2359808


block4_pool (MaxPooling2D) (None, 14, 14, 512) 0


block5_conv1 (Conv2D) (None, 14, 14, 512) 2359808


block5_conv2 (Conv2D) (None, 14, 14, 512) 2359808


block5_conv3 (Conv2D) (None, 14, 14, 512) 2359808


block5_pool (MaxPooling2D) (None, 7, 7, 512) 0


flatten (Flatten) (None, 25088) 0


fc1 (Dense) (None, 4096) 102764544


fc2 (Dense) (None, 4096) 16781312


predictions (Dense) (None, 1000) 4097000

Total params: 138,357,544
Trainable params: 138,357,544
Non-trainable params: 0



今回使用する画像はりんご(王林)を評価する。
apple_orin.jpg

  #画像の読み取り
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年にオーストラリアで、名前の由来ともなったマリア・アン・スミスにより、偶発実生で開発された
commodity-granny-smith.jpg

と、いうことで、画像自体はかなり近いので精度は高いとみてもよさそう。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

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5