《深度学习:卷积神经网络从入门到精通》——3.4 LeNet的Caffe代码实现及说明

举报
华章计算机 发表于 2019/06/06 08:55:16 2019/06/06
【摘要】 本书摘自《深度学习:卷积神经网络从入门到精通》——书中第3章,第3.4节,作者是李玉鑑、张婷、单传辉、刘兆英等。

3.4 LeNet的Caffe代码实现及说明

LeNet是Caffe安装包自带的一个例子模型。在安装好Caffe包后,其Caffe代码可以在子文件夹examples下的mnist案例中找到。

LeNet的Caffe实现代码共有三个文件:网络结构文件lenet_train_test.prototxt、求解器配置文件lenet_solver.prototxt和伪概率计算文件lenet.prototxt。其中,lenet_train_test.prototxt用来定义网络的训练数据目录、测试数据目录和网络结构细节,包括每个卷积层的卷积核个数、大小、步长,每个下采样层的类型、窗口大小、步长,全连接层的节点数目、激活函数的类型、损失函数类型,以及层与层之间的关系等。lenet_solver.prototxt用来给求解器配置训练和测试网络的有关超参数,包括学习率的大小、训练的迭代次数及优化方法、使用的计算模式(CPU或GPU)等。lenet.prototxt用来在模型训练好后对未知样本计算分类伪概率。下面分别对这三个文件的具体内容进行描述。

1.网络结构文件lenet_train_test.prototxt的内容描述

该文件主要用来定义LeNet的网络结构,有关参数及其含义见表3.2。

表3.2 网络结构文件lenet_train_test.prototxt的参数及其含义

image.png


下面是具体的代码。

name: "LeNet"

layer {

    name: "CaseName" # 表示案例名称

    type: "Data" # 表示该层用于数据输入

    top: "data"

    top: "label"

    data_param {

        source: "TrainSetDir" # 表示训练集目录

        backend: LEVELDB # 一种Caffe数据类型

        batch_size: Train_batch_size # 表示训练集迷你块的大小

    }

    transform_param {

        scale: 0.00390625 # 将图像灰度值除以256归一化,把输入数据变换到

  [0,1]区间

    }

    include: { phase: TRAIN }

}

layer {

    name: "CaseName"

    type: "Data"

    top: "data"

    top: "label"

    data_param {

        source: "TestSetDir" # 表示测试集目录

        backend: LEVELDB

        batch_size: Test_batch_size # 表示测试集迷你块的大小

    }

    transform_param {

        scale: 0.00390625

    }

    include: { phase: TEST }

}

layer {

    name: "conv1"

    type: "Convolution" # 表示该层为卷积层

    bottom: "data"

    top: "conv1"

    param {

        lr_mult: 1 # 权重学习率倍数,用来放大初始学习率base_lr

    }

    param {

        lr_mult: 2 #偏置学习率倍数,把初始学习率base_lr放大2倍

    }

    convolution_param {

        num_output: conv1_num_output # 表示卷积面的个数

        kernel_size: conv1_kernel_size # 表示卷积核的大小

        stride: conv1_stride # 表示卷积核的移动步长

        weight_filler {

            type: "xavier" # 使用xavier方法初始化权值,也可以设置为”gaussian”或其他方法

        }

        bias_filler {

            type: "constant" # 表示把偏置初始化为常数0,若要初始化为0.1,可用语句 value: 0.1

        }

    }

}

layer {

    name: "relu1"

    type: "Insanity" # 把该层的激活函数设置为Insanity类型,即一种randomized LReLU

    bottom: "conv1"

    top: "conv1"

}

layer {

    name: "pool1"

    type: "Pooling" # 池化层

    bottom: "conv1"

    top: "pool1"

    pooling_param {

        pool: MAX # 把池化类型选为最大池化,还可选择平均池化

        kernel_size: pool1_kernel_size # 表示池化窗的大小

        stride: pool1_stride # 表示池化窗的移动步长

    }

}

layer {

    name: "conv2"

    type: "Convolution" # 卷积层

    bottom: "pool1"

    top: "conv2"

    param {

        lr_mult: 1

    }

    param {

        lr_mult: 2

    }

    convolution_param {

        num_output: conv2_num_output # 表示卷积面的个数

        kernel_size: conv2_kernel_size # 表示卷积核的大小

        stride: conv2_stride # 表示卷积核的移动步长

        weight_filler {

            type: "xavier"

        }

        bias_filler {

            type: "constant"

        }

    }

}

layer {

    name: "relu2"

    type: "Insanity"

    bottom: "conv2"

    top: "conv2"

}

layer {

    name: "pool2"

    type: "Pooling" # 池化层

    bottom: "conv2"

    top: "pool2"

    pooling_param {

        pool: MAX

        kernel_size: pool2_kernel_size # 表示池化窗的大小

        stride: pool2_stride # 表示池化窗的移动步长

    }

}

layer {

    name: "ip1"

    type: "InnerProduct" # 全连接层,在这里也称为内积

    bottom: "pool2"

    top: "ip1"

    param {

        lr_mult: 1

    }

    param {

        lr_mult: 2

    }

    inner_product_param {

        num_output: ip1_num_output # 表示全连接层的节点数

        weight_filler {

            type: "xavier"

        }

        bias_filler {

            type: "constant"

        }

    }

}

layer {

    name: "relu3"

    type: "Insanity"

    bottom: "ip1"

    top: "ip1"

}

layer {

    name: "ip2"

    type: "InnerProduct" # 全连层

    bottom: "ip1"

    top: "ip2"

    param {

        lr_mult: 1

    }

    param {

        lr_mult: 2

    }

    inner_product_param {

        num_output: ip2_num_output # 全连接层的节点数

        weight_filler {

            type: "xavier"

        }

        bias_filler {

            type: "constant"

        }

    }

}

layer {

    name: "accuracy"

    type: "Accuracy" # 该层只出现在测试阶段,用于计算准确率

    bottom: "ip2" # 计算准确率要用到全连接层ip2

    bottom: "label" # 计算准确率还要用到标签层

    top: "accuracy"

    include {

        phase: TEST

    }

}

layer {

    name: "loss"

    type: "SoftmaxWithLoss" # 带损失的软最大输出层,采用退化交叉熵损失函数

    bottom: "ip2" # 计算损失要用到全连接层ip2

    bottom: "label" # 计算损失还要用到标签层

    top: "loss"

}

2.求解器配置文件lenet_solver.prototxt的内容描述

该文件主要用于配置对LeNet模型进行训练和测试的有关参数,其含义在表3.3中给出了详细描述。文件对这些参数的一种具体配置情况如方框3.1所示。

表3.3 求解器配置文件lenet_solver.prototxt的超参数及其含义

image.png


方框3.1 求解器的一种具体超参数配置

net: "C:/Caffe/caffe-windows-master/examples/mnist/lenet_train_test.prototxt"

test_iter: 100   

test_interval: 500 # 每训练500次,测试1次

base_lr: 0.01 

momentum: 0.9 

weight_decay: 0.0005

lr_policy: "inv" # 把学习率的下降策略选为inv类型,还可以选为fixed、step和exp等类型

gamma: 0.0001

power: 0.75

display: 100 # 每训练100次显示1次中间结果

max_iter: 10000 # 最多训练10?000次

snapshot: 5000 # 每训练5000次保存1次结果,命名为_iter_5000.caffemodel等

snapshot_prefix: "C:/Caffe/caffe-windows-master/examples/mnist/lenet"

type: “SGD” # 选用随机梯度下降法训练,还可选AdaDelta、AdaGrad、Adam、

# Nesterov、RMSProp

solver_mode: GPU

3.伪概率计算文件lenet.prototxt的内容描述

该文件主要用来在模型训练好后对未知样本计算分类伪概率,有关参数及其含义见表3.4。

表3.4 伪概率计算文件lenet.prototxt的参数及含义

image.png


下面是具体的代码。

name: "LeNet"

layer {

    name: "data"

    type: "Input"

    top: "data"

    input_param { shape: { dim: dim1 dim: dim2 dim: dim3 dim: dim4 } }  

    ?# 表示输入层大小

}

layer {

    name: "conv1"

    type: "Convolution"

    bottom: "data"

    top: "conv1"

    param {

        lr_mult: 1

    }

    param {

        lr_mult: 2

    }

    convolution_param {

        num_output: conv1_num_output # 表示卷积面的个数

        kernel_size: conv1_kernel_size # 表示卷积核的大小

        stride: conv1_stride # 表示卷积核的移动步长

        weight_filler {

            type: "xavier"

        }

        bias_filler {

            type: "constant"

        }

    }

}

layer {

    name: "pool1"

    type: "Pooling"

    bottom: "conv1"

    top: "pool1"

    pooling_param {

        pool: MAX

        kernel_size: pool1_kernel_size # 表示池化窗的大小

        stride: pool1_stride # 表示池化窗的移动步长

    }

}

layer {

    name: "conv2"

    type: "Convolution"

    bottom: "pool1"

    top: "conv2"

    param {

        lr_mult: 1

    }

    param {

        lr_mult: 2

    }

    convolution_param {

        num_output: conv2_num_output

        kernel_size: conv2_kernel_size

        stride: conv2_stride

        weight_filler {

            type: "xavier"

        }

        bias_filler {

            type: "constant"

        }

    }

}

layer {

    name: "pool2"

    type: "Pooling"

    bottom: "conv2"

    top: "pool2"

    pooling_param {

        pool: MAX

        kernel_size: pool2_kernel_size

        stride: pool2_stride

    }

}

layer {

    name: "ip1"

    type: "InnerProduct"

    bottom: "pool2"

    top: "ip1"

    param {

        lr_mult: 1

    }

    param {

        lr_mult: 2

    }

    inner_product_param {

        num_output: ip1_num_output # 表示全连层的节点数

        weight_filler {

            type: "xavier"

        }

        bias_filler {

            type: "constant"

        }

    }

}

layer {

    name: "relu1"

    type: "ReLU"

    bottom: "ip1"

    top: "ip1"

}

layer {

    name: "ip2"

    type: "InnerProduct"

    bottom: "ip1"

    top: "ip2"

    param {

        lr_mult: 1

    }

    param {

        lr_mult: 2

    }

    inner_product_param {

        num_output: ip2_num_output # ip2_num_output表示全连层的节点数

            weight_filler {

            type: "xavier"

        }

        bias_filler {

            type: "constant"

        }

    }

}

layer {

    name: "prob"

    type: "Softmax"

    bottom: "ip2"

    top: "prob"

}

最后,需要指出,这个伪概率计算文件lenet.prototxt是Caffe安装包自带的,但所定义的网络结构与网络结构文件lenet_train_test.prototxt并不完全一致。因此,如果模型是基于lenet_train_test.prototxt训练的,还必须对lenet.prototxt文件进行适当修改,使得两者的模型结构一致,才能对未知样本正确计算伪概率。


【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。