FashionMNIST

训练首个神经网络: 基本分类(个人总结)

项目背景: 数据集是FashionMNIST(70000张28*28灰度图像(训练6/测试1), 含衣服着装的10个类别), 此数据集本身已经被包含在keras中, 故只要导入keras.datasets.fashion_mnist模块, 调用函数fashion_mnist.load_data(), 便可以得到: 训练集数据/标签, 测试集数据/标签的变量(图片由视觉平面变成了np.array()的编程数据格式).

步骤要点

以下罗列一个(神经网络)模型搭建并跑通的一套要素点, 分为以下4个步骤点.

步骤1: 数据预处理.

图像为灰度图, 但是也有256个灰度, 在进入训练前, 要将其归一化到(0,1)区间(否则, 结果就是19.2%左右的准确度, 原因应该是相对于模型参数数量(一个128的Dense层和一个10的Dense层), 图片的值区间过大, 模型参数无法拟合它们?!).

步骤2/A: 模型构建.

模型层(构建) 说明
keras.layers.Flatten(input_shape=(28, 28)) 将图片弄成784的行向量(Flatten, 扁平化)
keras.layers.Dense(128, activation=tf.nn.relu) Dense是全连接层, 共128个神经元, 这个层后面也跟了relu的激活(sub层)
keras.layers.Dense(10, activation=tf.nn.softmax) 含10个神经元(作为输出), 激活则是softmax(softmax之后才是最终分类概率, 这之前的是logits)

步骤2/B: 模型编译.

编译要素 说明
优化器(optimizer) 根据模型损失函数的定义, 去减小数据与给定标签之间的损失函数值, 反正只要是连续函数, 优化器都想办法给你用偏导搞定, 偏导求出梯度之后(不是斜率), 模型得到更新, 更加拟合了, 我们说优化器(偏导+更新参数的方式)优化了模型, 或者机器/深度学习了. (注: 这里引出一个点, 机器学习, 更贴切的辞藻应该是数学拟合, 而机器学习这个用法给了外界一种前景预期)
损失函数(loss) (稀疏)类别交叉熵(parse_categorical_crossentropy), 根据模型跑出的结果概率和标签之间差别计算损失大小. (此处, 告诉PYTHON如何使用网络softmax输出和标签: ‘sparse_categorical_crossentropy‘)
指标(metrics) 评估模型效果的标准, 如”accuracy”, 就是准确数/总数, 这个指标/标准很常用了, 以至于其它标准说”ExcuseMe?!”.
1
2
3
4
# 代码;
model.compile(optimizer = tf.train.AdamOptimizer(),
loss = 'sparse_categorical_crossentropy',
metrics = ['accuracy'])

步骤3: 模型训练(拟合).

以上, 有了模型和一套对模型操作的具体方法(compile()中的内容), 那么就需要让它们动起来了, 让那套想法真正地作用于模型参数, 即优化并获取到更好的拟合参数, 下面, model.fit()出场:

1
2
3
4
5
6
7
8
9
10
11
12
model.fit(train_images, train_labels, epochs=5)
# keras训练时的输出, 训练期间, 系统会显示损失和准确率指标;
Epoch 1/5
60000/60000 [==============================] - 5s 87us/step - loss: 0.5033 - acc: 0.8242
Epoch 2/5
60000/60000 [==============================] - 5s 80us/step - loss: 0.3803 - acc: 0.8643
Epoch 3/5
60000/60000 [==============================] - 5s 85us/step - loss: 0.3399 - acc: 0.8758
Epoch 4/5
60000/60000 [==============================] - 5s 87us/step - loss: 0.3141 - acc: 0.8855
Epoch 5/5
60000/60000 [==============================] - 5s 88us/step - loss: 0.2941 - acc: 0.8917

步骤4: 模型评估/预测.

上面, 我们得到了训练过的一个模型, 不管其参数是否理想, 我们接下来使用还没使用的测试集, 来评估准确率(metrics=['accuracy']):

1
2
3
4
5
6
# 把 test_images 和 对应的test_labels 给 model.evaluate(), 它会帮你计算出结果;
test_loss, test_acc = model.evaluate(test_images, test_labels)
print('Test accuracy:', test_acc)
# 输出;
10000/10000 [==============================] - 1s 50us/step
Test accuracy: 0.8734

上面是整个模型的准确率, 要用模型来做真正的事情了, 即预测:

1
2
3
4
5
6
7
8
9
predictions = model.predict(test_images)
predictions[0]
# 输出, 最后一个值最大, 所以argmax()应该挑选出它;
array([4.2577299e-06, 7.2840301e-08, 2.3979945e-08, 2.0671453e-06,
9.1094840e-08, 1.2096325e-01, 1.5182156e-06, 1.9717012e-01,
1.2066002e-05, 6.8184656e-01], dtype=float32)
np.argmax(predictions[0])
# 输出;
9

总结

至此, FashionMNIST与一个简单的神经网络总结完毕, 这里的模型是神经网络而不是卷积神经网络, 因为这个数据集中的数据相对简单(2828, 黑白灰度, 干净, 归一化处理过), 所以用不了多少参数(784\128 + 128*10, 这个数量只包含了w参数)就能学会拟合这个数据集了.

一个模型的全过程: 1.数据(训练/测试), 2.模型构建/编译, 3.模型训练/拟合, 4.预测和指标评估.

Reference:

  1. 训练首个神经网络: 基本分类[REF].
  2. FashionMNIST[数据集].
1
2
3
4
5
6
7
8
9
10
11
12

graph LR

A[方形] -->B(圆角)

B --> C{条件a}

C -->|a=1| D[结果1]

C -->|a=2| E[结果2]

F[横向流程图]

$\Gamma$

${n+1 \choose k}={n \choose k}+{n \choose k-1}$

$\overline{xyz}$