Caffe文件详解

本文详细介绍了使用Caffe框架进行手写数字识别的过程,包括Mnist数据集的下载与处理,构建并训练LeNet卷积神经网络模型,以及模型测试与效果评估。深入探讨了网络模型描述文件与超参数文件的配置细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                                                                                                                                             点击此处返回总目录

 

上节课快速过了一遍手写数字识别的例子,但是很多细节没有讲清楚。这节课主要吧细节补充完整。

 

 

一、下载Mnist数据集。

下载下来的数据集分两部分:6万张图片的训练数据集,1万张图片的测试数据集。

图片是白底黑字。28*28大小。每个像素8位,也就是说每个像素强度介于0~255之间。

我们下载的数据集,已经转换成了二进制的形式,所以看不出图片的样子。

 

 

二、将数据集转换为LEVELDB或LMDB文件

 

LMDB的作用:

1. 统一数据类型。

2. 快。

 

 

三、修改网络模型描述文件

 

//lenet_train_test.prototxt

name: "LeNet"          #首先给网络起了个名字。网络的名字"LeNet"
layer {                       #定义一个层
  name: "mnist"         #层的名字"mnist"
  type: "Data"            #层的类型"Data",为数据层,数据只能来源于LevelDB或LMDB。

                                 #另外数据的来源还可能是来自内存,HDF5,图片等。但是type就不是"Data"了。
  top: "data"              #输出data。top是输出,bottom是输入。有两个top表示有两个输出。第一个输出叫"data"
  top: "label"              #输出label。
  include {
    phase: TRAIN              #该层只在TRAIN训练的时候有效
  }
  transform_param {         #数据的预处理
    scale: 0.00390625       #1/256,将输入的数据0-255归一化到0-1之间。每个值乘以scale。
  }
  data_param {
    source: "E:/Caffe-windows/caffe-windows/examples/mnist/lmdb/train_lmdb"   #数据来源。lmdb格式的数据。
    batch_size: 64             #每个批次处理64张图片。
    backend: LMDB           #数据格式为LMDB
  }
}
layer {                        #定义一个层。这个层跟上面层基本一样。不过该层在测试时有效,上面的层在训练时有效。
  name: "mnist"       
  type: "Data"           
  top: "data"           
  top: "label"             
  include {                 
    phase: TEST             #该层只在TEST测试的时候有效
  }                         
  transform_param {        
    scale: 0.00390625
  }
  data_param {
    source: "E:/Caffe-windows/caffe-windows/examples/mnist/lmdb/test_lmdb" #数据来源
    batch_size: 100         #每个批次处理100张图片
    backend: LMDB
  }
}
layer {                              #第一个卷积层
  name: "conv1"               #层的名字"conv1"
  type: "Convolution"        #层的类型"Convolution"
  bottom: "data"                #输入data。这个data就是从上面来的。
  top: "conv1"                   #输出conv1
  param {                         #这个是权值的学习率
    lr_mult: 1                     #学习率系数。最终的学习率:lr_mult乘以超参数文件solver.prototxt里面的base_lr
  }
  param {                         #这个是偏置的学习率
    lr_mult: 2                     #学习率系数。最终的学习率是lr_mult乘以超参数文件solver.prototxt里面的base_lr
  }
  convolution_param {
    num_output: 20       #卷积核的个数为20,或者表示输出特征平面的个数为20。因为有多少个卷积核就输出多少个特征平面。
    kernel_size: 5          #卷积核的大小5*5。如果卷积核长和宽不等,则需要用kernel_h和kernel_w分别设置
    stride: 1                   #步长为1。也可以用stride_h和stride_w来设置
    weight_filler {           #权值w初始化。
      type: "xavier"         #使用"Xavier"算法,也可以设置为"gaussian"(高斯算法)
    }
    bias_filler {               #偏置初始化
      type: "constant"     #一般设置为"constant",取值为0
    }
  }
}
layer {                          #第一个池化层
  name: "pool1"            #层的名字"pool1"
  type: "Pooling"           #层的类型"Pooling"
  bottom: "conv1"         #输入conv1。输入是第一个卷积层的输出。
  top: "pool1"                #输出pool1
  pooling_param {           
    pool: MAX               #池化方法。常用的方法有MAX,AVE或STOCHASTIC(随机值)
    kernel_size: 2         #池化核的大小2*2。如果池化核长和宽不等,则需要用kernel_h和kernel_w分别设置
    stride: 2                  #池化的步长。也可以用stride_h和stride_w来设置
  }
}
layer {                         #第二个卷积层
  name: "conv2"
  type: "Convolution"
  bottom: "pool1"
  top: "conv2"
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  convolution_param {
    num_output: 50          #卷积核的个数为50,或者表示输出特征平面的个数为50
    kernel_size: 5
    stride: 1
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
layer {                              #第二个池化层。
  name: "pool2"
  type: "Pooling"
  bottom: "conv2"
  top: "pool2"
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layer {                             #定义第一个全连接层
  name: "ip1"                   #层的名字"ip1"
  type: "InnerProduct"      #层的类型"InnerProduct",表示是全连接层
  bottom: "pool2"             #输入是第二个池化层的输出pool2
  top: "ip1"                       #输出ip1
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  inner_product_param {
    num_output: 500         #共有500个神经元
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
layer {                         #激活函数
  name: "relu1"            #层的名字"relu1"
  type: "ReLU"             #层的类型"ReLU",激活函数
  bottom: "ip1"             #输入ip1
  top: "ip1"                   #输出ip1。名字虽然一样,但是值有所改变。
}
layer {                         #第二个全连接层
  name: "ip2"               
  type: "InnerProduct"
  bottom: "ip1"            
  top: "ip2"                 
  param {
    lr_mult: 1
  }
  param {
    lr_mult: 2
  }
  inner_product_param {
    num_output: 10          #10个输出,代表10个分类
    weight_filler {
      type: "xavier"
    }
    bias_filler {
      type: "constant"
    }
  }
}
layer {                         #该层计算准确率。
  name: "accuracy"    
  type: "Accuracy"       #层的类型"Accuracy",用来判断准确率
  bottom: "ip2"           
  bottom: "label"       
  top: "accuracy"         #层的输出accuracy
  include {
    phase: TEST          #该层只在TEST测试的时候有效
  }
}
layer {                         #定义loss层,计算损失
  name: "loss"              
  type: "SoftmaxWithLoss"   #层的类型"SoftmaxWithLoss",输出loss值
  bottom: "ip2"            
  bottom: "label"          
  top: "loss"                 #层的输出loss
}

 

 

 

四、修改超参数文件

 

//lenet_solver.prototxt

#网络模型描述文件
#如果训练模型和测试模型不一样的话,也可以用train_net和test_net来对训练模型和测试模型分别设定:
#train_net: "xxxxxxxxxx"
#test_net: "xxxxxxxxxx"

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


#这个参数要跟test_layer结合起来考虑,在test_layer中一个batch是100,而总共的测试图片是10000张
#所以这个参数就是10000/100=100。说明我们需要测试100次。

test_iter: 100


#每训练500次进行一次测试
test_interval: 500


#学习率
base_lr: 0.01

 

#动力。因为Caffe的SGD其实是Momentum法,所以有这个参数。
momentum: 0.9

type:SGD

#type:SGD #优化算法的选择。这一行可以省略,因为默认值就是SGD,Caffe中一共有6中优化算法可以选择
#1. Stochastic Gradient Descent (type: "SGD"), 在Caffe中SGD其实应该是Momentum,并不是标准的随机梯度下降法。
#2. AdaDelta (type: "AdaDelta"),
#3. Adaptive Gradient (type: "AdaGrad"),
#4. Adam (type: "Adam"),
#5. Nesterov’s Accelerated Gradient (type: "Nesterov")
#6. RMSprop (type: "RMSProp")

 

#权重衰减项,其实也就是正则化项。作用是防止过拟合
weight_decay: 0.0005

 

#学习率调整策略
#如果设置为inv,还需要设置一个power, 返回base_lr * (1 + gamma * iter) ^ (- power),其中iter表示当前的迭代次数
lr_policy: "inv"
gamma: 0.0001
power: 0.75

 

#每训练100次屏幕上显示一次,如果设置为0则不显示
display: 100

 

#最大迭代次数
max_iter: 2000

 

#快照。可以把训练的model和solver的状态进行保存。每迭代5000次保存一次,如果设置为0则不保存
snapshot: 5000
snapshot_prefix: "E:/Caffe-windows/caffe-windows/examples/mnist/models"

 

#选择运行模式
solver_mode: CPU

 

 

 

五、开始训练模型

 

 

六、准备测试图片

 

 

七、生成均值文件

             

后面还会讲。

 

 

八、准备标签

 

 

九、测试分类效果

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值