マスク検出のモデル学習 II

関連ライブラリのインポート

from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.layers import AveragePooling2D
from tensorflow.keras.layers import Dropout
from tensorflow.keras.layers import Flatten
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Input
from tensorflow.keras.models import Model
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.applications.mobilenet_v2 import preprocess_input
from tensorflow.keras.preprocessing.image import img_to_array
from tensorflow.keras.preprocessing.image import load_img
from tensorflow.keras.utils import to_categorical
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from imutils import paths
import matplotlib.pyplot as plt
import numpy as np
import argparse
import os

パラメータパーサーを構築し、パラメータを解析する

  • データセット: マスクありまたはマスクなしのデータセットの入力パス
  • プロット: matplotlib を使用して生成される出力トレーニング グラフへのパス
  • モデル: 生成されたマスク検出器モデルの保存パス
#path 为你文件夹路径
parser  = argparse.ArgumentParser()
parser .add_argument("-d", "--dataset", required=True, help="path to input dataset",default="path")
parser .add_argument("-p", "--plot", type=str, default="plot.png", help="path to output loss/accuracy plot")
parser .add_argument("-m", "--model", type=str,default="mask_detector.model",help="path to output face mask detector model")
args = vars(parser .parse_args())

学習率、エポック、batch_size を設定する

rate = 1e-4
epoch = 20
batch_size = 32

データセットの構築

preprocess_input() は、tensorflow の keras に付属する正規化関数に似ており、受信イメージを正規化し、イメージの処理速度を向上させることができます。paths.list_images 関数は、サブフォルダーがある場合でも、フォルダー下の画像パスを直接取得できます。

imagePaths = list(paths.list_images(args['dataset']))
print(len(imagePaths))
data = []
labels = []
for imagePath in imagePaths:
    print(imagePath)
    label = imagePath.split(os.path.sep)[-2]
    #导入数据,调整size为(224, 224)
    image = load_img(imagePath, target_size=(224, 224))
    image = img_to_array(image)
    # 归一化
    image = preprocess_input(image)

    data.append(data)
    labels.append(labels)

data = np.array(data, dtype= 'float32')
labels = np.array(labels)
# 对图像标签的独热编码
encoder = LabelBinarizer()
labels = encoder.fit_transform(labels)
# 转为二进制
labels = to_categorical(labels)

#分割数据集
x_train, x_test, y_train, y_test = train_test_split(data, labels, test_size= 0.2, stratify= labels, random_state= 42)

データ増強

ImageDataGenerator() は keras.preprocessing.image モジュールの画像ジェネレーターであり、バッチ内のデータを拡張し、データセットのサイズを拡張し、モデルの一般化機能を強化することもできます。回転、変形、正規化など。

  • rotation_range(): 回転範囲
  • width_shift_range(): 水平方向の移動範囲
  • height_shift_range(): 垂直方向の移動範囲
  • zoom_range(): ズーム範囲
  • fill_mode: 塗りつぶしモード、定数、最近接、反映
  • horizo​​ntal_flip(): 水平反転
  • vertical_flip(): 垂直方向に反転します
aug = ImageDataGenerator(
	rotation_range=20,
	zoom_range=0.15,
	width_shift_range=0.2,
	height_shift_range=0.2,
	shear_range=0.15,
	horizontal_flip=True,
	fill_mode="nearest"
)

モデルの微調整

設定を微調整するには、次の 3 つの手順を実行します。

  1. ImageNet で事前トレーニングされた MobileNet 重みをロードする
  2. 新しい FC ヘッダーを構築し、それをベースラインに追加して、古い FC ヘッダーを置き換えます。
  3. ネットワークのベース層をフリーズします。バックプロパゲーション中、これらのベース層の重みは更新されませんが、ヘッド層の重みは調整されます。
baseModel = MobileNetV2(weights='imagenet', include_top= False, input_tensor= Input(shape=(224, 224,3)))

headModel = baseModel.output
headModel = AveragePooling2D(pool_size = (7, 7)(headModel))
headModel = Flatten(name= 'flatten')(headModel)
headModel = Dense(128, activation= 'relu')(headModel)
headModel = Dropout(0.5)(headModel)
headModel = Dense(2, activation='softmax')(headModel)

model = Model(inputs = baseModel.input, outputs = headModel)
#冻结网络的基本层:在反向传播过程中,这些基本层的权重不会被更新,而头层的权重将被调整
for layer in baseModel.layers:
    layer.trainable = False
#使用Adam优化器、学习率衰减计划和二进制交叉熵编译我们的模型。
optimizer = Adam(lr = rate, decay = rate/epoch )
model.compile(loss="binary_crossentropy", optimizer=optimizer, metrics=["accuracy"])
#数据增强对象(aug)将提供一批经过修改的图像数据
H = model.fit(
	aug.flow(x_train, y_train, batch_size=batch_size),
	steps_per_epoch=len(x_train) // batch_size,
	validation_data=(x_train, y_train),
	validation_steps=len(x_train) // batch_size,
	epochs=x_train)
predIdxs = model.predict(x_test, batch_size=batch_size)

ここに画像の説明を挿入

損失曲線を描く

N = epoch
plt.style.use("ggplot")
plt.figure()
plt.plot(np.arange(0, N), H.history["loss"], label="train_loss")
plt.plot(np.arange(0, N), H.history["val_loss"], label="val_loss")
plt.plot(np.arange(0, N), H.history["accuracy"], label="train_acc")
plt.plot(np.arange(0, N), H.history["val_accuracy"], label="val_acc")
plt.title("Training Loss and Accuracy")
plt.xlabel("Epoch #")
plt.ylabel("Loss/Accuracy")
plt.legend(loc="lower left")
plt.savefig(args["plot"])

結果を示す:
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/Peyzhang/article/details/126375137