一、实验介绍
-
实验环境:jupyter notebook、Tensorflow.keras
-
数据集Fashion Mnist与样例代码及相关参考:
https://www.tensorflow.org/tutorials/keras/classification
https://zhuanlan.zhihu.com/p/161656714
https://msd.misuland.com/pd/4146263742822220136
https://baijiahao.baidu.com/s?id=1653421414340022957&wfr=spider&for=pc1、认识数据集
2、尝试使用DNN、CNN
等神经网络模型进行分类
3、评估、比较各模型的性能
二、Fashion MNIST数据集
- 包含
10
个类别的70000
个灰度图像。这些图像以低分辨率(28×28像素)展示了单件衣物。
Fashion MINIST
旨在临时替代经典MNIST
数据集,后者常被用作计算机视觉机器学习程序的“Hello, World”。MNIST
数据集包含手写数字(0、1、2 等)的图像,其格式与您将使用的衣物图像的格式相同。- 使用 Fashion MNIST来实现多样化,因为它比常规 MNIST更具挑战性。这两个数据集都相对较小,都用于验证某个算法是否按预期工作。对于代码的测试和调试,它们都是很好的起点。
标签 | 类 |
---|---|
0 | T恤/上衣 |
1 | 裤子 |
2 | 套头衫 |
3 | 连衣裙 |
4 | 外套 |
5 | 凉鞋 |
6 | 衬衫 |
7 | 运动鞋 |
8 | 包 |
9 | 短靴 |
三、实验代码和结果截图
1、导入python包
tf.keras
是Tensorflow
中用来构建和训练模型的高级API。
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow import keras
2、全局变量
-
train_images
和train_labels
是模型用来学习的数据,test_images
和test_labels
被用来对模型进行测试。 -
每个图像都会被映射到一个标签。
fashion_minist = keras.datasets.fashion_mnist# 载入Fashion MINIST数据集
# 返回四个28×28的Numpy数组,像素值介于0~255之间,标签是整数数组,介于0~9之间
(train_images,train_labels),(test_images,test_labels) = fashion_minist.load_data()
# 数据集中不包括类名称,将它们存储在class_names中供稍后绘制图像时使用
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
# 将像素值缩小至0~1之间,对训练集和测试集做相同处理
train_images = train_images / 255.0
test_images = test_images / 255.0
# (为了验证数据的格式是否正确,以及是否已准备好构建和训练网络)显示训练集中的前25个图像,并在每个图像的下方显示类名称
plt.figure(figsize = (10,10))
for i in range (25):
plt.subplot(5,5,i+1)# 五行五列
plt.xticks([])
plt.yticks([])
# plt.imshow(train_images[i],cmap=plt.cm.gray)
plt.imshow(train_images[i],cmap=plt.cm.binary)# cmap参数接受一个值,其中每个值代表一种配色方案
plt.xlabel(class_names[train_labels[i]])
plt.show()
3、构建模型:构建神经网络模型需要先配置模型的层,然后再编译模型
3.1 构建DNN模型
-
该网络的第一层
tf.keras.layers.Flatten
将图像格式从二维数组(28 x 28 像素)转换成一维数组(28 x 28 = 784 像素)。将该层视为图像中未堆叠的像素行并将其排列起来。该层没有要学习的参数,它只会重新格式化数据。 -
展平像素后,网络会包括两个
tf.keras.layers.Dense
层的序列。它们是密集连接或全连接神经层。第一个 Dense 层有 128 个节点(或神经元)。第二个(也是最后一个)层会返回一个长度为 10 的 logits 数组。每个节点都包含一个得分,用来表示当前图像属于 10 个类中的哪一类。 -
在深度神经网络中,通常使用一种叫线性整流函数(修正线性单元):
Rectified Linear Unit(ReLU)
,作为神经元的激活函数。 R e L U ( x ) = m a x ( 0 , x ) ReLU(x) = max(0,x) ReLU(x)=max(0,x),即
R e L U ( x ) = { 0 if x < 0 x if x ≥ 0 ReLU(x) = \begin{cases} 0& \text{ if } x<0 \\ x& \text{ if } x≥0 \end{cases} ReLU(x)={0x if x<0 if x≥0 -
在准备对模型进行训练之前,还需要再对其进行一些设置。以下内容是在模型的编译步骤中添加的:
① 损失函数(loss function
) :用于测量模型在训练期间的准确率。您会希望最小化此函数,以便将模型“引导”到正确的方向上。
② 优化器(optimizer
) :决定模型如何根据其看到的数据和自身的损失函数进行更新。
③ 指标 (例如:accuracy
):用于监控训练和测试步骤。以下示例使用了准确率,即被正确分类的图像的比率。
# 设置层
model = keras.Sequential([
keras.layers.Flatten(input_shape = (28,28)),
keras.layers.Dense(128, activation = 'relu'),
keras.layers.Dense(10)
])
# 编译模型
model.compile(optimizer = 'adam',
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics = ['accuracy'])
# 训练模型
model.fit(train_images,train_labels,epochs=10)# epochs:迭代次数
# 评估准确率
test_loss_dnn, test_acc_dnn = model.evaluate(test_images,test_labels,verbose=2)
print("\nTest accuracy is:",test_acc_dnn)
# 进行预测
probability_model = tf.keras.Sequential([model,tf.keras.layers.Softmax()])
predictions = probability_model.predict(test_images)
# 第一个预测结果
predictions[0]
3.2 构建CNN模型,CNN模型中多了卷积层和池化层,先卷积再池化再卷积再池化,最后全连接层。
# Fashion MINIST数据集是3维的,不符合卷积的输入要求(4维),采用如下命令将3维的输入扩展维4维的输入
train_images = np.expand_dims(train_images, axis=3)
test_images = np.expand_dims(test_images, axis=3)
# 设置层
model=keras.models.Sequential([
keras.layers.Conv2D(64, (3, 3), activation='relu', input_shape=(28,28,1)),
keras.layers.MaxPooling2D(2,2),
keras.layers.Conv2D(64,(3,3),activation='relu'),
keras.layers.MaxPooling2D(2,2),
keras.layers.Flatten(),
keras.layers.Dense(128, activation=tf.nn.relu),
keras.layers.Dense(10)
])
# 编译模型
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
# 训练模型
model.fit(train_images,train_labels,epochs=10,
validation_data=(test_images,test_labels))# epochs:迭代次数
# 评估准确率
test_loss_cnn, test_acc_cnn = model.evaluate(test_images,test_labels,verbose=2)
print("\nTest accuracy is:",test_acc_cnn)
四、总结
本案例同样的迭代10次,使用CNN
比使用DNN
运行时间长的多,但CNN的准确度更高,可自行设置不同的迭代次数,比较两种模型的运行时间、准确度等(除迭代次数,激活函数的选择和优化器的选择等都对准确度有影响)。