Keras deep learning uses Xception pre-trained neural network to realize cat and dog classification, and the accuracy of the test set is as high as 0.99
In the previous article, I used the VGG16 pre-trained neural network to realize the case of cat and dog classification, that is, Keras deep learning uses the VGG16 pre-trained neural network to realize the classification of cats and dogs . The accuracy rate of the training set at that time was 0.90, while the test set The accuracy rate is 0.89.
This article uses the Xception pre-trained neural network to implement a cat and dog classification case, and the result will be better than VGG16.
Xception (separable convolution)
The Xception V1 model pre-trained on ImageNet, on ImageNet, the model has achieved the verification set top1 0.790 and top5 0.945 accuracy rate (the first hit result and the first five inclusion results).
Note that this model only supports the dimension order of channels_last (height, width, channel). The default input size of the model is 299✖️299
Implementation process
The process of using the Xception pre-trained neural network to classify cat and dog images is similar to that of VGG16, except that the pre-trained neural network has been changed.
model training
First of all, we need to import the required packages. For this training model, the Xception pre-trained network model is used. It is also good news for those who do not have GPU support. It can speed up model training, and can also greatly improve the accuracy of small batch data sets.
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
From the cat and dog dataset resources found on the Internet, load the cat and dog dataset and divide the cat and dog training (train) data and test (test) data. I have uploaded the original data set of cats and dogs to Baidu cloud disk. Please pick up the required articles at the end of the article.
# 创建划分好的训练测试目录
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)
Create an image data iterator and normalize the original image
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')
Using Matplotlib, we can output the image; the data of the image is essentially the color data value of the three channels, namely the RGB value.
# [批次](批次数据集, 批次二分类结果)[批次数据集下标] --- 对应迭代器的数据格式
# 0 为猫;1 为狗 --- 二分类结果表示
plt.imshow(train_generator[0][0][0])
print(train_generator[0][1][0])
Initialize the Xception pre-trained neural network; use the Xception network, use imageNet weights, whether include_top includes the last fully connected layer and output layer,
covn_base = Xception(weights='imagenet', include_top=False,
input_shape=(200,200,3))
Use summary() to view the structure of the neural network
covn_base.summary()
The structure of the Xception model:
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
__________________________________________________________________________________________________
Use the Xception network to extract the feature value of the picture, and put it into the linear network for training to improve the speed
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)
Build the fully connected Dense layer of your own model and output the results; use GlobalAveragePooling2D to flatten the image data processed by Xception (that is, become one-dimensional data), and finally boil down to the problem of y=w1x1+w2x2...+b. The result is output; use the relu activation function; use Dropout to suppress overfitting; finally output the result, because the result is a binary classification, that is, 0 is a cat and 1 is a dog. Therefore, there is only one output result, so the sigmoid function is used to output the binary classification result.
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'))
Compile the model; use the Adam activation function, and adjust the optimization rate; because it is a two-category problem, the loss function here uses binary_crossentropy
model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.0005/10), loss='binary_crossentropy', metrics=['acc'])
Start training the model; test the test set during training, here a total of 50 training
history = model.fit(train_featrues,train_labels, epochs=50, batch_size=50, validation_data=(test_featrues, test_labels))
The following are the training results. Among them, loss is the loss value of the training set, acc is the accuracy rate of the training set; val_loss is the loss value of the test set, and val_acc is the accuracy rate of the test set. It can be seen that the results are relatively ideal, the accuracy of the training set and test set can reach about 99%, and the fitting is very good.
Using Matplotlib to draw the accuracy curves of the following training set and test set, you can see the changes in the training process more clearly.
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
Save the trained model as a local h5 type file
model.save('cat_dog_model.h5')
After the above training process is completed, the next step is to use the saved trained model to test the real data
model testing
In the model test, for convenience, we use OpenCV to help us resize the pictures acquired on the network and display the output results conveniently.
Import the required packages.
import tensorflow as tf
import numpy as np
from keras.models import load_model
import cv2
Define the OpenCV image display function
def show(image):
cv2.namedWindow('test', 0)
cv2.imshow('test', image)
# 0任意键终止窗口
cv2.waitKey(0)
cv2.destroyAllWindows()
Load the weights of Xception and the saved training model
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')
Use OpenCV to read the picture and resize the picture to a size of 200✖️200, and expand the image data to the data format required by 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)
Use Xception and your own trained model to predict the image respectively
result = int(cat_dog_model.predict(covn_base.predict(input_data))[0][0])
Output the recognition result and display the input image
if result == 1:
print("狗")
if result == 0:
print("猫")
show(resize_image)
You can see that the following is the recognition result, the cat is accurate, and
the dog image is recognized, and the result is accurate
This is the end of the article. Even if this case is a small test of Keras deep learning, I hope it can also be used as one of the small cases for everyone to enter deep learning.
Cat and dog data set Baidu network disk link
Link: https://pan.baidu.com/s/16K4P5Nb1k5_sfFml-qEF2g Extraction code: mchl