在下面的Python代码中,引入了一个类,该类有一个用于网络实例化的静态方法。
from keras.models import Sequential
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras.layers.core import Activation, BatchNormalization, Dropout, Flatten, Dense
class ClassLeNet:
@staticmethod
def create(width, height, kernels, hidden, classes):
net = Sequential()
net.add(Conv2D(kernels, (5, 5), padding='same', input_shape=(height, width, 1)))
net.add(Activation('relu'))
net.add(BatchNormalization())
net.add(Conv2D(kernels, (5, 5), padding='same'))
net.add(Activation('relu'))
net.add(BatchNormalization())
net.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
net.add(Conv2D(kernels, (3, 3), padding='same'))
net.add(Activation('relu'))
net.add(BatchNormalization())
net.add(Conv2D(kernels, (3, 3), padding='same'))
net.add(Activation('relu'))
net.add(BatchNormalization())
net.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
net.add(Flatten())
net.add(Dense(hidden))
net.add(Activation('relu'))
net.add(Dropout(0.5))
net.add(Dense(hidden))
net.add(Activation('relu'))
net.add(Dense(classes))
net.add(Activation('softmax'))
return net
上述代码导入了所需的Python包和类。关于类名的一些备注:
在类中定义的create方法有五个参数:
由于网络是一个前馈CNN,实例化了Sequential模型类。
使用多个add方法调用来按所需顺序堆叠层。所有Conv2D卷积层的构造函数都提供以下参数:
第一个卷积层创建时有一个额外的参数input_shape,它指定了输入图像的维度。
激活层使用ReLU激活函数,由relu参数值指定。最后一个激活层是个例外:它使用SOFTMAX函数来提供每个类别(年龄组)的概率输出。
池化层初始化有两个参数:
在堆栈的最后部分有三个全连接(Dense)层。两个隐藏层的实例化神经元数量等于hidden参数值。最后一个输出层的神经元数量等于类别数。
在两个全连接层之间有一个dropout层,概率为0.5。注意卷积和全连接部分之间的Flatten层。这是必要的,因为卷积输出有三个维度(宽度、高度和核的数量),而全连接输入是一维的。因此,卷积数据必须转换为1D数组,然后才能用作密集层的输入。
有了构建CNN模型的类实现后,可以如下实例化模型:
from keras.optimizers import SGD
kernels = 16
hidden = 256
imgsize = 128
classes = 10
net = ClassLeNet.create(imgsize, imgsize, kernels, hidden, classes)
opt = SGD(lr=0.01)
net.compile(loss='categorical_crossentropy', optimizer=opt, metrics=['accuracy'])
首先,为模型参数分配值:
然后调用create方法来实例化网络模型,使用上述参数值。此外,还需要选择用于训练模型的优化方法。随机梯度下降(SGD)优化器实例化,学习率值lr=0.01。
最后,模型使用上述优化器编译,使用准确度作为度量,以及交叉熵作为损失函数(分类问题的常见选择)。