前言
MNIST 数字识别问题的全连接实现和LeNet-5实现。Keras是目前最为广泛的深度学习工具之一,底层可以支持Tensorflow、MXNet、CNTK、Theano。通过Keras我们深度学习过程基本可以简化为:数据处理、模型定义、模型训练。
tensorflow版本: 1.13.1
Keras版本:2.2.4
运行环境:Google CoLab(推荐大家去用下 )
全连接实现
样例来自于Tensorflow官方。
导入需要的包
from __future__ import absolute_import, division, print_function, unicode_literals
import tensorflow as tf
数据处理
加载MNIST数据集,其中每张图片是28*28,每个点位的值是0-255.
将样本的数据从整型转换为浮点数
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# print(x_train[0]) 载入的是 0-255 的 28*28的图片
x_train, x_test = x_train / 255.0, x_test / 255.0
# print(x_train[0]) 的值为 0-1 加速后期优化
Downloading data from https://s3.amazonaws.com/img-datasets/mnist.npz
11493376/11490434 [==============================] - 135s 12us/step
模型定义
建立Keras模型,通过一层一层的叠加
model = tf.keras.models.Sequential([
# Flatten 变成784 的输入
tf.keras.layers.Flatten(input_shape=(28, 28)),
# 512的全连接层
tf.keras.layers.Dense(512, activation=tf.nn.relu),
# droput 0.2 这个 以后再做讨论 主要是用来防止过拟合
tf.keras.layers.Dropout(0.2),
# 全连接层 10
tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
选择优化方法,以及损失函数类型。
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
模型训练
训练与评价模型。
model.fit(x_train, y_train, epochs=5)
model.evaluate(x_test, y_test)
Epoch 1/5
60000/60000 [==============================] - 33s 554us/step - loss: 0.2194 - acc: 0.9359
Epoch 2/5
60000/60000 [==============================] - 29s 484us/step - loss: 0.0967 - acc: 0.9698
Epoch 3/5
60000/60000 [==============================] - 30s 506us/step - loss: 0.0685 - acc: 0.97820s - loss: 0.0686 - acc: 0
Epoch 4/5
60000/60000 [==============================] - 31s 519us/step - loss: 0.0536 - acc: 0.9828
Epoch 5/5
60000/60000 [==============================] - 37s 610us/step - loss: 0.0420 - acc: 0.98635s
10000/10000 [==============================] - 1s 131us/step
最终测试集结果
[0.06397853024117649, 0.982]
MNIST数据集的LeNet-5实现
同理还是三步骤:数据处理、模型定义、模型训练
import keras
from keras.datasets import mnist
from keras.models import Sequential
# 各个层有不同的作用 依次为 全连接层 Flatten层 卷积层 池化层
from keras.layers import Dense,Flatten,Conv2D,MaxPooling2D
from keras import backend as K
基础向量定义
num_classes = 10
img_rows,img_cols = 28, 28
数据处理
载入数据
(trainX, trainY),(testX,testY) = mnist.load_data()
由于底层(Tensorflow或MXNet)对输入的要求不一样,所以这里需要根据对图像编码格式来设置输入层
if K.image_data_format() == 'channals_first':
trainX = trainX.reshape(trainX.shape[0],1,img_rows,img_cols)
testX = testX.reshape(testX.shape[0],1,img_rows,img_cols)
input_shape = (1,img_rows, img_cols)
else:
trainX = trainX.reshape(trainX.shape[0],img_rows,img_cols,1)
testX = testX.reshape(testX.shape[0],img_rows,img_cols,1)
input_shape = (img_rows, img_cols,1)
# 将图像像素从0-255转换为0-1之间实数
trainX = trainX.astype('float32')
testX = testX.astype('float32')
trainX = trainX / 255.0
testX = testX / 255.0
# 将标准答案 转为 one-hot向量。例如数字1 就是 [0,1,0,0,0,0,0,0,0,0]
trainY = keras.utils.to_categorical(trainY, num_classes)
testY = keras.utils.to_categorical(testY, num_classes)
训练模型就是先定义一个Sequential类,然后再Sequential实例中通过add函数添加网络层。就跟搭积木一样一层一层的添加。不同的层有不同的参数
model = Sequential()
# 卷积层 主要参数 卷积核个数,卷积核大小,激活函数,步长,输入shape=[28,28,1] 默认不padding 默认步长为1
model.add(Conv2D(32,kernel_size=(5,5),activation='relu',input_shape=input_shape))
# 卷积后 尺寸为 (24,24,32)(28-5+1)/1 = 24 加快计算 防止过拟合
# 最大池化层 参数 池化操作的大小
model.add(MaxPooling2D(pool_size=(2,2)))
# 池化后 (12,12,32)
# 继续卷积
model.add(Conv2D(64,kernel_size=(5,5),activation='relu'))
# 卷积后 (8,8,64)
# 继续池化
model.add(MaxPooling2D(pool_size=(2,2)))
# 池化后 尺寸为 (4,4,64)
# Flatten层用来将输入“压平”,即把多维的输入一维化,常用在从卷积层到全连接层的过渡。Flatten不影响batch的大小。
model.add(Flatten())
# Flatten之后 为 4*4*16 256
# 全连接层 结点个数:500 激活函数:relu
model.add(Dense(500,activation='relu'))
# 全连接层 也是 输出层 10个结点
model.add(Dense(num_classes,activation='softmax'))
将搭建好的“积木”或者说是小火车,Sequential是火车头,后面逐层add是一节节车厢。
通过Sequential的compile函数,指定优化函数、损失函数、以及训练中的监控指标等定义好“火车头”。
model.compile(loss=keras.losses.categorical_crossentropy,# 分类的交叉熵损失
optimizer=keras.optimizers.SGD(),# 随机梯度下降
metrics=['accuracy']) # 监控指标是 准确率
通过fit函数来训练模型,主要参数为:训练数据,batch大小和训练轮数。
model.fit(trainX,trainY,batch_size=128,
epochs=20,
validation_data=(testX,testY))
Train on 60000 samples, validate on 10000 samples
Epoch 1/20
60000/60000 [==============================] - 2s 41us/step - loss: 0.0638 - acc: 0.9809 - val_loss: 0.0554 - val_acc: 0.9834
.......省略中间的轮数
Epoch 20/20
60000/60000 [==============================] - 3s 44us/step - loss: 0.0291 - acc: 0.9915 - val_loss: 0.0338 - val_acc: 0.9886
对模型进行评价,输出loss 和评价方式 准确率的值。
score = model.evaluate(testX,testY)
print('Test loss:',score[0])
print('test accuracy',score[1])
10000/10000 [==============================] - 0s 49us/step
Test loss: 0.03384795787587063
test accuracy 0.9886
网友评论