第三章–八股搭建神经网络
本讲目标:
用八股的方式写mnist数据集手写数字识别。参考视频。
提供6万张 28*28 像素点的0~9手写数字图片和标签,用于训练。
提供1 万张 28*28 像素点的0~9手写数字图片和标签,用于测试。
mnist=tf.keras.datasets.mnist
(x_train,y_train),(x_test,y_test)=mnist.load_data()
print(x_train.shape)
print(y_train.shape)
print(x_test.shape)
print(y_test.shape)
输出结果如下
(60000, 28, 28)
(60000,)
(10000, 28, 28)
(10000,)
如果这里下载数据集失败,可以点击这个链接下载,将下载好的文件放在C:\Users\[UserName]\.keras\datasets
文件夹下即可。
plt.imshow(x_train[0],cmap='gray')
print("x_train[0]:\n",x_train[0])
print("y_train[0]:\n",y_train[0])
可以得到如下输出,分别是图片5,图片的像素,以及图片的标签。
y_train[0]:
5
import tensorflow as tf
from tensorflow.keras.layers import Dense,Flatten
from tensorflow.keras import Model
from tensorflow.keras.datasets import mnist
import matplotlib.pyplot as plt
(x_train,y_train),(x_test,y_test)=mnist.load_data()
print(x_train.shape)
print(y_train.shape)
print(x_test.shape)
print(y_test.shape)
x_train,x_test=x_train/255.0,x_test/255.0
下面使用函数Sequential搭建的一层神经网络,首先用Flatten函数将图像展开成一维,再添加一个中间128个结点的中间层,最后输出层是10个结点对应数字0-9。
model=tf.keras.models.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128,activation='relu'),
tf.keras.layers.Dense(10,activation='softmax')
])
设置优化器为adam;
设置损失为交叉熵损失,其参数from_logits
的方式要参考上一步的输出,上一步的输出是softmax
概率分布式的,并不是原始数据,所以这里的from_logits
设置为False
;
设置输出方式metrics为sparse_categorical_accuracy,即输出值和预测值都是独热编码形式的。
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=['sparse_categorical_accuracy']
)
设置输入训练数据集为x_train
,y_trian
,测试数据集为x_test
,y_test
;
设置最小批次数据量batch_size
为32;
设置迭代轮数epochs
为5;
设置测试频率为一个epochs
一次,即validation_freq
=1;
model.fit(x_train,y_train,batch_size=32,epochs=5,validation_data=(x_test,y_test),validation_freq=1)
model.summary()
输出结果如下:
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
flatten (Flatten) (None, 784) 0
_________________________________________________________________
dense (Dense) (None, 128) 100480
_________________________________________________________________
dense_1 (Dense) (None, 10) 1290
=================================================================
Total params: 101,770
Trainable params: 101,770
Non-trainable params: 0
_________________________________________________________________
第一个Dense层的参数量为100480=(28x28)x128+128
第二个Dense层的参数量为1290=128x10+10
import tensorflow as tf
from tensorflow.keras.layers import Dense,Flatten
from tensorflow.keras import Model
from tensorflow.keras.datasets import mnist
import matplotlib.pyplot as plt
(x_train,y_train),(x_test,y_test)=mnist.load_data()
print(x_train.shape)
print(y_train.shape)
print(x_test.shape)
print(y_test.shape)
x_train,x_test=x_train/255.0,x_test/255.0
model=tf.keras.models.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128,activation='relu'),
tf.keras.layers.Dense(10,activation='softmax')
])
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=['sparse_categorical_accuracy']
)
model.fit(x_train,y_train,batch_size=32,epochs=5,validation_data=(x_test,y_test),validation_freq=1)
model.summary()
输出结果如下:
Epoch 1/5
1875/1875 [==============================] - 3s 2ms/step - loss: 0.2544 - sparse_categorical_accuracy: 0.9276 - val_loss: 0.1281 - val_sparse_categorical_accuracy: 0.9626
Epoch 2/5
1875/1875 [==============================] - 3s 1ms/step - loss: 0.1122 - sparse_categorical_accuracy: 0.9664 - val_loss: 0.0991 - val_sparse_categorical_accuracy: 0.9709
Epoch 3/5
1875/1875 [==============================] - 3s 2ms/step - loss: 0.0786 - sparse_categorical_accuracy: 0.9753 - val_loss: 0.0882 - val_sparse_categorical_accuracy: 0.9743
Epoch 4/5
1875/1875 [==============================] - 3s 2ms/step - loss: 0.0583 - sparse_categorical_accuracy: 0.9822 - val_loss: 0.0738 - val_sparse_categorical_accuracy: 0.9763
Epoch 5/5
1875/1875 [==============================] - 3s 2ms/step - loss: 0.0464 - sparse_categorical_accuracy: 0.9858 - val_loss: 0.0788 - val_sparse_categorical_accuracy: 0.9756
功能式API用class搭建神经网络,可以更加灵活的搭建非线性网络,其处理流程仅在第三步有所不同,将上述第三步改为如下:
class MnistModel(Model):
def __init__(self):
super(MnistModel,self).__init__()
self.flatten=Flatten()
self.d1=Dense(128,activation='relu')
self.d2=Dense(10,activation='softmax')
def call(self,x):
x=self.flatten(x)
x=self.d1(x)
y=self.d2(x)
return y
model=MnistModel()
运行程序,可以得到相同的输出结果和识别准确率。