目的:实现mnist分类
1.加载mnist图片数据
(train_x, train_y), (test_x, test_y) = mnist.load_data()
2.修改数据类型,数据归一化
# 将数据转化为浮点型
x_train = train_x.astype('float32')
y_train = train_y.astype('float32')
x_test = test_x.astype('float32')
y_test = test_y.astype('float32')
#数据归一化
x_train /= 255
x_test /= 255
# 标签进行one_hont编码
y_train = keras.utils.to_categorical(y_train, num_classes=10)
y_test = keras.utils.to_categorical(y_test, num_classes=10)
- 修改数据形状
x_train = x_train.reshape(60000, 28, 28, 1)
x_test = x_test.reshape(10000, 28, 28, 1)
4.搭建学习网络
model = Sequential([
Conv2D(filters=6, kernel_size=(5, 5), padding='valid', activation='tanh', input_shape=(28, 28, 1)),
MaxPooling2D(pool_size=(2, 2)),
Conv2D(filters=16, kernel_size=(5, 5), padding='valid', activation='tanh'),
MaxPooling2D(pool_size=(2, 2)),
Flatten(),
Dense(120, activation='tanh'),
Dense(84, activation='tanh'),
Dense(10, activation='softmax')
])
5.配置学习网络
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])
6.开始训练
model.fit(x_train, y_train, batch_size=64, epochs=20, verbose=1, validation_split=0.2, shuffle=True)
7.评价网络
score = model.evaluate(x_test, y_test, batch_size=64)
print(score)
遇到问题:
1.
ValueError: Negative dimension size caused by subtracting 5 from 1 for 'conv2d_1/convolution' (op: 'Conv2D') with input shapes: [?,1,28,28], [5,5,28,6].
这是因为本来案例用的是Theano作为keras的后台,Theano的格式是(1,28,28)的格式,如果是TensorFlow需要修改输入格式为(28,28,1)
2.
Error when checking input: expected conv2d_1_input to have 4 dimensions, but got array with shape (60000, 28, 28)
直接导入的mnist数据为(60000,28,28),而这你的cnn网络需要的是(60000,28,28,1),所以需要修改矩阵形状为(60000,28,28,1)
x_train = x_train.reshape(60000, 28, 28,1)
x_test = x_test.reshape(10000, 28, 28,1)
完整代码
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Flatten
from keras.layers import Conv2D, MaxPooling2D
if __name__ == "__main__":
(train_x, train_y), (test_x, test_y) = mnist.load_data()
x_train = train_x.astype('float32')
y_train = train_y.astype('float32')
x_test = test_x.astype('float32')
y_test = test_y.astype('float32')
x_train /= 255
x_test /= 255
y_train = keras.utils.to_categorical(y_train, num_classes=10)
y_test = keras.utils.to_categorical(y_test, num_classes=10)
x_train = x_train.reshape(60000, 28, 28, 1)
x_test = x_test.reshape(10000, 28, 28, 1)
model = Sequential([
Conv2D(filters=6, kernel_size=(5, 5), padding='valid', activation='relu', input_shape=(28, 28, 1)),
MaxPooling2D(pool_size=(2, 2)),
Conv2D(filters=16, kernel_size=(5, 5), padding='valid', activation='relu'),
MaxPooling2D(pool_size=(2, 2)),
Flatten(),
Dense(120, activation='relu'),
Dense(84, activation='relu'),
Dense(10, activation='softmax')
])
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])
model.fit(x_train, y_train, batch_size=64, epochs=20, verbose=1, validation_split=0.2, shuffle=True)
score = model.evaluate(x_test, y_test, batch_size=64)
print(score)
model.save('lenet5.h5')