- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍦 参考文章:[深度学习100例-卷积神经网络(CNN)彩色图片分类 | 第2天]
- 🍖 原作者:K同学啊|接辅导、项目定制
我的环境:
- 语言环境:Python3.11.2
- 编译器:PyCharm Community Edition 2022.3
- 深度学习环境:TensorFlow2
一、运行代码
1.1 前期工作
依旧使用TensorFlow进行彩色图片分类的学习
#彩色图片分类
import tensorflow as tf
from tensorflow.keras import datasets,layers,models
import matplotlib.pyplot as plt
#导入数据
(train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data()
#归一化
train_images = train_images/255.0
test_images = test_images/255.0
#可视化图片
#设置展示标签
class_name = ['airplane', 'automoblie', 'bird', 'cat', 'deer', 'dog', 'frog', 'hores', 'ship', 'truck']
#展示前20张图片
plt.figure(figsize=(20,10))
for i in range(20):
#设置布局两行十列,子图为第i+1个
plt.subplot(2, 10, i+1)
#不显示x轴,y轴刻度
plt.xticks([])
plt.yticks([])
#不显示网格线
plt.grid(False)
#图片展示
plt.imshow(train_images[i], cmap=plt.cm.binary)
#设置x轴标签
plt.xlabels(class_name[train_labels[i][0]])
plt.show()
在导入数据时使用了tf.keras.datasets.cifar10.load_data()进行导入, 其中tf.keras.datasets.cifar10的定义在keras.datasets.cifar10模块中,也包括load_data函数。load_data函数通过访问函数内所给的网址获取数据。
彩色图片在使特征处于同一数量级时依然使用归一化,直接除以最大值与最小值的差即255.0。
与mnist手写集相同,cifar10的标签也是用数字表示, 想在显示中明确看到图片分类需要先定义一个列表将种类类型放入列表中,即class_name列表。
1.2 构建CNN网络
#构建CNN网络
model = models.Sequential([
#构建第一个卷积层,32个3*3卷积核,激活函数为ReLu
layers.Conv2D(32, (3, 3), activation='relu',input_shape=(32, 32, 3)),
#设置第一个池化层
layers.MaxPooling2D(2, 2),
#设置第2个卷积层
layers.Conv2D(64, (3, 3), activation='relu'),
#设置第二个池化层
layers.MaxPooling2D(2, 2),
#设置第三个卷积层
layers.Conv2D(64, (3, 3), activation='relu'),
#设置Flatten连接层
layers.Flatten(),
#设置全连接层
layers.Dense(64, activation='relu'),
#设置输出层
layers.Dense(10)
])
#打印网络结构
model.summary()
池化层分为两类,最大池化层和均值池化层。均值池化层对背景保留更好,而最大池化层对纹理提取更好。
在网络结构中有两个参数output shape和param,output shape为输出形状,param为模型中需要训练的参数总数,这些参数是通过训练数据得到的权重,用于卷积操作中的特征提取。从输出结果可以看出经过卷积层后输出的形状=输入形状-卷积核+1 ,而经过池化层输出的形状却不符合,这是因为池化层默认步长为池化核大小,在2*2的池化核进行池化操作时,会在处理完一组数据后移动步长的长度后再次进行池化操作直到处理完成。
1.3 编译
model.compile(
#设置优化器
optimizer='adam',
#设置损失函数
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
#设置性能指标列表
metrics=['accuracy']
)
1.4 训练模型
history = model.fit(train_images,train_labels,epochs=10,
validation_data=(test_images, test_labels)
)
fit函数返回的是History对象,其History.histry属性记录了损失函数和其他指标的数值随epoch变化的情况
1.5 预测
#显示测试集第一张图
plt.imshow(test_images[0])
plt.show()
#导入numpy库
import numpy as np
#预测测试集全部图片
pre = model.predict(test_images)
print(class_name[np.argmax(pre[0])])
np.argmax是对函数求参数的函数,即将pre[0]看作f(x),则np.argmax函数求的便是x的最大值。
pre[0]的输出结果:
print(pre[0])
可以看到最大是第4个,此时np.argmax(pre[0])返回值为3,最终输出结果为'cat'
1.6 模型评估
#绘制函数
plt.plot(history.history['accuracy'], label='accuracy')
plt.plot(history.history['val_accuracy'], label='val_accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.ylim([0.5, 1])
plt.legend(loc='lower right')
plt.show
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
使用plt.plot函数构建模型函数,plt.ylim函数指定了y轴的范围为0.5到1,plt.legend(loc='')设置图例的位置。
model.evaluate函数将对测试集的预测结果与测试集标签进行对比,结果将返回损失值(loss)和精度(accuracy),参数verbose只有1和2两个值,分别表示是否显示进度条。
verbose为1:
verbose为2:
二、图片识别
代码成功跑通后在百度上找张彩色图片进行识别
原始图片:
将其调整为32*32*3的jpg图片:
#引入图片
img = plt.imread('C:\\Users\\DELL\\Desktop\\c.jpg')
#更改图片格式
x = img.reshape((1,32,32,3))
#使用模型进行识别
pre1 = model.predict(x)
#输出结果
print(pre1)
print(class_name[np.argmax(pre1)])
运行了两次,第二次得到正确的结果: