Keras には、いくつかの学習済みモデルが簡単に使えるようなモジュールが用意されてます。
今回は、Oxford大学で作成された VGG16 を利用して動物の画像分類を試してみました。

テストに使った画像は以下の通りです。

イヌ (dog01.jpg, dog02.jpg, dog03.jpg)

dog01dog02dog03

ネコ(家猫) (cat01.jpg, cat02.jpg, cat03.jpg)

cat01cat02cat03

野生ネコ(マヌルネコ)(oto01.jpg)

oto01

ウサギ (rab01.jpg, rab02.jpg)

rab01rab02

野鳥 (brd01.jpg, brd02.jpg, brd03.jpg)

brd01brd02brd03

—- Keras VGG16 を利用して画像を分類する Python プログラム
import tensorflow as tf
import keras as kr
import numpy as np
import datetime as dt
from keras.preprocessing import image as img

## 学習済みモデルのダウンロード
print(‘Model loading ..’)
model = kr.applications.vgg16.VGG16()
print(‘Model loading .. OK’)

## 画像を読み込み
# 画像を読み込み、画像をパラメータの配列形式に変換
print(‘Reading original picture …’)
arr_imagefiles = [
‘data/image/dog01.jpg’,
・・(略)・・・
‘data/image/brd03.jpg’,
]
arr_images = []
for imagefile in arr_imagefiles:
image = kr.preprocessing.image.load_img(imagefile, target_size=(224,224))
arr_image = img.img_to_array(image)
arr_image = kr.applications.vgg16.preprocess_input(arr_image)
arr_images.append(arr_image)
arr_input = np.stack(arr_images)

## 予測
time1 = dt.datetime.now()
print(‘Prediction … ‘ + str(time1))
probs = model.predict(arr_input)
time2 = dt.datetime.now()
print(‘Prediction …OK ‘ + str(time2))

## 結果の上位2件までを表示
print(‘result——-‘)
results = kr.applications.vgg16.decode_predictions(probs)
for i, result in enumerate(results):
print(arr_imagefiles[i])
print(result[0])
print(result[1])
print(‘———–end.’)

——– 実行結果 この結果は確率の高い方がら2種類を表示しています。
result——-
data/image/dog01.jpg
(‘n02102480’, ‘Sussex_spaniel’, 0.890942)
(‘n02100877’, ‘Irish_setter’, 0.06080574)
data/image/dog02.jpg
(‘n02113712’, ‘miniature_poodle’, 0.5399989)
(‘n02113624’, ‘toy_poodle’, 0.4090109)
data/image/dog03.jpg
(‘n02085936’, ‘Maltese_dog’, 0.85274106)
(‘n02113624’, ‘toy_poodle’, 0.03191002)
data/image/cat01.jpg
(‘n02124075’, ‘Egyptian_cat’, 0.80399853)
(‘n02123045’, ‘tabby’, 0.09012239)
data/image/cat02.jpg
(‘n02123394’, ‘Persian_cat’, 0.93466675)
(‘n02112018’, ‘Pomeranian’, 0.014521879)
data/image/cat03.jpg
(‘n02123045’, ‘tabby’, 0.42056268)
(‘n04162706’, ‘seat_belt’, 0.11350574)
data/image/oto01.jpg
(‘n02444819’, ‘otter’, 0.20657453)
(‘n02127052’, ‘lynx’, 0.18093377)
data/image/rab01.jpg
(‘n02088238’, ‘basset’, 0.7435406)
(‘n02102177’, ‘Welsh_springer_spaniel’, 0.092291385)
data/image/rab02.jpg
(‘n02325366’, ‘wood_rabbit’, 0.5588175)
(‘n02326432’, ‘hare’, 0.20253257)
data/image/brd01.jpg
(‘n02012849’, ‘crane’, 0.43793336)
(‘n02009912’, ‘American_egret’, 0.20867929)
data/image/brd02.jpg
(‘n02017213’, ‘European_gallinule’, 0.37958065)
(‘n01847000’, ‘drake’, 0.22867891)
data/image/brd03.jpg
(‘n02058221’, ‘albatross’, 0.9688129)
(‘n01796340’, ‘ptarmigan’, 0.00950058)
———–end.

犬の画像については詳しく犬種まで分類されてます。
1番目の画像は、Sussex_spaniel(サセックス・スパニエル犬)である可能性が 89% 程度でした。
2番目の画像は、miniature_poodle(ミニチュアプードル) 54% , toy_poodle(トイプードル) 41% 程度で見解が分かれています。
筆者は犬の種類は詳しくないのですが、犬であることはわかります。

猫の画像も種類まで詳しく分類されていますが、
三番目の seat_belt(シートベルト??)11% はどこを見たのでしょう?
窓枠と猫の顔の位置がシートベルトに見えるような特徴があったのでしょうか?

野生ネコ(マヌルネコ)は、otter(カワウソ)20%, lynx(オオヤマネコ)18% の結果で、おそらくデータが無かったからだと思います。
一般の画像データから学習しているモデルでは、野生動物は難しいと思います。

このモデルはウサギの分類も苦手なのでしょうか?
ウサギが、basset(バセット犬)74% になってしまいました。
バセット犬をネット検索で調べてみたら、たれ耳ウサギに似た特徴がありました。

野鳥の分類もほとんどハズレでした。
サギが crane(ツル)になったり、ユリカモメが albatross(アホウドリ)になったり、ほとんどハズレでした。
どうして間違えたのか考えてみるのも面白いと思います。

Keras では既存のモデルに追加学習ができる機能が用意されています。
動物分類のデータが不足していたら自分で集めて補足することもできるかもしれません。

 

(S.Onda 2018/6/10)