%cd/content/drive/My Drive/dog_folder
from PIL import Image
import os, glob
import numpy as np
from PIL import ImageFile
# IOError: image file is truncated (0 bytes not processed)回避のため
ImageFile.LOAD_TRUNCATED_IMAGES = True
classes = ["ラブラドールレトリバー", "ミニチュアダックスフンド","ゴールデンレトリバー","ダルメシアン",
"コーギー", "ポメラニアン" ]
num_classes = len(classes)
image_size = 64
num_testdata = 25
X_train = []
X_test = []
y_train = []
y_test = []
for index, classlabel in enumerate(classes):
photos_dir = "./" + classlabel
files = glob.glob(photos_dir + "/*.jpg")
for i, file in enumerate(files):
image = Image.open(file)
image = image.convert("RGB")
image = image.resize((image_size, image_size))
data = np.asarray(image)
if i < num_testdata:
X_test.append(data)
y_test.append(index)
else:
# angleに代入される値
# -20
# -15
# -10
# -5
# 0
# 5
# 10
# 15
# 画像を5度ずつ回転
for angle in range(-20, 20, 5):
img_r = image.rotate(angle)
data = np.asarray(img_r)
X_train.append(data)
y_train.append(index)
# FLIP_LEFT_RIGHT は 左右反転
img_trains = img_r.transpose(Image.FLIP_LEFT_RIGHT)
data = np.asarray(img_trains)
X_train.append(data)
y_train.append(index)
X_train = np.array(X_train)
X_test = np.array(X_test)
y_train = np.array(y_train)
y_test = np.array(y_test)
xy = (X_train, X_test, y_train, y_test)
np.save("./typesofdogs.npy", xy)
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from tensorflow.keras.optimizers import RMSprop
from keras.utils import np_utils
import keras
import numpy as np
classes = ["ラブラドールレトリバー", "ミニチュアダックスフンド","プードル","ブルドッグ","ゴールデンレトリバー","秋田犬 ","ダルメシアン",
"コーギー", "シェトランドシープドッグ" ,"チワワ" ,"シベリアンハスキー" ,
"シェパード", "ポメラニアン" ,"セントバーナード" ]
num_classes = len(classes)
image_size = 64
# データを読み込む関数
def load_data():
X_train, X_test, y_train, y_test = np.load("typesofdogs.npy", allow_pickle=True)
# 入力データの各画素値を0-1の範囲で正規化(学習コストを下げるため)
X_train = X_train.astype("float") / 255
X_test = X_test.astype("float") / 255
# to_categorical()にてラベルをone hot vector化
y_train = np_utils.to_categorical(y_train, num_classes)
y_test = np_utils.to_categorical(y_test, num_classes)
return X_train, y_train, X_test, y_test
# モデルを学習する関数
def train(X, y, X_test, y_test):
model = Sequential()
# Xは(1200, 64, 64, 3)
# X.shape[1:]とすることで、(64, 64, 3)となり、入力にすることが可能です。
model.add(Conv2D(32,(3,3), padding='same',input_shape=X.shape[1:]))
model.add(Activation('relu'))
model.add(Conv2D(32,(3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.1))
model.add(Conv2D(64,(3,3), padding='same'))
model.add(Activation('relu'))
model.add(Conv2D(64,(3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.45))
model.add(Dense(14))
model.add(Activation('softmax'))
# https://keras.io/ja/optimizers/
# 今回は、最適化アルゴリズムにRMSpropを利用
opt = RMSprop(lr=0.00005, decay=1e-6)
# https://keras.io/ja/models/sequential/
model.compile(loss='categorical_crossentropy',optimizer=opt,metrics=['accuracy'])
model.fit(X, y, batch_size=28, epochs=40)
# HDF5ファイルにKerasのモデルを保存
model.save('./cnn.h5')
return model
# メイン関数データの読み込みとモデルの学習を行います。
def main():
# データの読み込み
X_train, y_train, X_test, y_test = load_data()
# モデルの学習
model = train(X_train, y_train, X_test, y_test)
main()
今回は、ダウンロードしたラブラドールレトリバーの画像をLabradorRetriever.jpgというファイル名でアップロードし、変数testpic に代入します。
画像はこちらからダウンロード可能です。
from PIL import Image
import keras
import sys, os
import numpy as np
from keras.models import load_model
imsize = (64, 64)
"""
LabradorRetriever.jpgというファイル名の画像をGoogle Colab上にアップロードする方法は2通りあります。
1つが、下記のコードを実行し画像をアップロードする方法
from google.colab import files
uploaded = files.upload()
2つ目が、Colab左メニューの>アイコンを押して、目次、コード スニペット、ファイル
の3つ表示されるますが、右のファイルタブから画像をアップロードする方法です。
このファイルタブをクリックするとアップロードと更新の2つがありますが、
アップロードを押すと画像をアップロードすることが可能です。
"""
testpic = "./ミニチュアダックスフンド.jpeg"
keras_param = "./cnn.h5"
def load_image(path):
img = Image.open(path)
img = img.convert('RGB')
# 学習時に、(64, 64, 3)で学習したので、画像の縦・横は今回 変数imsizeの(64, 64)にリサイズします。
img = img.resize(imsize)
# 画像データをnumpy配列の形式に変更
img = np.asarray(img)
img = img / 255.0
return img
model = load_model(keras_param)
img = load_image(testpic)
prd = model.predict(np.array([img]))[0]
print(prd) # 精度の表示
prelabel = np.argmax(prd)
classes = ["ラブラドールレトリバー","ミニチュアダックスフンド","プードル","ブルドッグ","ゴールデンレトリバー","秋田犬 ","ダルメシアン",
"コーギー", "シェトランドシープドッグ" ,"チワワ" ,"シベリアンハスキー" ,
"シェパード", "ポメラニアン" ,"セントバーナード" ]
pred_answer = "これは " + classes[prelabel] + "です"
print(pred_answer)
先ほどのラブラドールレトリバーの画像を予測させて見ると、次のように正しく認識できています。
スクリーンショット
for i in range(16):
print("{}の確率: {}%".format(classes[i],int(prd[i]*100)))
※万が一上記の推論のプログラムで、cnn.h5が存在しないというようなエラーが出た場合、うまく学習フェースのセクションのプログラムが動いていないかと思います。
その場合は、こちらからcnn.h5をダウンロードしご利用ください。
>>> ラブラドールレトリバー
念のためにミニチュアダックスフンドの画像でも検証を行います。
ラブラドールレトリバーの画像と同様の方法で以下の猫の画像「Dachshund.jpg」をアップロードし、変数testpicを「./LabradorRetriever.jpg」から「./Dachshund.jpg」に変更し、先ほどのコードを再度実行します 。
ミニチュアダックスフンドの画像は、インターネットからお好きなものをダウンロードしてアップロードしてください。
>>> ミニチュアダックスフンド
もし、より精度を上げたい場合には画像収集時の引数max_numを増やすことで学習に使うデータ数を増やして再学習させてみましょう。
モデルの方は完成しましたので、その後作成していた下記の「Flask」「HTML」「CSS」のコードを作成。