MNIST数据集信息参考:http://yann.lecun.com/exdb/mnist/index.html
Most examples are using MNIST dataset of handwritten digits. The dataset contains 60,000 examples for training and 10,000 examples for testing. The digits have been size-normalized and centered in a fixed-size image (28x28 pixels) with values from 0 to 1. For simplicity, each image has been flatten and converted to a 1-D numpy array of 784 features (28*28).

问题:keras.datasets.mnist.load_data()失败,原因是外网上不了。
keras.datasets下载数据集时,由于文件是存储在亚马逊的服务器上;
由log错误信息可以知道,是无法链接到亚马逊的网址导致无法下载数据
解决方案翻墙复制URL直接手动下载,放在同一目录下;
看load_data()内部源码发现其实就是调用numpy.load()函数;
numpy.load() 函数起到很重要的作用。它可以读取 .npy .npz 等文件类型,并返回对应的数据类型。
- 如果文件类型是 .pny 则返回一个1维数组。
- 如果文件类型是 .npz 则返回一个类似字典的数据类型,包含 {filename: array} 键值对。如,本例中的键值对如下所示:
链接:https://pan.baidu.com/s/1f0TGHlfiskUuZoK4mglCjg 密码:vwxm
1. DNN
#coding=utf-8
import numpy as np
from keras.utils import np_utils, plot_model
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.optimizers import SGD, Adam #导入不同优化器
from keras.regularizers import l2
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
# 内置load_data()多次加载数据都是失败,于是下载数据后自定义方法
def load_data(path="mnist.npz"):
f = np.load(path)
x_train, y_train = f['x_train'], f['y_train']
x_test, y_test = f['x_test'], f['y_test']
f.close()
return (x_train, y_train), (x_test, y_test)
#载入数据
(x_train,y_train), (x_test,y_test) = load_data()
print('x_shape:', x_train.shape) #x_shape: (60000, 28, 28)
print('y_shape:', y_train.shape) #y_shape: (60000,)
x_train = x_train.reshape(x_train.shape[0], -1)/255.0 #重新定义数据格式 60000,784及归一化
x_test = x_test.reshape(x_test.shape[0], -1)/255.0
#转one-hot标签
y_train = np_utils.to_categorical(y_train, num_classes=10)
y_test = np_utils.to_categorical(y_test, num_classes=10)
#创建模型,输入784个神经元,输出10个神经元
model = Sequential()
# model.add(Dense(units=256, input_dim=784, use_bias='one', activation='relu', kernel_regularizer=l2(0.01)))
model.add(Dense(units=256, input_dim=784, use_bias='one', activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(units=128, input_dim=256, activation='tanh'))
model.add(Dropout(0.5))
model.add(Dense(units=10, input_dim=128, activation='softmax'))
#定义优化器
adam = Adam(lr=0.001)
sgd = SGD(lr=0.2)
model.summary() #print
model.compile(optimizer=sgd, loss='mse', metrics=['accuracy']) #定义loss func mse
# model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=['accuracy']) #定义loss func categorical_crossentropy
# model.compile(optimizer=adam, loss='mse', metrics=['accuracy'])
#训练模型
model.fit(x_train, y_train, batch_size=64, epochs=10)
#评估模型
loss,accuracy=model.evaluate(x_test, y_test)
print('loss:', loss)
print('accuracy:', accuracy)
plot_model(model, to_file='mnist_dnn.png', show_shapes=True)
lena = mpimg.imread('mnist_dnn.png') # 读取和代码处于同一目录下的mnist_dnn.png
#此时 lena 就已经是一个 np.array 了,可以对它进行任意处理
lena.shape #(512, 512, 3)
plt.imshow(lena) # 显示图片
plt.axis('off') # 不显示坐标轴
plt.show()
config = model.get_config()
model = model.from_config(config)
运行结果如下:

2. RNN
#coding=utf-8
import numpy as np
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense
from keras.layers.recurrent import SimpleRNN
from keras.optimizers import Adam
input_size = 28 # 数据长度-一行有28个像素
time_steps = 28 # 序列长度-一共有28行
cell_size = 256 # 隐藏层cell个数
# 内置load_data()多次加载数据都是失败,于是下载数据后自定义方法
def load_data(path="mnist.npz"):
f = np.load(path)
x_train, y_train = f['x_train'], f['y_train']
x_test, y_test = f['x_test'], f['y_test']
f.close()
return (x_train, y_train), (x_test, y_test)
(x_train,y_train), (x_test,y_test) = load_data() #载入数据
x_train = x_train/255.0 # (60000,28,28)
x_test = x_test/255.0
# 换one hot格式
y_train = np_utils.to_categorical(y_train, num_classes=10)
y_test = np_utils.to_categorical(y_test, num_classes=10) #one hot
model = Sequential() # 创建模型
# 循环神经网络
model.add(SimpleRNN(units=cell_size, input_shape=(time_steps, input_size)))
# 输出层
model.add(Dense(128, activation='tanh'))
model.add(Dense(10, activation='softmax'))
# 定义优化器
adam = Adam(lr=1e-4)
# 定义优化器,loss function,训练过程中计算准确率
model.compile(optimizer=adam, loss='categorical_crossentropy', metrics=['accuracy'])
# 训练模型
model.fit(x_train, y_train, batch_size=64, epochs=10)
# 评估模型
loss, accuracy = model.evaluate(x_test,y_test)
print('test loss',loss)
print('test accuracy',accuracy)
运行结果:

3. CNN
#coding:utf-8
import numpy as np
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense, Dropout, Convolution2D, MaxPooling2D, Flatten
from keras.optimizers import Adam
def load_data(path="mnist.npz"):
f = np.load(path)
x_train, y_train = f['x_train'], f['y_train']
x_test, y_test = f['x_test'], f['y_test']
f.close()
return (x_train, y_train), (x_test, y_test)
(x_train,y_train), (x_test,y_test) = load_data()
x_train = x_train.reshape(-1,28,28,1)/255.0
x_test = x_test.reshape(-1,28,28,1)/255.0
y_train = np_utils.to_categorical(y_train, num_classes=10)
y_test = np_utils.to_categorical(y_test, num_classes=10)
model = Sequential()
# 第一个卷积层
# input_shape 输入平面
# filters 卷积核/滤波器个数
# kernel_size 卷积窗口大小
# strides 步长
# padding padding方式 same/valid
# activation 激活函数
model.add(Convolution2D(input_shape=(28,28,1), filters=32, kernel_size=5, strides=1, padding='same', activation='relu'))
model.add(MaxPooling2D(pool_size=2, strides=2, padding='same'))
model.add(Convolution2D(64, 5, strides=1, padding='same', activation='relu'))
model.add(MaxPooling2D(2, 2, 'same'))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))
adam = Adam(lr=1e-4)
model.compile(optimizer=adam, loss='categorical_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=128, epochs=10)
loss,accuracy = model.evaluate(x_test, y_test)
print('test loss', loss)
print('test accuracy', accuracy)
运行结果:

优化改进方向:
- 优化器;
- 损失函数;
- dropout;
- 正则化项;
- ImageDataGenerator;
- 修改网络结构;