Keras ディープ ラーニングは、Xception の事前トレーニング済みニューラル ネットワークを使用して猫と犬の分類を実現し、テスト セットの精度は 0.99 もの高さです。
前回の記事では、VGG16 事前学習済みニューラル ネットワークを使用して猫と犬の分類を実現しました、つまり、Keras 深層学習は、VGG16 事前学習済みニューラル ネットワークを使用して猫と犬の分類を実現します。その時点でのトレーニング セットの正解率は 0.90 でしたが、テスト セットの正解率は 0.89 でした。
この記事では、Xception の事前トレーニング済みニューラル ネットワークを使用して猫と犬の分類ケースを実装しています。結果は VGG16 よりも優れています。
Xception (分離可能な畳み込み)
ImageNet で事前トレーニングされた Xception V1 モデルは、ImageNet で検証セットの精度率 (最初のヒット結果と最初の 5 つの包含結果) のトップ 1 0.790 およびトップ 5 0.945 を達成しました。
このモデルは、channels_last (高さ、幅、チャネル) の次元順序のみをサポートしていることに注意してください。モデルのデフォルトの入力サイズは 299✖️299 です
実装プロセス
Xception の事前トレーニング済みニューラル ネットワークを使用して猫と犬の画像を分類するプロセスは、事前トレーニング済みのニューラル ネットワークが変更されていることを除いて、VGG16 のプロセスと似ています。
モデルトレーニング
まず、必要なパッケージをインポートする必要があります。このトレーニング モデルには、Xception の事前トレーニング済みネットワーク モデルが使用されています。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 Xception
インターネット上で見つかった猫と犬のデータセット リソースから、猫と犬のデータセットを読み込み、猫と犬のトレーニング (トレーニング) データとテスト (テスト) データを分割します。猫と犬の元のデータセットを百度クラウドディスクにアップロードしました。記事の最後にある必要な記事を選択してください。
# 创建划分好的训练测试目录
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])
Xception 事前トレーニング済みニューラル ネットワークを初期化します。Xception ネットワークを使用し、imageNet 重みを使用します。include_top に最後に完全に接続された層と出力層が含まれるかどうか、
covn_base = Xception(weights='imagenet', include_top=False,
input_shape=(200,200,3))
summary() を使用してニューラル ネットワークの構造を表示します。
covn_base.summary()
Xception モデルの構造:
Model: "xception"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_1 (InputLayer) [(None, 200, 200, 3 0 []
)]
block1_conv1 (Conv2D) (None, 99, 99, 32) 864 ['input_1[0][0]']
block1_conv1_bn (BatchNormaliz (None, 99, 99, 32) 128 ['block1_conv1[0][0]']
ation)
block1_conv1_act (Activation) (None, 99, 99, 32) 0 ['block1_conv1_bn[0][0]']
block1_conv2 (Conv2D) (None, 97, 97, 64) 18432 ['block1_conv1_act[0][0]']
block1_conv2_bn (BatchNormaliz (None, 97, 97, 64) 256 ['block1_conv2[0][0]']
ation)
block1_conv2_act (Activation) (None, 97, 97, 64) 0 ['block1_conv2_bn[0][0]']
block2_sepconv1 (SeparableConv (None, 97, 97, 128) 8768 ['block1_conv2_act[0][0]']
2D)
block2_sepconv1_bn (BatchNorma (None, 97, 97, 128) 512 ['block2_sepconv1[0][0]']
lization)
block2_sepconv2_act (Activatio (None, 97, 97, 128) 0 ['block2_sepconv1_bn[0][0]']
n)
block2_sepconv2 (SeparableConv (None, 97, 97, 128) 17536 ['block2_sepconv2_act[0][0]']
2D)
block2_sepconv2_bn (BatchNorma (None, 97, 97, 128) 512 ['block2_sepconv2[0][0]']
lization)
conv2d (Conv2D) (None, 49, 49, 128) 8192 ['block1_conv2_act[0][0]']
block2_pool (MaxPooling2D) (None, 49, 49, 128) 0 ['block2_sepconv2_bn[0][0]']
batch_normalization (BatchNorm (None, 49, 49, 128) 512 ['conv2d[0][0]']
alization)
add (Add) (None, 49, 49, 128) 0 ['block2_pool[0][0]',
'batch_normalization[0][0]']
block3_sepconv1_act (Activatio (None, 49, 49, 128) 0 ['add[0][0]']
n)
block3_sepconv1 (SeparableConv (None, 49, 49, 256) 33920 ['block3_sepconv1_act[0][0]']
2D)
block3_sepconv1_bn (BatchNorma (None, 49, 49, 256) 1024 ['block3_sepconv1[0][0]']
lization)
block3_sepconv2_act (Activatio (None, 49, 49, 256) 0 ['block3_sepconv1_bn[0][0]']
n)
block3_sepconv2 (SeparableConv (None, 49, 49, 256) 67840 ['block3_sepconv2_act[0][0]']
2D)
block3_sepconv2_bn (BatchNorma (None, 49, 49, 256) 1024 ['block3_sepconv2[0][0]']
lization)
conv2d_1 (Conv2D) (None, 25, 25, 256) 32768 ['add[0][0]']
block3_pool (MaxPooling2D) (None, 25, 25, 256) 0 ['block3_sepconv2_bn[0][0]']
batch_normalization_1 (BatchNo (None, 25, 25, 256) 1024 ['conv2d_1[0][0]']
rmalization)
add_1 (Add) (None, 25, 25, 256) 0 ['block3_pool[0][0]',
'batch_normalization_1[0][0]']
block4_sepconv1_act (Activatio (None, 25, 25, 256) 0 ['add_1[0][0]']
n)
block4_sepconv1 (SeparableConv (None, 25, 25, 728) 188672 ['block4_sepconv1_act[0][0]']
2D)
block4_sepconv1_bn (BatchNorma (None, 25, 25, 728) 2912 ['block4_sepconv1[0][0]']
lization)
block4_sepconv2_act (Activatio (None, 25, 25, 728) 0 ['block4_sepconv1_bn[0][0]']
n)
block4_sepconv2 (SeparableConv (None, 25, 25, 728) 536536 ['block4_sepconv2_act[0][0]']
2D)
block4_sepconv2_bn (BatchNorma (None, 25, 25, 728) 2912 ['block4_sepconv2[0][0]']
lization)
conv2d_2 (Conv2D) (None, 13, 13, 728) 186368 ['add_1[0][0]']
block4_pool (MaxPooling2D) (None, 13, 13, 728) 0 ['block4_sepconv2_bn[0][0]']
batch_normalization_2 (BatchNo (None, 13, 13, 728) 2912 ['conv2d_2[0][0]']
rmalization)
add_2 (Add) (None, 13, 13, 728) 0 ['block4_pool[0][0]',
'batch_normalization_2[0][0]']
block5_sepconv1_act (Activatio (None, 13, 13, 728) 0 ['add_2[0][0]']
n)
block5_sepconv1 (SeparableConv (None, 13, 13, 728) 536536 ['block5_sepconv1_act[0][0]']
2D)
block5_sepconv1_bn (BatchNorma (None, 13, 13, 728) 2912 ['block5_sepconv1[0][0]']
lization)
block5_sepconv2_act (Activatio (None, 13, 13, 728) 0 ['block5_sepconv1_bn[0][0]']
n)
block5_sepconv2 (SeparableConv (None, 13, 13, 728) 536536 ['block5_sepconv2_act[0][0]']
2D)
block5_sepconv2_bn (BatchNorma (None, 13, 13, 728) 2912 ['block5_sepconv2[0][0]']
lization)
block5_sepconv3_act (Activatio (None, 13, 13, 728) 0 ['block5_sepconv2_bn[0][0]']
n)
block5_sepconv3 (SeparableConv (None, 13, 13, 728) 536536 ['block5_sepconv3_act[0][0]']
2D)
block5_sepconv3_bn (BatchNorma (None, 13, 13, 728) 2912 ['block5_sepconv3[0][0]']
lization)
add_3 (Add) (None, 13, 13, 728) 0 ['block5_sepconv3_bn[0][0]',
'add_2[0][0]']
block6_sepconv1_act (Activatio (None, 13, 13, 728) 0 ['add_3[0][0]']
n)
block6_sepconv1 (SeparableConv (None, 13, 13, 728) 536536 ['block6_sepconv1_act[0][0]']
2D)
block6_sepconv1_bn (BatchNorma (None, 13, 13, 728) 2912 ['block6_sepconv1[0][0]']
lization)
block6_sepconv2_act (Activatio (None, 13, 13, 728) 0 ['block6_sepconv1_bn[0][0]']
n)
block6_sepconv2 (SeparableConv (None, 13, 13, 728) 536536 ['block6_sepconv2_act[0][0]']
2D)
block6_sepconv2_bn (BatchNorma (None, 13, 13, 728) 2912 ['block6_sepconv2[0][0]']
lization)
block6_sepconv3_act (Activatio (None, 13, 13, 728) 0 ['block6_sepconv2_bn[0][0]']
n)
block6_sepconv3 (SeparableConv (None, 13, 13, 728) 536536 ['block6_sepconv3_act[0][0]']
2D)
block6_sepconv3_bn (BatchNorma (None, 13, 13, 728) 2912 ['block6_sepconv3[0][0]']
lization)
add_4 (Add) (None, 13, 13, 728) 0 ['block6_sepconv3_bn[0][0]',
'add_3[0][0]']
block7_sepconv1_act (Activatio (None, 13, 13, 728) 0 ['add_4[0][0]']
n)
block7_sepconv1 (SeparableConv (None, 13, 13, 728) 536536 ['block7_sepconv1_act[0][0]']
2D)
block7_sepconv1_bn (BatchNorma (None, 13, 13, 728) 2912 ['block7_sepconv1[0][0]']
lization)
block7_sepconv2_act (Activatio (None, 13, 13, 728) 0 ['block7_sepconv1_bn[0][0]']
n)
block7_sepconv2 (SeparableConv (None, 13, 13, 728) 536536 ['block7_sepconv2_act[0][0]']
2D)
block7_sepconv2_bn (BatchNorma (None, 13, 13, 728) 2912 ['block7_sepconv2[0][0]']
lization)
block7_sepconv3_act (Activatio (None, 13, 13, 728) 0 ['block7_sepconv2_bn[0][0]']
n)
block7_sepconv3 (SeparableConv (None, 13, 13, 728) 536536 ['block7_sepconv3_act[0][0]']
2D)
block7_sepconv3_bn (BatchNorma (None, 13, 13, 728) 2912 ['block7_sepconv3[0][0]']
lization)
add_5 (Add) (None, 13, 13, 728) 0 ['block7_sepconv3_bn[0][0]',
'add_4[0][0]']
block8_sepconv1_act (Activatio (None, 13, 13, 728) 0 ['add_5[0][0]']
n)
block8_sepconv1 (SeparableConv (None, 13, 13, 728) 536536 ['block8_sepconv1_act[0][0]']
2D)
block8_sepconv1_bn (BatchNorma (None, 13, 13, 728) 2912 ['block8_sepconv1[0][0]']
lization)
block8_sepconv2_act (Activatio (None, 13, 13, 728) 0 ['block8_sepconv1_bn[0][0]']
n)
block8_sepconv2 (SeparableConv (None, 13, 13, 728) 536536 ['block8_sepconv2_act[0][0]']
2D)
block8_sepconv2_bn (BatchNorma (None, 13, 13, 728) 2912 ['block8_sepconv2[0][0]']
lization)
block8_sepconv3_act (Activatio (None, 13, 13, 728) 0 ['block8_sepconv2_bn[0][0]']
n)
block8_sepconv3 (SeparableConv (None, 13, 13, 728) 536536 ['block8_sepconv3_act[0][0]']
2D)
block8_sepconv3_bn (BatchNorma (None, 13, 13, 728) 2912 ['block8_sepconv3[0][0]']
lization)
add_6 (Add) (None, 13, 13, 728) 0 ['block8_sepconv3_bn[0][0]',
'add_5[0][0]']
block9_sepconv1_act (Activatio (None, 13, 13, 728) 0 ['add_6[0][0]']
n)
block9_sepconv1 (SeparableConv (None, 13, 13, 728) 536536 ['block9_sepconv1_act[0][0]']
2D)
block9_sepconv1_bn (BatchNorma (None, 13, 13, 728) 2912 ['block9_sepconv1[0][0]']
lization)
block9_sepconv2_act (Activatio (None, 13, 13, 728) 0 ['block9_sepconv1_bn[0][0]']
n)
block9_sepconv2 (SeparableConv (None, 13, 13, 728) 536536 ['block9_sepconv2_act[0][0]']
2D)
block9_sepconv2_bn (BatchNorma (None, 13, 13, 728) 2912 ['block9_sepconv2[0][0]']
lization)
block9_sepconv3_act (Activatio (None, 13, 13, 728) 0 ['block9_sepconv2_bn[0][0]']
n)
block9_sepconv3 (SeparableConv (None, 13, 13, 728) 536536 ['block9_sepconv3_act[0][0]']
2D)
block9_sepconv3_bn (BatchNorma (None, 13, 13, 728) 2912 ['block9_sepconv3[0][0]']
lization)
add_7 (Add) (None, 13, 13, 728) 0 ['block9_sepconv3_bn[0][0]',
'add_6[0][0]']
block10_sepconv1_act (Activati (None, 13, 13, 728) 0 ['add_7[0][0]']
on)
block10_sepconv1 (SeparableCon (None, 13, 13, 728) 536536 ['block10_sepconv1_act[0][0]']
v2D)
block10_sepconv1_bn (BatchNorm (None, 13, 13, 728) 2912 ['block10_sepconv1[0][0]']
alization)
block10_sepconv2_act (Activati (None, 13, 13, 728) 0 ['block10_sepconv1_bn[0][0]']
on)
block10_sepconv2 (SeparableCon (None, 13, 13, 728) 536536 ['block10_sepconv2_act[0][0]']
v2D)
block10_sepconv2_bn (BatchNorm (None, 13, 13, 728) 2912 ['block10_sepconv2[0][0]']
alization)
block10_sepconv3_act (Activati (None, 13, 13, 728) 0 ['block10_sepconv2_bn[0][0]']
on)
block10_sepconv3 (SeparableCon (None, 13, 13, 728) 536536 ['block10_sepconv3_act[0][0]']
v2D)
block10_sepconv3_bn (BatchNorm (None, 13, 13, 728) 2912 ['block10_sepconv3[0][0]']
alization)
add_8 (Add) (None, 13, 13, 728) 0 ['block10_sepconv3_bn[0][0]',
'add_7[0][0]']
block11_sepconv1_act (Activati (None, 13, 13, 728) 0 ['add_8[0][0]']
on)
block11_sepconv1 (SeparableCon (None, 13, 13, 728) 536536 ['block11_sepconv1_act[0][0]']
v2D)
block11_sepconv1_bn (BatchNorm (None, 13, 13, 728) 2912 ['block11_sepconv1[0][0]']
alization)
block11_sepconv2_act (Activati (None, 13, 13, 728) 0 ['block11_sepconv1_bn[0][0]']
on)
block11_sepconv2 (SeparableCon (None, 13, 13, 728) 536536 ['block11_sepconv2_act[0][0]']
v2D)
block11_sepconv2_bn (BatchNorm (None, 13, 13, 728) 2912 ['block11_sepconv2[0][0]']
alization)
block11_sepconv3_act (Activati (None, 13, 13, 728) 0 ['block11_sepconv2_bn[0][0]']
on)
block11_sepconv3 (SeparableCon (None, 13, 13, 728) 536536 ['block11_sepconv3_act[0][0]']
v2D)
block11_sepconv3_bn (BatchNorm (None, 13, 13, 728) 2912 ['block11_sepconv3[0][0]']
alization)
add_9 (Add) (None, 13, 13, 728) 0 ['block11_sepconv3_bn[0][0]',
'add_8[0][0]']
block12_sepconv1_act (Activati (None, 13, 13, 728) 0 ['add_9[0][0]']
on)
block12_sepconv1 (SeparableCon (None, 13, 13, 728) 536536 ['block12_sepconv1_act[0][0]']
v2D)
block12_sepconv1_bn (BatchNorm (None, 13, 13, 728) 2912 ['block12_sepconv1[0][0]']
alization)
block12_sepconv2_act (Activati (None, 13, 13, 728) 0 ['block12_sepconv1_bn[0][0]']
on)
block12_sepconv2 (SeparableCon (None, 13, 13, 728) 536536 ['block12_sepconv2_act[0][0]']
v2D)
block12_sepconv2_bn (BatchNorm (None, 13, 13, 728) 2912 ['block12_sepconv2[0][0]']
alization)
block12_sepconv3_act (Activati (None, 13, 13, 728) 0 ['block12_sepconv2_bn[0][0]']
on)
block12_sepconv3 (SeparableCon (None, 13, 13, 728) 536536 ['block12_sepconv3_act[0][0]']
v2D)
block12_sepconv3_bn (BatchNorm (None, 13, 13, 728) 2912 ['block12_sepconv3[0][0]']
alization)
add_10 (Add) (None, 13, 13, 728) 0 ['block12_sepconv3_bn[0][0]',
'add_9[0][0]']
block13_sepconv1_act (Activati (None, 13, 13, 728) 0 ['add_10[0][0]']
on)
block13_sepconv1 (SeparableCon (None, 13, 13, 728) 536536 ['block13_sepconv1_act[0][0]']
v2D)
block13_sepconv1_bn (BatchNorm (None, 13, 13, 728) 2912 ['block13_sepconv1[0][0]']
alization)
block13_sepconv2_act (Activati (None, 13, 13, 728) 0 ['block13_sepconv1_bn[0][0]']
on)
block13_sepconv2 (SeparableCon (None, 13, 13, 1024 752024 ['block13_sepconv2_act[0][0]']
v2D) )
block13_sepconv2_bn (BatchNorm (None, 13, 13, 1024 4096 ['block13_sepconv2[0][0]']
alization) )
conv2d_3 (Conv2D) (None, 7, 7, 1024) 745472 ['add_10[0][0]']
block13_pool (MaxPooling2D) (None, 7, 7, 1024) 0 ['block13_sepconv2_bn[0][0]']
batch_normalization_3 (BatchNo (None, 7, 7, 1024) 4096 ['conv2d_3[0][0]']
rmalization)
add_11 (Add) (None, 7, 7, 1024) 0 ['block13_pool[0][0]',
'batch_normalization_3[0][0]']
block14_sepconv1 (SeparableCon (None, 7, 7, 1536) 1582080 ['add_11[0][0]']
v2D)
block14_sepconv1_bn (BatchNorm (None, 7, 7, 1536) 6144 ['block14_sepconv1[0][0]']
alization)
block14_sepconv1_act (Activati (None, 7, 7, 1536) 0 ['block14_sepconv1_bn[0][0]']
on)
block14_sepconv2 (SeparableCon (None, 7, 7, 2048) 3159552 ['block14_sepconv1_act[0][0]']
v2D)
block14_sepconv2_bn (BatchNorm (None, 7, 7, 2048) 8192 ['block14_sepconv2[0][0]']
alization)
block14_sepconv2_act (Activati (None, 7, 7, 2048) 0 ['block14_sepconv2_bn[0][0]']
on)
==================================================================================================
Total params: 20,861,480
Trainable params: 20,806,952
Non-trainable params: 54,528
__________________________________________________________________________________________________
Xceptionネットワークを使用して画像の特徴量を抽出し、それを線形ネットワークに入れてトレーニングし、速度を向上させます
batch_size = 20
def extract_features(data_generator, sample_count):
i = 0
features = np.zeros(shape=(sample_count, 7, 7, 2048))
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 層を構築して結果を出力し、Xception で処理された画像データを GlobalAveragePooling2D を使用して平坦化し (つまり 1 次元データにし)、最終的に y=w1x1+w2x2 の問題に集約します。 ..+b. 結果を出力します。relu 活性化関数を使用します。Dropout を使用して過学習を抑制します。結果は 2 値分類、つまり 0 は猫、1 は犬であるため、最後に結果を出力します。したがって、出力結果は1つしかないため、シグモイド関数を使用して二項分類結果を出力します。
model = keras.Sequential()
model.add(layers.GlobalAveragePooling2D(input_shape=(7, 7, 2048)))
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dropout(0.7))
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 はテスト セットの正解率です。結果は依然として比較的理想的であり、トレーニング セットとテスト セットの精度は約 99% に達し、フィッティングが非常に良好であることがわかります。
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()
Xception の重みと保存されたトレーニング モデルをロードします。
covn_base = tf.keras.applications.Xception(weights='imagenet', include_top=False, input_shape=(200, 200, 3))
cat_dog_model = load_model('./cat_dog_model.h5')
OpenCV を使用して画像を読み取り、画像を 200✖️200 のサイズにリサイズし、画像データを Xception が必要とするデータ形式に展開します。
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)
Xception と独自のトレーニング済みモデルをそれぞれ使用して画像を予測します
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