本文来自《Keras深度学习:入门、实战与进阶》第一章 第四小节 Keras构建深度学习。
将利用Keras自带的MNIST数据集来构建深度全连接深度学习模型,进行手写数字0~9的类别预测。 MNIST数据集共有训练数据60000项、测试数据10000项。MNIST数据集中的每一项数据都由image(数字图像)和label(真实的数字)所组成。Keras已经提供了现成的函数dataset_mnist(),可以帮助我们下载并读取数据。第一次执行dataset_mnist(),程序会检查用户目录下是否已经有MNIST数据集文件,如果还没有,就会自动下载文件。
我们将MNIST数据集读入到R语言中,分别查看这4个数据集的维度大小。
> # 读入MNIST数据集
> library(keras)
> c(c(x_train_image, y_train_label), c(x_test_image, y_test_label)) %<-% dataset_mnist()
> # 查看数据集维度
> cat('train_data=',dim(x_train_image))
train_data= 60000 28 28
> cat('test_data=',dim(x_test_image))
test_data= 10000 28 28
> cat('y_train_label:',dim(y_train_label))
y_train_label: 60000
> cat('y_test_label:',dim(y_test_label))
y_test_label: 10000
从以上执行结果可知,四个数据集大小分别为:
运行以下命令,绘制x_train_image数据集的前9张图片,标题用y_train_label对应的数字标签显示。
> # 显示MNIST数据的iamges和label
> par(mfrow=c(3,3))
> par(mar=c(0, 0, 1.5, 0), xaxs='i', yaxs='i')
> for(i in 1:9){
+ plot(as.raster(x_train_image[i,,],max = 255))
+ title(main = paste0('label=', y_train_label[i]))
+ }
> par(mfrow=c(1,1))
我们在建立深度神经网络模型(deep neural network)前,必须先将iamge和label的内容进行预处理,才能使用全连接神经网络模型进行训练于预测。数据预处理分为以下两部分:
> # image预处理
> # reshape
> x_Train <- array_reshape(x_train_image,dim = c(60000,784))
> x_Test <- array_reshape(x_test_image,dim = c(10000,784))
> # 标准化
> x_Train_normalize <- x_Train / 255
> x_Test_normalize <- x_Test / 255
> # 查看预处理后的训练数据维度
> dim(x_Train_normalize)
[1] 60000 784
> # 查看预处理后的数字范围
> range(x_Train_normalize)
[1] 0 1
label(数字图像真实的值)数据预处理> # label One-Hot Encoding
> y_train_label[1:5]
[1] 5 0 4 1 9
> y_TrainOneHot <- to_categorical(y_train_label)
> y_TestOneHot <- to_categorical(y_test_label)
> y_TrainOneHot[1:5,]
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 0 0 0 0 0 1 0 0 0 0
[2,] 1 0 0 0 0 0 0 0 0 0
[3,] 0 0 0 0 1 0 0 0 0 0
[4,] 0 1 0 0 0 0 0 0 0 0
[5,] 0 0 0 0 0 0 0 0 0 1
我们将建立序贯(Sequential)堆积的深度神经网络模型,后续只需要通过 %>% 将各个神经网络层加入模型即可。该模型网络结构如下:
> # 建立模型结构
> model <- keras_model_sequential() # 建立序贯模型
> model %>% layer_dense(units = 256,
+ input_shape = c(784),
+ kernel_initializer = 'normal',
+ activation = 'relu') # 添加隐藏层
> model %>% layer_dense(units = 10,
+ kernel_initializer = 'normal',
+ activation = 'softmax') # 添加输出层
> model %>% compile(loss = 'categorical_crossentropy',
+ optimizer = 'adam',
+ metrics = c('accuracy'))
> train_history <- model %>% fit(x=x_Train_normalize,
+ y=y_TrainOneHot,validation_split=0.2,
+ epochs=10, batch_size=200,verbose=2)
Train on 48000 samples, validate on 12000 samples
Epoch 1/10
- 6s - loss: 0.4386 - acc: 0.8822 - val_loss: 0.2159 - val_acc: 0.9407
Epoch 2/10
- 3s - loss: 0.1851 - acc: 0.9473 - val_loss: 0.1539 - val_acc: 0.9556
Epoch 3/10
- 2s - loss: 0.1289 - acc: 0.9635 - val_loss: 0.1216 - val_acc: 0.9645
Epoch 4/10
- 3s - loss: 0.0975 - acc: 0.9724 - val_loss: 0.1084 - val_acc: 0.9677
Epoch 5/10
- 2s - loss: 0.0774 - acc: 0.9782 - val_loss: 0.0944 - val_acc: 0.9713
Epoch 6/10
- 2s - loss: 0.0638 - acc: 0.9825 - val_loss: 0.0869 - val_acc: 0.9743
Epoch 7/10
- 2s - loss: 0.0512 - acc: 0.9862 - val_loss: 0.0896 - val_acc: 0.9721
Epoch 8/10
- 2s - loss: 0.0434 - acc: 0.9883 - val_loss: 0.0857 - val_acc: 0.9747
Epoch 9/10
- 3s - loss: 0.0362 - acc: 0.9905 - val_loss: 0.0833 - val_acc: 0.9748
Epoch 10/10
- 4s - loss: 0.0298 - acc: 0.9926 - val_loss: 0.0764 - val_acc: 0.9767
利用plot()函数绘制出10次训练周期的误差及准确率曲线
> plot(train_history)
接下来我们使用predict_classes()函数对测试数据集进行类别预测。
> # 模型预测
> prediction <- model %>%
+ predict_classes(x_Test_normalize)
> prediction[1:9]
[1] 7 2 1 0 4 1 4 9 6
通过可视化手段展示测试集前9张数字图像、实际和预测标签。
> par(mfrow=c(3,3))
> par(mar=c(0, 0, 1.5, 0), xaxs='i', yaxs='i')
> for(i in 1:9){
+ plot(as.raster(x_test_image[i,,],max = 255))
+ title(main = paste0('label=',y_test_label[i],'predict=',prediction[i]))
+ }
> par(mfrow=c(1,1)
作者公众号:我爱数据科学