# encoding:utf-8 from __future__ import print_function import keras from keras.datasets import mnist from keras.models import Sequential from keras.layers import Dense, Dropout, Flatten from keras.layers import Conv2D, MaxPooling2D from keras import backend as K # batch_size 太小会导致训练慢,过拟合等问题,太大会导致欠拟合。所以要适当选择 batch_size = 128 # 0-9手写数字一个有10个类别 num_classes = 10 # 12次完整迭代,差不多够了 epochs = 2 # input image dimensions# 输入的图片是28*28像素的灰度图 img_rows, img_cols = 28, 28 # the data, shuffled and split between train and test sets (x_train, y_train), (x_test, y_test) = mnist.load_data() # keras输入数据有两种格式,一种是通道数放在前面,一种是通道数放在后面 # 在如何表示一组彩色图片的问题上,Theano和TensorFlow发生了分歧,'th'模式,也即Theano模式会把100张RGB三通道的16×32(高为16宽为32)彩色图表示为下面这种形式(100,3,16,32),Caffe采取的也是这种方式。 # 第0个维度是样本维,代表样本的数目,第1个维度是通道维,代表颜色通道数。后面两个就是高和宽了。这种theano风格的数据组织方法,称为“channels_first”,即通道维靠前。 # 而TensorFlow,的表达形式是(100,16,32,3),即把通道维放在了最后,这种数据组织方式称为“channels_last”。 # Keras默认的数据组织形式在~/.keras/keras.json中规定,可查看该文件的image_data_format一项查看,也可在代码中通过K.image_data_format()函数返回,请在网络的训练和测试中保持维度顺序一致。 if K.image_data_format() == 'channels_first': x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols) x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols) input_shape = (1, img_rows, img_cols) else: x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1) x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1) input_shape = (img_rows, img_cols, 1) x_train = x_train.astype('float32') x_test = x_test.astype('float32') x_train /= 255 x_test /= 255 print('x_train shape:', x_train.shape) print(x_train.shape[0], 'train samples') print(x_test.shape[0], 'test samples') # convert class vectors to binary class matrices # 把类别0-9变成2进制,方便训练 y_train = keras.utils.to_categorical(y_train, num_classes) y_test = keras.utils.to_categorical(y_test, num_classes) # 牛逼的Sequential类可以让我们灵活地插入不同的神经网络层 model = Sequential() # 加上一个2D卷积层, 32个输出(也就是卷积通道),激活函数选用relu, # 卷积核的窗口选用3*3像素窗口 model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=input_shape)) # 64个通道的卷积层 model.add(Conv2D(64, (3, 3), activation='relu')) # 池化层是2*2像素的 model.add(MaxPooling2D(pool_size=(2, 2))) # 对于池化层的输出,采用0.25概率的Dropout model.add(Dropout(0.25)) # 展平所有像素,比如[28*28] -> [784] model.add(Flatten()) # 对所有像素使用全连接层,输出为128,激活函数选用relu model.add(Dense(128, activation='relu')) model.add(Dropout(0.5)) # 对刚才Dropout的输出采用softmax激活函数,得到最后结果0-9 model.add(Dense(num_classes, activation='softmax')) # 模型我们使用交叉熵损失函数,最优化方法选用Adadelta model.compile(loss=keras.losses.categorical_crossentropy, optimizer=keras.optimizers.Adadelta(), metrics=['accuracy']) model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, verbose=1, validation_data=(x_test, y_test)) score = model.evaluate(x_test, y_test, verbose=0) print('Test loss:', score[0]) print('Test accuracy:', score[1])