本篇文章是我利用 caffe进行深度学习的知识点总结,包含别人学习笔记链接
caffe简介
caffe的作者为UC Berkeley大学的贾扬清。caffe是一个c++/CUDA架构,支持命令行、Python、Matlab接口,可以在CPU/GPU上运行。
Caffe项目的文件结构
- caffe(要编译的文件,里面包含用c++写的数据输入、网络层、计算等核心文件)
- data (要处理或者转换的数据)
- models:
train.prototxt (网络模型) solve.prototxt(设置训练的一系列参数) xxx.caffemodel(finetune 时用的初始化参数,训练新模型则不需要)
- scripts(训练网络的代码,可以是python文件,shell文件等)
caffe 安装参考:https://www.jianshu.com/p/9e0a18608527
caffe 网络结构
caffe 使用Blob数组结构来存储、交换、处理网络(就像numpy的存储结构为narray),用caffe Layer来定义神经网络结构,它包含数据层、视觉层等类型
下面以代码为例,讲解常用层
train.prototxt( 以下为VGG16模型部分代码)
- 数据层
name: "VGG16"
layer {
name: "data"
type: "Data" #输入的数据类型
top: "data"
top: "label"
include {
phase: TRAIN
}
#数据预处理,来增强数据
transform_param {
mirror: true
crop_size: 224
mean_value: 103.939
mean_value: 116.779
mean_value: 123.68
}
data_param {
source: "data/ilsvrc12_shrt_256/ilsvrc12_train_leveldb" #数据库文件路径
batch_size: 64 #网络单次输入数据数量
backend: LEVELDB #选择使用LevelDB还是LMDB
}
}
caffe支持输入的数据类型:
type | data |
---|---|
Data | LMDB/levelDB |
MemoryData | 内存数据 |
HDF5Data | HDF5数据 |
ImagesData | 图像数据Images |
WindowsData | 窗口Windows |
top:表示输出的方向,bottom:表示输入的数据来源(层的名称),可以有多个top和bottom
注意:在数据层中,至少有一个命名为data的top。如果有第二个top,一般命名为label
LMDB参考资料:https://zhuanlan.zhihu.com/p/23485774
- 卷积层
layer {
bottom: "data"
top: "conv1_1"
name: "conv1_1"
type: "Convolution"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
convolution_param {
num_output: 64
pad: 1
kernel_size: 3
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
value: 0
}
}
}
参数
num_output | 卷积核数量 |
kernel_size | 卷积核高度/宽度(可分别设置宽高) |
weight_filler | 参数初始化方案 |
bias_term | 是否给卷积输出添加偏置项 |
pad | 图像周围补0的像素个数 |
stride | 滑动步长 |
group | 指定分组卷积操作的组数 |
lr_mult | 学习率(最终的学习率要乘以 solver.prototxt 配置文件中的 base_lr) |
decay_mult | 权值衰减 |
dropout_ratio | 丢弃数据的概率 |
- | - |
dropout_ratio和decay_mult设置为了防止数据过拟合
- 池化层
layer {
bottom: "pool1"
top: "conv2_1"
name: "conv2_1"
type: "Convolution"
param {
lr_mult: 1
decay_mult: 1
}
param {
lr_mult: 2
decay_mult: 0
}
convolution_param {
num_output: 128
pad: 1
kernel_size: 3
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
value: 0
}
}
}
参数 | |
---|---|
pool | 池化方式,Max:最大池化,AVE:均值池化,STOCHASTIC:随机池化 |
-
激活层
-
损失函数层
layer { bottom: "fc8" bottom: "label" top: "loss" name: "loss" type: "SoftmaxWithLoss" }
type | |
---|---|
SoftmaxWithLoss | 交叉信息熵损失函数 |
Softmax | 多分类损失函数 |
caffe网络模型各层信息(详细):https://wenku.baidu.com/view/f77c73d02f60ddccdb38a025.html
Caffe模型训练
- 网络可视化
当你写好自己的prototxt文件后,想要检查自己的网络框架是否搭建正确,可以借助 Netscope (在线caffe net可视化工具)http://ethereon.github.io/netscope/#/editor
- 训练参数设置
caffe模型的训练参数在solve.prototxt文件中,该文件是caffe的核心,它交替调用前向算法和反向传播算法来更新参数,使loss的值达到最小
net: "train_val.prototxt"
test_iter: 833
# make test net, but don't invoke it from the solver itself
test_interval: 1000
display: 200
average_loss: 100
base_lr: 1e-5
lr_policy: "step"
gamma: 0.1
stepsize: 5000
# lr for unnormalized softmax -- see train_val definition
# high momentum
momentum: 0.9
# no gradient accumulation
clip_gradients: 10000
iter_size: 1
max_iter: 80000
weight_decay: 0.02
snapshot: 4000
snapshot_prefix: "weight/VGG_item"
test_initialization: false
参数 | |
---|---|
train_net | 训练所需网络模型(最好写绝对路径) |
test_net | 测试所需网络模型 |
test_iter | 测试次数 (test_iter * batchsize = 训练的数据量) |
base_lr | 基本学习率 |
lr_policy | 学习率改变的方法 |
weight_decay | 权重衰减 |
momentum | 表示上一次梯度更新的权重 |
max_iter | 最大迭代次数 |
snapshot | 保存模型间隔 |
snapshot_prefix | 保存模型路径+前缀 |
solver_mode | 是否使用GPU |
average_loss | 取多次foward的loss作平均,进行显示输出 |
type | 优化算法 |
- 训练网络
1、命令行
我们可以在命令行输入代码训练网络
./build/tools/caffe train -solver solver.prototxt
(详细请参考:《caffe命令行解析》https://www.cnblogs.com/denny402/p/5076285.html)
2、python
我们也可以利用caffe的python接口来编写训练网络的程序
其他问题
- 输入输出大小
在用自己的数据训练或者微调网络的过程中,可能会出现img 与label_img大小不同的情况,这个时候就仔细分析训练过程所显示的每一层输入输出的大小,更改相应的参数使最后训练的img与label_img大小相同
卷积核与池化层输出图像尺寸计算公式:
(W-F+2P)/S+1
参数 | 说明 |
---|---|
w | 输入图像大小 |
F | 卷积核尺寸(kernel_size) |
S | 步幅大小(stride) |
P | padding大小(pad) |