Fashion MNIST数据集构建DNN神经网络模型

通过Fashion MNIST数据集构建DNN神经网络模型


一、导入Fashion MNIST数据集

Fashion MNIST数据集包括了是70000张服饰图片的数据集,图片格式是均为28*28像素的灰度图,每张图片内容对应相应的服饰种类,共有10种。
在这里插入图片描述
在这里插入图片描述

其中60000张供训练,10000张供测试。


Tensorflow 当中就内置了该数据集,使用时我们直接使用load_data()导入即可,代码如下:

from tensorflow import keras
fashion_mnist=keras.datasets.fashion_mnist
(train_images,train_labels),(test_images,test_labels)=fashion_mnist.load_data()

加载完数据集后,我们先看一下训练集图片规格

print(train_images.shape)

结果显示就是60000张28行28列像素组成的图片集。

(60000, 28, 28)

再来看trian_images当中的第一张图片的信息。

print(train_images[0])

输出出来是一个28*28的矩阵,矩阵中对应位置上的值是其灰度值,如下所示:

[[  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   1   0   0  13  73   0
    0   1   4   0   0   0   0   1   1   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   3   0  36 136 127  62
   54   0   0   0   1   3   4   0   0   3]
 [  0   0   0   0   0   0   0   0   0   0   0   0   6   0 102 204 176 134
  144 123  23   0   0   0   0  12  10   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0 155 236 207 178
  107 156 161 109  64  23  77 130  72  15]
 [  0   0   0   0   0   0   0   0   0   0   0   1   0  69 207 223 218 216
  216 163 127 121 122 146 141  88 172  66]
 [  0   0   0   0   0   0   0   0   0   1   1   1   0 200 232 232 233 229
  223 223 215 213 164 127 123 196 229   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0 183 225 216 223 228
  235 227 224 222 224 221 223 245 173   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0 193 228 218 213 198
  180 212 210 211 213 223 220 243 202   0]
 [  0   0   0   0   0   0   0   0   0   1   3   0  12 219 220 212 218 192
  169 227 208 218 224 212 226 197 209  52]
 [  0   0   0   0   0   0   0   0   0   0   6   0  99 244 222 220 218 203
  198 221 215 213 222 220 245 119 167  56]
 [  0   0   0   0   0   0   0   0   0   4   0   0  55 236 228 230 228 240
  232 213 218 223 234 217 217 209  92   0]
 [  0   0   1   4   6   7   2   0   0   0   0   0 237 226 217 223 222 219
  222 221 216 223 229 215 218 255  77   0]
 [  0   3   0   0   0   0   0   0   0  62 145 204 228 207 213 221 218 208
  211 218 224 223 219 215 224 244 159   0]
 [  0   0   0   0  18  44  82 107 189 228 220 222 217 226 200 205 211 230
  224 234 176 188 250 248 233 238 215   0]
 [  0  57 187 208 224 221 224 208 204 214 208 209 200 159 245 193 206 223
  255 255 221 234 221 211 220 232 246   0]
 [  3 202 228 224 221 211 211 214 205 205 205 220 240  80 150 255 229 221
  188 154 191 210 204 209 222 228 225   0]
 [ 98 233 198 210 222 229 229 234 249 220 194 215 217 241  65  73 106 117
  168 219 221 215 217 223 223 224 229  29]
 [ 75 204 212 204 193 205 211 225 216 185 197 206 198 213 240 195 227 245
  239 223 218 212 209 222 220 221 230  67]
 [ 48 203 183 194 213 197 185 190 194 192 202 214 219 221 220 236 225 216
  199 206 186 181 177 172 181 205 206 115]
 [  0 122 219 193 179 171 183 196 204 210 213 207 211 210 200 196 194 191
  195 191 198 192 176 156 167 177 210  92]
 [  0   0  74 189 212 191 175 172 175 181 185 188 189 188 193 198 204 209
  210 210 211 188 188 194 192 216 170   0]
 [  2   0   0   0  66 200 222 237 239 242 246 243 244 221 220 193 191 179
  182 182 181 176 166 168  99  58   0   0]
 [  0   0   0   0   0   0   0  40  61  44  72  41  35   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]
 [  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0
    0   0   0   0   0   0   0   0   0   0]]

我们用matplotlib库将此图片显示出来

代码如下:

import matplotlib.pyplot as plt
print(plt.imshow(train_images[0]))

得到下图:
第一张图片

看一下训练集标签的规格

print(train_labels.shape)
print(train_labels)

它其实就是60000个0-9的数字集合,0-9每个数字分别对应一种服饰,一共有10类。

(60000,)
[9 0 0 ... 3 0 5]

二、模型的构造

仍然采用我们的Sequential顺序模型,我们在这里建立三层。

  • 第一层为Flatten层,作用是将输入到这一层的数据降维展平,经过这一层可以将60000* 28* 28的张量形状展平成60000 *(28 *28),相当于特殊的reshape操作。
  • 第二层为Dense,同时我们设置了它的神经单元节点数为128个,激活函数使用的是ReLU。
  • 第三层为Dense,同时我们设置了它的神经单元节点数为10个,激活函数使用的是softmax。这一层也是我们的输出层,它最后会输出十个表示概率的数据,其中最大那个数据的索引值就代表预测的相应服饰的种类。

代码如下:

model=keras.Sequential([
    keras.layers.Flatten(input_shape=(28,28)),
    keras.layers.Dense(128,activation='relu'),
    keras.layers.Dense(10,activation='softmax')])

三、模型的训练与评估

1.模型编译与训练

  • 优化方法选用adam,这是现在一种流行且常用的优化方法,且是适合我们此次模型的优化;
  • 因为我们这个数据集的labels是数字编码,所用我们选用的损失函数是sparse_categorical_crossentropy(若labels是one-hot 编码,就要用 categorical_crossentropy作为损失函数);
  • 评价函数用于估计当前训练模型的性能,它与损失函数相似,只不过评价函数不会用于训练过程中,我们在此处使用accuracy对模型进行评价与度量。

当然优化方法、损失函数以及评价函数的选取均不唯一,这里选用的各函数都是比较适合本模型构建的。

代码如下:

model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
model.fit(train_images,train_labels,epochs=5)
Epoch 1/5
1875/1875 [==============================] - 2s 924us/step - loss: 2.8096 - accuracy: 0.6776
Epoch 2/5
1875/1875 [==============================] - 2s 820us/step - loss: 0.7157 - accuracy: 0.7189
Epoch 3/5
1875/1875 [==============================] - 2s 907us/step - loss: 0.6311 - accuracy: 0.7618
Epoch 4/5
1875/1875 [==============================] - 2s 838us/step - loss: 0.5610 - accuracy: 0.7991
Epoch 5/5
1875/1875 [==============================] - 1s 775us/step - loss: 0.5334 - accuracy: 0.8103

我们可以看出随着迭代次数的增加,loss值变得越来越小,accuracy不断变大,说明模型在逐步变优。

这里注意每次迭代数据为1875,这与我们已知60000张图片的数据量不符,但实际上因为神经网络训练是一批一批的送进去的,这个显示的是有1875批,并不会影响最终结果


我们会通过model.summary()输入各层参数情况
model.summary()

在这里插入图片描述
这里我们可以看出faltten层无任何参数;

第一层dense有(28* 28+ 1)* 128=100480个参数;

第二层dense有(128+ 1) *10=1290个参数。

2.模型的评估与预测

用model.evaluate()对test_images,test_labels进行评估
代码如下:

print(model.evaluate(test_images,test_labels))
313/313 [==============================] - 0s 510us/step - loss: 0.5897 - accuracy: 0.8057
[0.589713454246521, 0.8057000041007996]

得到了他们的loss=0.5897,accuracy=0.8057


再输出对第一张图片的预测结果,得到以下数据

print(model.predict(test_images)[0])
[7.7883360e-21 1.2046684e-14 7.0122875e-32 1.8309863e-20 8.0739542e-33
 5.0458151e-01 8.1663665e-30 2.1106225e-01 8.7941183e-14 2.8435624e-01]

各数据表相应概率,找出最大数据值索引与其第一张图片的标签进行对比。

import numpy as np
print(np.argmax(model.predict(test_images)[0]))
print(test_labels[0])
9
9

结果都为9,说明该模型对第一张图的种类预测正确。

四、模型的优化

1.Normalization

首先我们将train_images和test_images的值进行Normalization, Normalization是一个统计学中的概念,我们可以叫它归一化或者规范化,它并不是一个完全定义好的数学操作(如加减乘除)。它通过将数据进行偏移和尺度缩放调整,在数据预处理时是非常常见的操作,在网络的中间层如今也很频繁的被使用。

我们只需进行下列代码的改动,其他代码不变。

train_images=train_images/255.0
test_images=test_images/255.0
Epoch 1/5
1875/1875 [==============================] - 1s 735us/step - loss: 0.4999 - accuracy: 0.8226
Epoch 2/5
1875/1875 [==============================] - 1s 712us/step - loss: 0.3733 - accuracy: 0.8660
Epoch 3/5
1875/1875 [==============================] - 1s 767us/step - loss: 0.3368 - accuracy: 0.8767
Epoch 4/5
1875/1875 [==============================] - 1s 742us/step - loss: 0.3129 - accuracy: 0.8859
Epoch 5/5
1875/1875 [==============================] - 1s 723us/step - loss: 0.2931 - accuracy: 0.8919

我们可以看到相对于未进行Normalization的模型,该模型经5次迭代之后的loss值更低,并且accuracy值更高,说明模型变得更优。

2.找到最佳的训练次数

当我们的模型建立过程中训练次数过多的话,模型会出现过拟合的情况,使得模型过于拟合于训练集的数据,而对新输入的数据预测结果并不很理想;但是,如果我们训练次数较少的话,模型的拟合程度也不会很好。所以,找到最佳的训练次数对模型的优化也至关重要。

对此,我们需要设定一个类,代码如下;
我们这个类是对Callback类的继承,我们只需设定好终止条件,然后在model.fit()中调用它,我们就能得到想要的结果。

class Callback1(tf.keras.callbacks.Callback):
    def on_epoch_end(self,epoch,logs={}):
        if(logs.get('loss')<0.3):
            self.model.stop_training=True
...
model.fit(train_images,train_labels,epochs=10,callbacks=Callback1())

3.最优方法完整代码

实现Callback和Normalization完整代码如下所示:

import tensorflow as tf
from tensorflow import keras
import matplotlib.pyplot as plt 
import numpy as np
class Callback1(tf.keras.callbacks.Callback):
    def on_epoch_end(self,epoch,logs={}):
        if(logs.get('loss')<0.3):
            self.model.stop_training=True
fashion_mnist=keras.datasets.fashion_mnist
(train_images,train_labels),(test_images,test_labels)=fashion_mnist.load_data()
train_images=train_images/255.0
test_images=test_images/255.0
model=keras.Sequential([
    keras.layers.Flatten(input_shape=(28,28)),
    keras.layers.Dense(128,activation='relu'),
    keras.layers.Dense(10,activation='softmax')])
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
model.fit(train_images,train_labels,epochs=10,callbacks=Callback1())
print(model.evaluate(test_images,test_labels))

运行结果:

Epoch 1/10
1875/1875 [==============================] - 1s 796us/step - loss: 0.4992 - accuracy: 0.8228
Epoch 2/10
1875/1875 [==============================] - 1s 722us/step - loss: 0.3751 - accuracy: 0.8637
Epoch 3/10
1875/1875 [==============================] - 1s 787us/step - loss: 0.3389 - accuracy: 0.8759
Epoch 4/10
1875/1875 [==============================] - 1s 755us/step - loss: 0.3150 - accuracy: 0.8838
Epoch 5/10
1875/1875 [==============================] - 1s 722us/step - loss: 0.2986 - accuracy: 0.8895

313/313 [==============================] - 0s 490us/step - loss: 0.3491 - accuracy: 0.8760
[0.3491261601448059, 0.8759999871253967]

根据结果可知,在第五次迭代时,loss值小于0.3,此时便终止了继续训练。通过对测试集进行评估,得到 loss=0.3491261601448059 , accuracy=0.8759999871253967
对测试集预测结果还是比较理想的。

总结

利用Fashion MNIST数据集进行深度学习模型的构建,内容上突出表现了神经网络所要解决问题的思路与想法。但这仅仅相当于我们使用Tensorflow 写出的“Hello World”。神经网络的构建,深度学习的思想非常丰富而又多样,如何利用Tensorflow 创建展示,是我们所要努力学习的方向。

  • 10
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

choosetobehappy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值