caffe在 .\examples\mnist文件夹下有一个 lenet.prototxt文件,这个文件定义了一个广义的LetNet-5模型,对这个模型文件逐段分解一下。

name: "LeNet"   //网络的名称是LeNet
layer {                //定义一个网络层
  name: "data"   //定义该网络层的名称为 data
  type: "Input"   //定义网络层的类型是 输入层
  top: "data"      //定义网络层的输出名称为data
  //定义该网络层的训练参数
  input_param { 
  
  //如果同时读取过多张图片进行训练,训练耗时比较久
  //所以CNN中分组读入训练图片
  //shape中第一个参数定义每组中包含图片数量
  //第二个参数定义组数
  //第三和第四个参数定义图片大小

  //定义读取数据维度是: 64 1 28 28
  shape: { dim: 64 dim: 1 dim: 28 dim: 28 }
   }
}

//第一卷积层定义
layer {      //定义一个网络层
  name: "conv1"  //网络层的名称是conv1
  type: "Convolution"  //网络层的类型是 卷积层

  //模型结构图有两种常用画法,一种是从左到右,一种是从下到上
  //caffe中使用从下到上画法,所以“bottom”表示的是上一层(输入层)

  bottom: "data"  //网络层的输入层是 data层

  //同理,输出层在上,“top”表示输出

  top: "conv1"   //该层的输出层名称为conv1

  //param定义权重和偏置的学习率,学习率大,迭代速度快,但是容易找不到最优解
  //学习率小,迭代速度慢,耗时久
  //如果有两个lr_mult参数,第一个表示权重(卷积核)的学习率系数,第二个表示偏置的学习率系数
  //lr_mult定义的只是学习率系数,最终的值需要乘以solver.prototxt配置文件中配置的base_lr的值
  //一般偏置的学习率系数是权重学习率系数的2倍

  param {
    lr_mult: 1   //该层权重学习率的系数为1
  }
  param {
    lr_mult: 2   //该层偏置学习率的系数为2
  }
  //卷积操作的参数设置
  convolution_param {
    num_output: 20   //卷积输出特征图的数量为20
    kernel_size: 5      //卷积核的大小是5*5
    stride: 1               //卷积操作的步长是1,即卷积核逐个移动
    weight_filler {
      type: "xavier"   //卷积核参数采用xavier方法初始化
    }
    bias_filler {
      type: "constant"   //偏置初始值为0
    }
  }
} //卷积完成之后,数据的维度变成 64 20 24 24

//第一池化层定义 
layer {
  name: "pool1"      //网络层的名称是pool1
  type: "Pooling"     //网络层的类型是池化层
  bottom: "conv1"  //网络层的输入时conv1(第一卷积层)
  top: "pool1"         //网络层的输出名称是 pool1

  //池化操作的参数设置
  pooling_param {
    pool: MAX        //最大值池化
    kernel_size: 2    //池化核尺寸 是2*2 
    stride: 2            //池化步长是2
  }
}   //第一池化完成之后,数据的维度变成 64 20 12 12 

//第二卷积层定义
layer {
  name: "conv2"       //网络层的名称是conv2
  type: "Convolution"  //网络层的类型是卷积层
  bottom: "pool1"    //网络层的输入时 pool1(第一池化层)
  top: "conv2"          //网络层的输出名称是 conv2
  param { 
    lr_mult: 1             //卷积核的学习率系数是1
  }
  param {
    lr_mult: 2             //偏置的学习率系数是2
  }

  //第二卷积层参数设置
  convolution_param {
    num_output: 50       //输出特征图的数量
    kernel_size: 5           //卷积核的尺寸是5*5
    stride: 1                   //卷积操作步长是1
    weight_filler {
      type: "xavier"          //卷积核参数采用xavier方法初始化
    }
    bias_filler {
      type: "constant"       //偏置初始值为0
    }
  }
}    //第二卷积操作完成之后,数据维度是 64 50 8 8 

//第二池化层
layer {
  name: "pool2"       //网络层的名称是 pool2
  type: "Pooling"      //网络层的类型是池化层
  bottom: "conv2"    //网络层的输入时 conv2(第二卷积层)
  top: "pool2"           //网络层的输出名称是 pool2
  pooling_param {
    pool: MAX            //池化方式是最大值池化
    kernel_size: 2        //池化核大小是2*2
    stride: 2                 //池化步长是2
  }
}        //第二池化层完成之后,数据维度是  64 50 4 4

//第一层全连接层定义
layer {
  name: "ip1"    //网络层的名称是ip1
  type: "InnerProduct"    //网络层的类型是 全连接层
  bottom: "pool2"          //网络层的输入时 pool2(第二池化层)
  top: "ip1"                     //网络层的输出名称是ip1
  param {
    lr_mult: 1                  //卷积核的学习率系数是1
  }
  param {
    lr_mult: 2					//偏置的学习率系数是2
  }

  //第一全连接层参数设置
  inner_product_param { 
    num_output: 500     //输出向量维度,500个输出神经元
    weight_filler {
      type: "xavier"          //卷积核参数采用xavier方法初始化
    }
    bias_filler {
      type: "constant"	      //偏置初始值为0
    }
  }
}  //第一全连接层完成之后数据的维度是 1  500 1 1

//激活函数层的定义
layer {
  name: "relu1"     //网络层的名称是relu1
  type: "ReLU"      //网络层的类型是ReLU激活函数
  bottom: "ip1"     //网络层的输入时ip1(第一全连接层)
  top: "ip1"           //网络层的输出名称是 ip1,跟输入名称一样
}   //激活层完成之后,数据的维度是 1 500 1 1

//第二全连接层定义
//数据的分类判断在本层完成
layer {
  name: "ip2"      //网络层的名称是 ip2
  type: "InnerProduct"   //网络层的类型是全连接层
  bottom: "ip1"       //网络层的输入时 ip1(激活函数层)
  top: "ip2"      //网络层的输出名称是 ip2
  param {
    lr_mult: 1        //卷积核的学习率系数是1
  }
  param {
    lr_mult: 2	       //偏置的学习率系数是2
  }

  //第二全连接层参数设置
  inner_product_param {
    num_output: 10     //输出维度是10,分别是0~9的数字
    weight_filler {
      type: "xavier"       //卷积核参数采用xavier方法初始化
    }
    bias_filler {
      type: "constant"	  //偏置初始值为0
    }
  }
}    //第二全连接层完成之后,数据的维度是 1 10 1 1

//输出层定义
layer {
  name: "prob"    //网络的名称是 prob
  type: "Softmax"   //网络的类型是损失函数
  bottom: "ip2"     //网络的输入是 ip2(第二全连接层)
  top: "prob"       //网络的输出名称是 prob
}


lenet.prototxt模型可视化,可以作为对比:





posted on 2017-06-28 00:26  未雨愁眸  阅读(235)  评论(0编辑  收藏  举报