[keras] [VGG]転移学習アプリケーション

環境構成

Python 3.6
scikit-image 0.17.2
numpy 1.19.0 opencv
-python 3.4.2.16 opencv
-contrib-python 3.4.2.16

プログラムの進捗状況

トレーニングデータを読む

train_datagen = ImageDataGenerator(rescale=1./255,
                                  rotation_range = 45,
                                  width_shift_range = 0.2,
                                  height_shift_range = 0.2,
                                  shear_range = 0.2,
                                  zoom_range = 0.2,
                                  horizontal_flip=True)

train_gen = train_datagen.flow_from_directory("data/train",
                                             target_size = (240, 240),
                                             batch_size = 8,
                                             class_mode="categorical")

ImageDataGenerator

データ拡張が可能です;
参照リンク:Keras ImageDataGenerator

  • 再スケール:0から255までの値を0から1の間の値に正規化します。
  • rotation_range:整数、画像のランダムな回転角、値は[0、180]、デフォルトは通常反時計回りだと思います。
  • width_shift_range:浮動小数点数、特定の比率、画像のランダムな水平シフトの範囲、値は[0、1]です。
  • height_shift_range:浮動小数点数、特定の比率、画像のランダムな垂直移動の振幅、値は[0、1]です。
  • せん断範囲:(反時計回りの)せん断変換の程度を示す浮動小数点数。
  • zoom_range:ランダムズームの程度を示す浮動小数点数、または[下、上]の形式のリスト。
  • Horizo​​ntal_flip:ブール値、ランダムな水平フリップ。

フォルダに従って画像を自動的に分類します。
ここに画像の説明を挿入

flow_from_directory

フォルダごとに番号を付けて自動的に分類できます。
ここに画像の説明を挿入
トレーニングデータをバッチで表示します。バッチには8つの画像があり、temp [0]は画像、temp [1]はラベル、
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
データ範囲は0〜1です。:ワン
ここに画像の説明を挿入
ホットエンコーディングが完了しました:
ここに画像の説明を挿入
ここに画像の説明を挿入

事前にトレーニングされたモデルをオンラインでロードする

VGG = keras.applications.vgg16.VGG16(weights="imagenet", include_top=False, input_shape=[240, 240, 3])

ここに画像の説明を挿入
または、ローカルにアクセスしたファイルをロードします。

from keras.models import load_model
VGG = load_model("model/VGG_Pretrained.h5")

モデル情報の表示:
ここに画像の説明を挿入
ここに画像の説明を挿入

モデルの最後に分類子を追加します

from keras.layers import Dense, Flatten

x = VGG.layers[-1].output
x = Flatten()(x)
x = Dense(64, activation="sigmoid")(x)
predictions=Dense(5, activation="softmax")(x)

model = keras.Model(inputs=VGG.inputs, outputs=predictions)

モデルの背後に分類器を追加します。出力層のニューロンの数はラベルと同じである必要があります。平坦化を追加する必要があります。そうしないと、密層は行列入力を受け入れることができません。
簡単に言うと、ニューロンの2つの層が追加されます。より厄介なのは、元のモデルを接続することです。

for layer in model.layers[:-2]:
    layer.trainable=False

最後の2つのレイヤーのみをトレーニングします。
ここに画像の説明を挿入

オプティマイザーを定義する

adam = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-8)
model.compile(loss="categorical_crossentropy", optimizer=adam, metrics=["accuracy"])

トレーニングモデル

model.fit_generator(train_gen, steps_per_epoch=12, epochs=10)

ここに画像の説明を挿入
トレーニング済みモデルを保存します。
ここに画像の説明を挿入

テストデータをロードする

import skimage.io as io
import skimage.transform as transform

img = io.imread("data/test/3.jpg")
img = img/255
img = transform.resize(img, output_shape=[240, 240])
print(img.shape)
plt.imshow(img)

ここに画像の説明を挿入
テストを開始します。

indices = {'紫葡萄': 0, '红苹果': 1, '绿葡萄': 2, '黄苹果': 3, '黄香蕉': 4}
output = model.predict(img.reshape([1, 240, 240, 3]))
print(output)

ここに画像の説明を挿入

出力結果

output_rには2つの数値があり、それぞれ予測結果の行数と列数を示します。
ここに画像の説明を挿入

完全なソースコード

冗長な出力情報はありません

# 完整版
import numpy as np
import keras
import matplotlib.pyplot as plt

from keras.models import Sequential
from keras.optimizers import Adam
from keras.utils.np_utils import to_categorical

from keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(rescale=1./255,
                                  rotation_range = 45,
                                  width_shift_range = 0.2,
                                  height_shift_range = 0.2,
                                  shear_range = 0.2,
                                  zoom_range = 0.2,
                                  horizontal_flip=True)

train_gen = train_datagen.flow_from_directory("data/train",
                                             target_size = (240, 240),
                                             batch_size = 8,
                                             class_mode="categorical")
# 从网上下载预先存取好的模型
VGG = keras.applications.vgg16.VGG16(weights="imagenet", include_top=False, input_shape=[240, 240, 3])

# 或者直接从本地导入
# from keras.models import load_model
# VGG = load_model("model/VGG_Pretrained.h5")

# 在原模型末尾加入分类器
from keras.layers import Dense, Flatten

x = VGG.layers[-1].output
x = Flatten()(x)
x = Dense(64, activation="sigmoid")(x)
predictions=Dense(5, activation="softmax")(x)

model = keras.Model(inputs=VGG.inputs, outputs=predictions)

# 设置为只需要训练最后新加入的两层神经元
for layer in model.layers[:-2]:
    layer.trainable=False

# 定义优化器
adam = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-8)
model.compile(loss="categorical_crossentropy", optimizer=adam, metrics=["accuracy"])

# 训练模型
model.fit_generator(train_gen, steps_per_epoch=12, epochs=10)

# 载入测试数据
import skimage.io as io
import skimage.transform as transform

img = io.imread("data/test/3.jpg")
img = img/255
img = transform.resize(img, output_shape=[240, 240])
# print(img.shape) # 查看图片信息
# plt.imshow(img)

# 结果展示
indices = {'紫葡萄': 0, '红苹果': 1, '绿葡萄': 2, '黄苹果': 3, '黄香蕉': 4}
output = model.predict(img.reshape([1, 240, 240, 3]))
# print(output)

# 使得结果更加清晰
output_r = np.where(output==np.max(output))
print(np.max(output_r[1])) # 表示预测结果的列编号

おすすめ

転載: blog.csdn.net/weixin_44092088/article/details/113061624