前言
实现mnist手写数字识别
一、代码实现
import tensorflow as tf from tensorflow.keras.datasets import mnist import matplotlib as plt from tensorflow.keras import models from tensorflow.keras import layers (train_images,train_labels), (test_images, test_labels) = mnist.load_data() # train_images.shape: (60000,28,28) 6万张图像,每一张图像都是28*28的像素图片。 # 构建神经网络 network = models.Sequential() network.add(layers.Dense(512, activation='relu', input_shape=(28*28,))) # 几分类就写几,这里是10分类。 network.add(layers.Dense(10, activation='softmax')) # compile(编译):损失函数、优化器、在训练和测试过程中需要监控的指标 # metrics:指标列表,对于分类问题,我们一般将该列表设置为metrics=['accuracy'],均方误差回归损失用mse # 多分类损失用'categorical_crossentropy',二分类损失用'binary_crossentropy' network.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy']) # 数据处理:将其变换为网络要求的形状,并且进行归一化 train_images = train_images.reshape((60000, 28*28)) train_images = train_images.astype('float32')/255 test_images = test_images.reshape((10000, 28*28)) test_images = test_images.astype('float32')/255 from tensorflow.keras.utils import to_categorical # to_categorical:将类别向量转换为二进制(只有0和1)的矩阵类型表示。即将原有的类别向量转换为独热编码的形式。 train_labels = to_categorical(train_labels) test_labels = to_categorical(test_labels) # 开始训练 network.fit(train_images, train_labels, epochs=20, batch_size=128) # 评估 test_loss, test_acc = network.evaluate(test_images, test_labels) print(test_loss, test_acc)
二、一些注意问题
2-1、网络构建方式
可以是(通过构建器创建):
network = models.Sequential() network.add(layers.Dense(512, activation='relu', input_shape=(28*28,))) network.add(layers.Dense(10, activation='softmax'))
也可以是(通过add方法构建):
network = models.Sequential([ layers.Dense(512, activation='relu', input_shape=(28*28,)), layers.Dense(10, activation='softmax'), ])
2-2、确定模型输入数据的规格
第一层需要通过参数传递告知模型数据规格,后边的层不需要,因为可以自动的根据第一层的输出进行推导。
通过input_shape参数:
network.add(layers.Dense(512, activation='relu', input_shape=(28*28,)))
也可以通过input_dim参数设定,和上边的含义类似:
network.add(layers.Dense(512, activation='relu', input_dim=28*28))
注意:input_shape=(28✖28,)代表的是输入的数据是28✖28维的一阶向量。input_shape的格式是元组,所以必须写为(28*28,)这种形式。
2-3、全连接层内部的张量运算
例子:
keras.layers.Dense(512, activation='relu')
注解:输入一个2D张量,返回另一个2D张量。函数如下所示
公式表示:output = relu(dot(w, input) + b)
即:输入张量和张量w(给定形状的随机张量)之间的点积运算(dot),得到的2D张量与向量b之间的加法运算,最后经过relu激活函数(即max(x,0)),relu运算和加法运算都是逐元素运算。w和b被称之为权重和可训练参数,一开始这些权重矩阵取较小的随机值,这一步叫做随机初始化。下一步是根据反馈信号逐渐调节这些权重。这个逐渐调节的过程叫做训练。
2-4、训练的具体步骤。
1、抽取训练样本x和对应目标y组成的数据批量
2、在x上运行网络(这一步叫做前向传播),得到预测值y_pred。(张量运算)
3、计算网络在这批数据上的损失,衡量y_pred和y之间的距离。
4、更新网络的权重,使得网络在这批数据上的损失略微下降。
注意:训练的过程就是重复上述步骤,最终使得预测值y_pred和预期目标y之间的距离非常小。
2-5、有关于点积的一些理解
keras.layers.Dense(512, activation='relu')
注意:两个向量之间的点积是一个标量,而且只有元素个数相同的向量之间才能做点积, 逐元素相乘然后相加。
import numpy as np np.dot([1, 2],[3,4]) # 输出 # 11
一般:两个矩阵之间的点积,对于两个矩阵x和y,当且仅当x.shape[1] == y.shape[0] 时,你才可以对它们做点积,得到的结果是一个形状为(x.shape[0], y.shape[1])的矩阵,即x的行与y的列相乘后的和相加。
np.dot([[1, 2],[1,2]], [[3, 4],[3,4]]) # 输出 # array([[ 9, 12], # [ 9, 12]])
参考文章:
总结
有些事情努力了就好啦,虽然结果惨不忍睹。。。😔