Keras ディープラーニングは、VGG16 事前トレーニング済みニューラル ネットワークを使用して猫と犬の分類を実現します

Keras ディープラーニングは、VGG16 事前トレーニング済みニューラル ネットワークを使用して猫と犬の分類を実現します

最近ディープラーニングに触れ始めたのですが、数あるディープラーニングのフレームワークの中でもKerasが入門に最適で、猫や犬の画像分類もコンピュータビジョンの古典的な事例ですので、その実装を紹介させていただきます。プロセス:

事前環境

  1. Python3.6 Pip3
  2. Keras、バックエンドとして Tensorflow を使用
  3. ナンピー
  4. マットプロットリブ
  5. OpenCV

実装プロセス

モデルトレーニング

まず、必要なパッケージをインポートする必要があります。このトレーニング モデルには、VGG16 の事前トレーニング済みネットワーク モデルが使用されています。GPU をサポートしていない人にとっても朗報です。モデルのトレーニングを高速化し、小規模なバッチ データ セットの精度を大幅に向上させることもできます。

import keras
import tensorflow as tf
from keras import layers
import numpy as np
import os
import shutil
import matplotlib.pyplot as plt
%matplotlib inline
from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.applications import VGG16

インターネット上で見つかった猫と犬のデータセット リソースから、猫と犬のデータセットを読み込み、猫と犬のトレーニング (トレーニング) データとテスト (テスト) データを分割します。猫と犬の元のデータセットを百度クラウドディスクにアップロードしました。記事の最後にある必要な記事を選択してください。

# 创建划分好的训练测试目录
BASE_DIR = './cat_dog'
train_dir = os.path.join(BASE_DIR, 'train')
train_dir_dog = os.path.join(train_dir, 'dog')
train_dir_cat = os.path.join(train_dir, 'cat')

test_dir = os.path.join(BASE_DIR, 'test')
test_dir_dog = os.path.join(test_dir, 'dog')
test_dir_cat = os.path.join(test_dir, 'cat')
train_dir_dog, test_dir_cat

os.mkdir(BASE_DIR)
os.mkdir(train_dir)
os.mkdir(train_dir_dog)
os.mkdir(train_dir_cat)
os.mkdir(test_dir)
os.mkdir(test_dir_dog)
os.mkdir(test_dir_cat)

# 数据集拷贝
source_dir = './source_data/train'

# 拷贝1000张猫的训练集到新划分的目录
fnames = ['cat.{}.jpg'.format(i) for i in range(1000)]
for fname in fnames:
    s = os.path.join(source_dir, fname)
    d = os.path.join(train_dir_cat, fname)
    shutil.copyfile(s, d)

# 拷贝1000张狗的训练集到新划分的目录
fnames = ['dog.{}.jpg'.format(i) for i in range(1000)]
for fname in fnames:
    s = os.path.join(source_dir, fname)
    d = os.path.join(train_dir_dog, fname)
    shutil.copyfile(s, d)

# 拷贝猫和狗测试集图片各500张,共1000张
fnames = ['dog.{}.jpg'.format(i) for i in range(1000, 1500)]
for fname in fnames:
    s = os.path.join(source_dir, fname)
    d = os.path.join(test_dir_dog, fname)
    shutil.copyfile(s, d)

fnames = ['cat.{}.jpg'.format(i) for i in range(1000, 1500)]
for fname in fnames:
    s = os.path.join(source_dir, fname)
    d = os.path.join(test_dir_cat, fname)
    shutil.copyfile(s, d)

画像データのイテレータを作成し、元の画像を正規化する

train_datagen = ImageDataGenerator(rescale=1 / 255)
test_datagen = ImageDataGenerator(rescale=1 / 255)

# 训练集数据生成器,从数据目录生成,读取成200*200的统一图像resize,本质是一个二分类问题,model我们使用binary
train_generator = train_datagen.flow_from_directory(train_dir, 
target_size=(200, 200), batch_size=20, class_mode='binary')

# 测试集数据
test_generator = test_datagen.flow_from_directory(test_dir, 
target_size=(200, 200), batch_size=20, class_mode='binary')

Matplotlib を使用すると、画像を出力できます。画像のデータは基本的に 3 つのチャネルのカラー データ値、つまり RGB 値です。

# [批次](批次数据集, 批次二分类结果)[批次数据集下标] --- 对应迭代器的数据格式
# 0 为猫;1 为狗  --- 二分类结果表示
plt.imshow(train_generator[0][0][0])
print(train_generator[0][1][0])

ここに画像の説明を挿入
VGG16 事前トレーニング済みニューラル ネットワークを初期化します。vgg ネットワークを使用し、imageNet 重みを使用します。include_top に最後に完全に接続された層と出力層が含まれるかどうか、

covn_base = VGG16(weights='imagenet', include_top=False, input_shape=(200,200,3))

summary() を使ってニューラルネットワークの構造を確認すると、VGG16 の構造も Conv2D (畳み込み) と MaxPooling2D (プーリング) の複数の層で構成されていることがわかります。

covn_base.summary()

ここに画像の説明を挿入
VGGネットワ​​ークを使用して画像の特徴量を抽出し、それを線形ネットワークに入れてトレーニングし、速度を向上させます

batch_size = 20
def extract_features(data_generator, sample_count):
    i = 0
    features = np.zeros(shape=(sample_count, 6, 6, 512))
    labels = np.zeros(shape=(sample_count))
    for inputs_batch, labels_batch in data_generator:
        features_batch = covn_base.predict(inputs_batch)
        features[i * batch_size : (i+1)*batch_size] = features_batch
        labels[i*batch_size:(i+1)*batch_size] = labels_batch
        i+=1
        if i * batch_size >= sample_count:
            break
    return features, labels

train_featrues, train_labels = extract_features(train_generator, 2000)
test_featrues, test_labels = extract_features(test_generator, 1000)

独自のモデルの全結合 Dense 層を構築して結果を出力し、VGG16 で処理された画像データを GlobalAveragePooling2D を使用して平坦化し (つまり 1 次元データにし)、最終的に y=w1x1+w2x2 の問題に集約します。 ..+b. 結果を出力します。relu 活性化関数を使用します。Dropout を使用して過学習を抑制します。結果は 2 値分類、つまり 0 は猫、1 は犬であるため、最後に結果を出力します。したがって、出力結果は1つしかないため、シグモイド関数を使用して二項分類結果を出力します。

model = keras.Sequential()
model.add(layers.GlobalAveragePooling2D(input_shape=(6, 6, 512)))
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(1, activation='sigmoid'))

モデルをコンパイルし、Adam 活性化関数を使用し、最適化率を調整します。これは 2 カテゴリの問題であるため、ここでは損失関数は binary_crossentropy を使用します。

model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.0005/10), loss='binary_crossentropy', metrics=['acc'])

モデルのトレーニングを開始します。トレーニング中にテスト セットをテストします。ここでは合計 50 回のトレーニングが行われます

history = model.fit(train_featrues,train_labels, epochs=50, 
batch_size=50, validation_data=(test_featrues, test_labels))

以下はトレーニング結果です。このうち、loss はトレーニング セットの損失値、acc はトレーニング セットの正解率、val_loss はテスト セットの損失値、val_acc はテスト セットの正解率です。結果は比較的理想的で、トレーニング セットとテスト セットの精度は約 90% に達し、適合性が非常に優れていることがわかります。
ここに画像の説明を挿入
Matplotlib を使用して次のトレーニング セットとテスト セットの精度曲線を描画すると、トレーニング プロセスの変化をより明確に確認できます。

plt.plot(range(50), history.history.get('val_acc'), c='r', label='val_acc')
plt.plot(range(50), history.history.get('acc'), c='b', label='acc')
plt.legend

ここに画像の説明を挿入
トレーニングされたモデルをローカルの h5 タイプ ファイルとして保存します

model.save('cat_dog_model.h5')

上記のトレーニング プロセスが完了したら、次のステップは、保存したトレーニング済みモデルを使用して実際のデータをテストすることです。

モデルのテスト

モデル テストでは、便宜上、ネットワーク上で取得した画像のサイズを変更し、出力結果を便利に表示するために OpenCV を使用します。
必要なパッケージをインポートします。

import tensorflow as tf
import numpy as np
from keras.models import load_model
import cv2

OpenCVの画像表示関数を定義する

def show(image):
    cv2.namedWindow('test', 0)
    cv2.imshow('test', image)
    # 0任意键终止窗口
    cv2.waitKey(0)
    cv2.destroyAllWindows()

VGG16 の重みと保存されたトレーニング モデルを読み込みます

covn_base = tf.keras.applications.VGG16(weights='imagenet', include_top=False, input_shape=(200, 200, 3))
cat_dog_model = load_model('./cat_dog_model.h5')

OpenCVを使用して画像を読み込み、画像を200✖️200のサイズにリサイズし、画像データをVGG16が必要とするデータ形式に展開します

image = cv2.imread('cat1.jpeg')
resize_image = cv2.resize(image, (200, 200), interpolation=cv2.INTER_AREA)
input_data = np.expand_dims(resize_image, axis=0)

VGG16 と独自のトレーニング済みモデルを使用して画像を予測します

result = int(cat_dog_model.predict(covn_base.predict(input_data))[0][0])

認識結果の出力と入力画像の表示

if result == 1:
    print("狗")
if result == 0:
    print("猫")
show(resize_image)


ここに画像の説明を挿入
以下が認識結果で、猫は正確、犬の画像は認識され、結果が正確であることがわかります
ここに画像の説明を挿入

この記事はこれで終わりですが、今回の事例は Keras ディープラーニングの小さなテストではありますが、皆さんがディープラーニングに参入するための小さな事例の 1 つとして活用していただければ幸いです。

猫と犬のデータ セット Baidu ネットワーク ディスク リンク

リンク: https://pan.baidu.com/s/16K4P5Nb1k5_sfFml-qEF2g 抽出コード: mchl

おすすめ

転載: blog.csdn.net/wFitting/article/details/123921832