layer { name: "mnist" type: "Data" top: "data" top: "label" include { phase: TRAIN } transform_param { scale: 0.00390625 } data_param { source: "examples/mnist/mnist_train_lmdb" batch_size: 64 backend: LMDB }}
上面是输入数据层,
layer { name: "conv1" type: "Convolution" param { lr_mult: 1 } param { lr_mult: 2 } convolution_param { num_output: 20 kernel_size: 5 stride: 1 weight_filler { type: "xavier" } bias_filler { type: "constant" } } bottom: "data" top: "conv1"
这一层带了data blob 由数据层提供,并且产生一个conv1 layer,输出了20 channels, 卷积核为5,步长为1,
fillers允许我们随机的初始化weights 和bias, weights filler 我们使用的是xavier 算法 ,这个算法能够自动的决定初始化的规模基于输出和输出神经元的数目。 对于bias filler,我们初始化为 一个常量,默认值为0
lr_mult 是学习率的调整。在这个例子中,我们设置weight learning rate 和 solver during runtime 给出的学习率一样,bias learning rate 是它的两倍。 这种方式能够导致更好的(convergence )收敛速度。
//Pooling Layer layer { name: "pool1" type: "Pooling" pooling_param { kernel_size: 2 stride: 2 pool: MAX } bottom: "conv1" top: "pool1"}
Pooling layer 相对容易定义,这一层将会max pooling 通过卷积核为2,步长为2,(没有重叠)
同样的,你可以写下第二个卷积layer 和 pooling layer。
//Fully Connected Layerlayer { name: "ip1" type: "InnerProduct" param { lr_mult: 1 } param { lr_mult: 2 } inner_product_param { num_output: 500 weight_filler { type: "xavier" } bias_filler { type: "constant" } } bottom: "pool2" top: "ip1"}
这将定义全连接层,在caffe中叫做InnerProduct Layer。 有500个输出。其他的看起来都很熟悉,同上。
//ReLU Layerlayer { name: "relu1" type: "ReLU" bottom: "ip1" top: "ip1"}
ReLU 是一个聪明的操作,我们可以就地操作来节省一些内存。实现方法是 bottom和top给出相同的名字
//another innerProduct layer layer { name: "ip2" type: "InnerProduct" param { lr_mult: 1 } param { lr_mult: 2 } inner_product_param { num_output: 10 weight_filler { type: "xavier" } bias_filler { type: "constant" } } bottom: "ip1" top: "ip2"}
ReLu层之后,我们定义了另外一个全连接层
//Loss Layerlayer { name: "loss" type: "SoftmaxWithLoss" bottom: "ip2" bottom: "label"}
softmax_loss 层 实现了softmax loss 和多项式逻辑loss。它携带两种blobs,第一中是预测数据,第二种是label数据,由data layer提供。它不产生任何输出,它的任务就是计算损失函数的值,当反向传播算法开始时汇报损失函数的值,并且初始化ip2的梯度。这就是魔法的开始。