说明:
1、2维卷积层,卷积核数量为32,大小为3×3,激活函数为ReLU(卷积核数量为16的倍数)
2维卷积层,卷积核数量为64,大小为3×3,激活函数为ReLU
2、池化层,pool_size取2×2
3、Flatten层把多维输入一维化
4、全连接层 Dense(128, activation='relu') ,神经元为128个
5、Dropout(0.5) 在训练过程中每次更新参数时随机断开一定百分比(rate)的输入神经元,防止过拟合
6、Adadelta优化器
这个算法就可以对低频的参数做较大的更新,对高频的做较小的更新,也因此,对于稀疏的数据它的表现很好,很好地提高了 SGD 的鲁棒性,例如识别 Youtube 视频里面的猫,训练 GloVe word embeddings,因为它们都是需要在低频的特征上有更大的更新。
梯度更新规则:
其中 g 为:t 时刻参数 θ_i 的梯度
如果是普通的 SGD, 那么 θ_i 在每一时刻的梯度更新公式为:
但这里的 learning rate η 也随 t 和 i 而变:
其中 G_t
是个对角矩阵, (i,i) 元素就是 t 时刻参数 θ_i
的梯度平方和。
Adagrad 的优点是减少了学习率的手动调节
超参数设定值:一般η选取0.01
缺点:
它的缺点是分母会不断积累,这样学习率就会收缩并最终会变得非常小。
卷积神经网络结构图
代码实现:
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 = 256
num_classes = 10
epochs = 2
# input image dimensions
img_rows, img_cols = 28, 28
# 国内好像不能直接导入数据集,我们试了几次都不行,后来将数据集下载到本地'~/.keras/datasets/',也就是当前目录(我的是用户文件夹下)下的.keras文件夹中。
#下载的地址为:https://s3.amazonaws.com/img-datasets/mnist.npz
(x_train, y_train), (x_test, y_test) = mnist.load_data()
#iamge_data_format选择"channels_last"或"channels_first",该选项指定了Keras将要使用的维度顺序。
#"channels_first"假定2D数据的维度顺序为(channels, rows, cols),3D数据的维度顺序为(channels, conv_dim1, conv_dim2, conv_dim3)
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)
#"channels_last"假定2D数据维度顺序为(rows,cols,channels),3D数据维度顺序为(conv_dim1, conv_dim2, conv_dim3, channels)
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')
#数据中每个像素值取值转换为0到1之间
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')
# 将标注的0-9数值转换为一个长度为10的one-hot 编码。注意从tensorflow.examples.tutorials.mnist导入的MNIST数据集标注已经是one-hot编码,
#所以从tutorials中导入MNIST数据集不需要下面两步。
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)
#下面开始搭建模型的架构,首先导入序贯模型(sequential),即多个网络层的线性堆叠
model = Sequential()
#第一层添加一个2维卷积层,卷积核大小为3×3,激活函数为ReLU,输入shape在‘channels_first’模式下为(samples,channels,rows,cols)
#在‘channels_last’模式下为(samples,rows,cols,channels)
model.add(Conv2D(32, kernel_size=(3, 3),
activation='relu',
input_shape=input_shape))
model.add(Conv2D(64, (3, 3), activation='relu'))
#为空域信号施加最大值池化,pool_size取(2,2)代表使图片在两个维度上均变为原长的一半
model.add(MaxPooling2D(pool_size=(2, 2)))
#Dropout将在训练过程中每次更新参数时按一定概率(rate)随机断开输入神经元,Dropout层用于防止过拟合。
model.add(Dropout(0.25))
#Flatten层把多维输入一维化,常用在从卷积层到全连接层的过渡。
model.add(Flatten())
#Dense层即全连接层
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))
#编译用来配置模型的学习过程,下面包括交叉熵损失函数、Adadelta优化器。指标列表metrics在分类问题一般设置为metrics=['accuracy']。
model.compile(loss=keras.losses.categorical_crossentropy,
optimizer=keras.optimizers.Adadelta(),
metrics=['accuracy'])
#fit函数指定模型训练的epoch数
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])
运行结果: