本节课目标:分享神经网络的搭建八股,用“六步法”, 不到20行代码,写出手写数字识别训练模型。
使用TensorflowAPI:tf.keras搭建网络八股。tf.keras是tensorflow2引入的高封装度的框架,可以用于快速搭建神经网络模型,keras为支持快速实验而生,能够把想法迅速转换为结果,是深度学习框架之中最终易上手的一个,它提供了一致而简洁的API,能够极大地减少一般应用下的工作量,提高代码地封装程度和复用性。目录
- 3.1 搭建网络八股Sequential
- 3.1.1 model=tf.keras.models.Sequential([网络结构]):
- 3.1.2 model.compile(optimizer = 优化器, loss = 损失函数, metrics = [“准确率”] ):
- 3.1.3 model.fit():
- 3.1.4model.summary():
- 3.2 搭建网络八股Class
- 3.3 MNIST数据集
- 3.3.1 MNIST介绍
- 3.3.2 导入MNIST数据集
- 3.3.3 训练MNIST数据集
- 3.4 Fashion_mnist数据集
第一步:import相关模块,如import tensorflow as tf。
第二步:指定输入网络的训练集和测试集,如指定训练集的输入x_train和标签y_train,测试集的输入x_test和标签y_test。
第三步:逐层搭建网络结构,model = tf.keras.models.Sequential()。
第四步:在model.compile()中配置训练方法,选择训练时使用的优化器、损失函数和最终评价指标。
第五步:在model.fit()中执行训练过程,告知训练集和测试集的输入值和标签、每个batch的大小(batchsize)和数据集的迭代次数(epoch)。
第六步:使用model.summary()打印网络结构,统计参数数目。
Sequential函数是一个容器,描述了神经网络的网络结构,在Sequential函数的输入参数中描述从输入层到输出层的网络结构。
Compile用于配置神经网络的训练方法,告知训练时使用的优化器、损失函数和准确率评测标准。
summary函数用于打印网络结构和参数统计。
上图是model.summary()对鸢尾花分类网络的网络结构和参数统计,对于一个输入为4输出为3的全连接网络,共有15个参数。
接下来看一下使用着六步法,怎么实现鸢尾花分类:
# 一
import tensorflow as tf
from sklearn import datasets
import numpy as np
# 二
x_train = datasets.load_iris().data
y_train = datasets.load_iris().target
np.random.seed(116)
np.random.shuffle(x_train)
np.random.seed(116)
np.random.shuffle(y_train)
tf.random.set_seed(116)
# 三
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(3, activation='softmax', kernel_regularizer=tf.keras.regularizers.l2())
])
# 四
model.compile(optimizer=tf.keras.optimizers.SGD(lr=0.1),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=['sparse_categorical_accuracy'])
# 五
model.fit(x_train, y_train, batch_size=32, epochs=500, validation_split=0.2, validation_freq=20)
# 六
model.summary()
使用Sequential可以快速搭建网络结构,但是如果网络包含跳连等其他复杂网络结构,Sequential就无法表示了。这就需要使用class来声明网络结构。
下面左边是一个模板,右边是鸢尾花分类的例子。
MyModel表示声明的神经网络的名字,括号中的Model表示创建的类需要继承tensorflow库中的Model类。类中需要定义两个函数,init()函数为类的构造函数用于初始化类的参数,spuer(MyModel,self).init()这行表示初始化父类的参数。之后便可初始化网络结构,搭建出神经网络所需的各种网络结构块。call()函数中调用__init__()函数中完成初始化的网络块,实现前向传播并返回推理值。
# 一
import tensorflow as tf
from tensorflow.keras.layers import Dense
from tensorflow.keras import Model
from sklearn import datasets
import numpy as np
# 二
x_train = datasets.load_iris().data
y_train = datasets.load_iris().target
np.random.seed(116)
np.random.shuffle(x_train)
np.random.seed(116)
np.random.shuffle(y_train)
tf.random.set_seed(116)
# 三
class IrisModel(Model):
def __init__(self):
super(IrisModel, self).__init__()
self.d1 = Dense(3, activation='softmax', kernel_regularizer=tf.keras.regularizers.l2())
def call(self, x):
y = self.d1(x)
return y
model = IrisModel()
# 四
model.compile(optimizer=tf.keras.optimizers.SGD(lr=0.1),
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
metrics=['sparse_categorical_accuracy'])
# 五
model.fit(x_train, y_train, batch_size=32, epochs=500, validation_split=0.2, validation_freq=20)
#六
model.summary()
MNIST数据集一共有7万张图片,是28×28像素的0到9手写数字数据集,其中6万张用于训练,1万张用于测试。每张图片包括784(28×28)个像素点,使用全连接网络时可将784个像素点组成长度为784的一维数组,作为输入特征。数据集图片如下所示。
keras函数库中提供了使用mnist数据集的接口,代码如下所示,可以使用load_data()直接从mnist中读取测试集和训练集。
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
输入全连接网络时需要先将数据拉直为一维数组,把784个像素点的灰度值作为输入特征输入神经网络。
tf.keras.layers.Flatten()
使用plt库中的两个函数可视化训练集中的图片。
plt.imshow(x_train[0],cmap=’gray’)
plt.show()
使用print打印出训练集中第一个样本以二位数组的形式打印出来,如下所示。
print(“x_train[0]:”,x_train[0])
使用Sequential实现手写数字识别:
import tensorflow as tf
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0 # 归一化,0-1之间
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()
使用class实现手写数字识别:
import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras import Model
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0 # 归一化,0-1之间
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()
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()
值得注意的是训练时需要将输入特征的灰度值归一化到[0,1]区间,这可以使网络更快收敛。
Fashion_mnist数据集具有mnist近乎所有的特征,包括60000张训练图片和10000张测试图片,图片被分为十类,每张图像为28×28的分辨率。
类别如下所示:
由于Fashion_mnist数据集和mnist数据集具有相似的属性,所以对于mnist只需将mnist数据集的加载换成Fashion_mnist就可以训练Fashion数据集了。代码如下所示:
import tensorflow as tf
fashion = tf.keras.datasets.fashion_mnist
(x_train, y_train),(x_test, y_test) = fashion.load_data()
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()