こんにちは、DXCEL WAVEの運営者(@dxcelwave)です!
ディープラーニングの画像認識に興味がある方向けに、Tensorflow(Keras)を用いてモデルを作成する方法について解説します。
畳み込みニューラルネットワーク(CNN)とは

CNNは多次元配列データを扱うことに特化したニューラルネットワークであり、画像認識や動体検知の分野で広く応用されています。
CNNは「畳み込み層」「プーリング層」「全結合層」で構成されるのが特徴です。畳み込み層で画像の特徴を抽出し、プーリング層で特徴データを圧縮します。この操作を繰り返した後、結合層で分類結果を出力します。
【参考】ディープラーニングモデル最適化の仕組み
【深層学習】ニューラルネットワークの仕組みとディープラーニングモデル性能最適化のポイント解説
ディープラーニングの実装を検討している方向けです。深層学習モデルを実装するための仕組みとモデルを最適化する手法など重要なポイントを踏襲しています。本記事読了後、モデル改善に向けた適切なアプローチができるようになるでしょう。
ディープラーニングの仕組みについて詳しく知りたい方はこちらの記事をご覧下さい。
【参考】Kerasを用いた深層学習プログラミング
Kerasでディープラーニングモデルを構築する方法を詳しく知りたい方向けにおすすめ教材をご紹介します。
【深層学習】画像認識AIモデルの作成概要

AI画像認証モデルの作成に際して、本記事では「りんご」「ぶどう」「みかん」を分類することを目的としたモデル作成を試みます。なお、上記画像以外の分類にも横展開できるようなスクリプト構成としていますため、お好みの用途にもご活用ください。
画像認識モデルの作成手順
次のような手順のもと、画像認証AIを作成します。
- データ前処理|データセットの読込・加工
- モデル学習・評価|CNN
- モデル推論
事前準備

トレーニング・テストデータを格納した画像フォルダ(data)とpythonスクリプトを記述したファイル(pythonファイル)を同ディレクトリに配置します。
サンプルの画像データは、fruits-sample-datasetからダウンロードできますためご活用ください。
【Python×Keras】画像認証AIの構築|ディープラーニング実践
それでは実際に画像認証AIモデルを構築していきましょう!
データ前処理|データセットの読込・加工
指定の画像ファイルを読み込み、3色(RGB)の数値配列に変換した後、モデル学習・評価用のトレーニングデータとテストデータを作成する方法を以下に示します。
from PIL import Image
import numpy as np
import os,glob
# クラスラベル
labels = ["grape","apple","orange"]
# ディレクトリ
dataset_dir = "data/dataset.npy" # 前処理済みデータ
model_dir = "data/cnn_h5" # 学習済みモデル
# リサイズ設定
resize_settings = (50,50)
# 画像データ
X_train = [] # 学習
y_train = [] # 学習ラベル
X_test = [] # テスト
y_test = [] # テストラベル
for class_num, label in enumerate(labels):
# 写真のディレクトリ
photos_dir = "data/" + label
# 画像データを取得
files = glob.glob(photos_dir + "/*.jpg")
#写真を順番に取得
for i,file in enumerate(files):
# 画像を1つ読込
image = Image.open(file)
# 画像をRGBの3色に変換
image = image.convert("RGB")
# 画像のサイズを揃える
image = image.resize(resize_settings)
# 画像を数字の配列変換
data = np.asarray(image)
# テストデータ追加
if i%4 ==0:
X_test.append(data)
y_test.append(class_num)
# 学習データ傘増し
else:
# -20度から20度まで4度刻みで回転したデータを追加
for angle in range(-25,20,5):
# 回転
img_r = image.rotate(angle)
# 画像 → 数字の配列変換
data = np.asarray(img_r)
# 追加
X_train.append(data)
y_train.append(class_num)
# 画像左右反転
img_trans = image.transpose(Image.FLIP_LEFT_RIGHT)
data = np.asarray(img_trans)
X_train.append(data)
y_train.append(class_num)
# X,YがリストなのでTensorflowが扱いやすいようnumpyの配列に変換
X_train = np.array(X_train)
X_test = np.array(X_test)
y_train = np.array(y_train)
y_test = np.array(y_test)
# 前処理済みデータを保存
dataset = (X_train,X_test,y_train,y_test)
np.save(dataset_dir,dataset)
上記実行後、dataset.npyという数値配列からなるトレーニング・テストデータがdataフォルダ直下に作成されます。
モデル学習・評価|CNN
前述で作成したdataset.npyを読み込み、畳み込みニューラルネットワーク(CNN)のモデルを学習・評価するスクリプトを以下に示します。
import tensorflow
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation,Dropout,Flatten,Dense
from keras.utils import np_utils
import numpy as np
# クラスラベル
labels = ["grape","apple","orange"]
# ディレクトリ
dataset_dir = "data/dataset.npy" # 前処理済みデータ
model_dir = "data/cnn_h5" # 学習済みモデル
# リサイズ設定
resize_settings = (50,50)
# メインの関数定義
def main():
"""
①データの前処理(エンコーディング)
"""
# 保存したnumpyデータ読み込み
X_train,X_test,y_train,y_test = np.load(dataset_dir, allow_pickle=True)
# 0~255の整数範囲になっているため、0~1間に数値が収まるよう正規化
X_train = X_train.astype("float") / X_train.max()
X_test = X_test.astype("float") / X_train.max()
# クラスラベルの正解値は1、他は0になるようワンホット表現を適用
y_train = np_utils.to_categorical(y_train,len(labels))
y_test = np_utils.to_categorical(y_test,len(labels))
"""
②モデル学習&評価
"""
#モデル学習
model = model_train(X_train,y_train)
#モデル評価
evaluate(model,X_test, y_test)
#モデル学習関数
def model_train(X_train,y_train):
#インスタンス
model = Sequential()
# 1層目 (畳み込み)
model.add(Conv2D(32,(3,3),padding="same", input_shape=X_train.shape[1:]))
model.add(Activation('relu'))
# 2層目(Max Pooling)
model.add(Conv2D(32,(3,3)))
model.add(Activation('relu'))
# 3層目 (Max Pooling)
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.3))
# 4層目 (畳み込み)
model.add(Conv2D(64,(3,3),padding="same"))
model.add(Activation('relu'))
# 5層目 (畳み込み)
model.add(Conv2D(64,(3,3)))
model.add(Activation('relu'))
# 6層目 (Max Pooling)
model.add(MaxPooling2D(pool_size=(2,2)))
# データを1次元化
model.add(Flatten())
# 7層目 (全結合層)
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
# 出力層(softmaxで0〜1の確率を返す)
model.add(Dense(3))
model.add(Activation('softmax'))
# 最適化アルゴリズム
opt = tensorflow.keras.optimizers.RMSprop(lr=0.005, decay=1e-6)
# 損失関数
model.compile(loss="categorical_crossentropy",
optimizer=opt,
metrics=["accuracy"]
)
# モデル学習
model.fit(X_train,y_train,batch_size=10,epochs=150)
# モデルの結果を保存
model.save(model_dir)
return model
# 評価用関数
def evaluate(model,X_test,y_test):
# モデル評価
scores = model.evaluate(X_test,y_test,verbose=1)
print("Test Loss: ", scores[0])
print("test Accuracy: ", scores[1])
モデル学習および評価の際は以下を追記し、実行してみましょう。
モデル学習完了後、dataフォルダ直下にcnn_h5(学習済モデルを格納したフォルダ)が作成されます。
# モデル学習実行
model = main()
今回畳み込みニューラルネットワークのレイヤーには次のようなものを定義しています。詳しくはKeras Documentationをご覧下さい。
レイヤー | 概要 |
---|---|
Conv2D | 畳み込み層 |
MaxPooling2D | プーリング層 |
Activation | 活性化関数 |
Dropout | ドロップアウト |
Flatten | 多次元配列を1次元のベクトルに変換 |
Dense | 全結合層 |
モデル推論
学習済モデルを用いて推論を実施するためのスクリプトを以下に示します。
import tensorflow
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation,Dropout,Flatten,Dense
from keras.utils import np_utils
import sys
import numpy as np
from PIL import Image
from tensorflow import keras
# クラスラベル
labels = ["grape","apple","orange"]
# ディレクトリ
dataset_dir = "data/dataset.npy" # 前処理済みデータ
model_dir = "data/cnn_h5" # 学習済みモデル
# リサイズ設定
resize_settings = (50,50)
# 推論用モデル
def predict():
#インスタンス
model = Sequential()
# 1層目 (畳み込み)
model.add(Conv2D(32,(3,3),padding="same", input_shape=X_train.shape[1:]))
model.add(Activation('relu'))
# 2層目(Max Pooling)
model.add(Conv2D(32,(3,3)))
model.add(Activation('relu'))
# 3層目 (Max Pooling)
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.3))
# 4層目 (畳み込み)
model.add(Conv2D(64,(3,3),padding="same"))
model.add(Activation('relu'))
# 5層目 (畳み込み)
model.add(Conv2D(64,(3,3)))
model.add(Activation('relu'))
# 6層目 (Max Pooling)
model.add(MaxPooling2D(pool_size=(2,2)))
# データを1列に並べる
model.add(Flatten())
# 7層目 (全結合層)
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.5))
# 出力層(softmaxで確率を渡す:当てはまるものを1で返す)
model.add(Dense(3))
model.add(Activation('softmax'))
# 最適化の手法
opt = tensorflow.keras.optimizers.RMSprop(lr=0.005, decay=1e-6)
# 損失関数
model.compile(loss="categorical_crossentropy",
optimizer=opt,
metrics=["accuracy"]
)
# モデル学習(推論では不要のためコメントアウト)
# model.fit(X_train,y_train,batch_size=10,epochs=150)
# モデルを読み込み
model = keras.models.load_model("data/cnn_h5")
return model
# 実行関数
def main(path):
X = [] # 推論データ格納
image = Image.open(path) # 画像読み込み
image = image.convert("RGB") # RGB変換
image = image.resize(resize_settings) # リサイズ
data = np.asarray(image) # 数値の配列変換
X.append(data)
X = np.array(X)
# モデル呼び出し
model = predict()
# numpy形式のデータXを与えて予測値を得る
model_output = model.predict([X])[0]
# 推定値 argmax()を指定しmodel_outputの配列にある推定値が一番高いインデックスを渡す
predicted = model_output.argmax()
# アウトプット正答率
accuracy = int(model_output[predicted] *100)
print("{0} ({1} %)".format(labels[predicted],accuracy))
推論の際は、以下を追記し実行してみましょう。
# 推論
path = "推論用画像のファイルパス"
image = Image.open(path)
main(path)
【参考】AI・機械学習における配信情報まとめ
当サイトではAI・機械学習における「基礎」から「最新のプログラミング手法」に至るまで幅広く解説しております。また「おすすめの勉強方法」をはじめ、副業・転職・フリーランスとして始める「AI・機械学習案件の探し方」についても詳しく言及しています。
【仕事探し】副業・転職・フリーランス
【教育】おすすめ勉強法
【参考】記事一覧
最後に

お問い合わせフォーム
上記課題に向けてご気軽にご相談下さい。
お問い合わせはこちら