1、层次模型学习笔记
在网上搜caffe教程,大都是一开始讲各种层没感觉,于是我先自己跑跑Caffe自带的两个例子(mnist与cifar10),然后对照着教程,把学习记录如下:
Caffe的层有很多种类型,比如Data, Convolution, Pooling等,层之间的数据流动是以Blobs的方式进行。
各层概述:
- Data:数组层;类型可以为 LevelDB、LMDB、内存、图片等
- Convolution:卷积层;CNN的核心
- Pooling:池化层;为了减少运算量与数据维度而设置的一种层
- ReLU、Sigmoid、TanH 、AbsVal、Power、BNLL:激活层,对输入数据进行激活操作(实际上就是一种函数变换),是逐元素进行运算的。从bottom得到一个blob数据输入,运算后,从top输入一个blob数据。在运算过程中,没有改变数据的大小,即输入和输出的数据大小是相等的。
- InnerProduct:全连接层;把输入当做一个向量,输出是一个简单向量(把输入数据的blobs的width与height全变为1)
- Accuracy: 输出分类(预测)精确度,只有test阶段才有
- softmax-loss/softmax 层;是分类器,计算类别的概率(Likelihood),是二分类Logistics Regression的多分类推广
以下通过官方示例进行简单阐述(cifar10_quick_train_test.prototxt):
name: "CIFAR10_quick"
layer {
name: "cifar" # 该层名字,随意
type: "Data" # 层类型,此处为 Data 数据层 <- LevelDB, LMDB, 内存, 图片等
top: "data" # top 示意输出数据;数据层中至少有一个命名为 data 的 top
top: "label" # top 示意输出数据;数据层中至少有一个命名为 data 的 top,如果有第二个top,则一般为 label
include { # 表示在什么阶段使用
phase: TRAIN # 表示此层处在训练模型中(如果没有则表示训练、测试模型都有)
}
transform_param {
mean_file: "examples/cifar10/mean.binaryproto" # 数据预处理 scale: 0.0039 即为 1/255 归一化
}
data_param {
source: "examples/cifar10/cifar10_train_lmdb"
batch_size: 100
backend: LMDB
}
}
layer {
name: "cifar"
type: "Data"
top: "data"
top: "label"
include {
phase: TEST
}
transform_param {
mean_file: "examples/cifar10/mean.binaryproto"
}
data_param {
source: "examples/cifar10/cifar10_test_lmdb"
batch_size: 100
backend: LMDB
}
}
layer {
name: "conv1"
type: "Convolution" # 卷积层 - CNN的核心 (全连接层InnerProduct 是卷积层的一种,只是卷积核大小与原数据一致)
bottom: "data"
top: "conv1"
param {
lr_mult: 1 # 学习率系数 # 第一个表示权值学习率
}
param {
lr_mult: 2 # 学习率系数 # 第二个表示偏置项学习率,一般偏置项学习率是 权值学习率的2倍
}
convolution_param {
num_output: 32 # 必须参数 # 卷积核(filter)个数
pad: 2 # 可选参数 # 扩充边缘,默认为0不扩充 # 可以用 pad_h pad_w 分别设定
kernel_size: 5 # 必须参数 # 卷积核大小 # 如果卷积核大小不等,则要用 kernel_h kernel_w 分别设定
stride: 1 # 可选参数 # 卷积核步长,默认为1,也可以用 stride_h stride_w 分别设定
weight_filler { # 可选参数 # 权值初始化。默认为 constant 值全为0 # 很多时候用 xavier 算法 # gaussian
type: "gaussian"
std: 0.0001
}
bias_filler { # 可选参数 # 偏置项初始化。默认为 constant 值全为0
type: "constant"
}
}
}
layer {
name: "pool1"
type: "Pooling" # 池化层,为了减少运算量与数据维度而设置的一种层
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX # 可选参数 # 池化方法,默认为MAX
kernel_size: 3 # 必须参数 # 卷积核大小 # 如果卷积核大小不等,则要用 kernel_h kernel_w 分别设定
stride: 2 # 可选参数 # 默认为1,一般设置为2,即不重叠,也可以用 stride_h stride_w 分别设定
# pad 可选参数 # 扩充边缘,默认为0不扩充 # 可以用 pad_h pad_w 分别设定
}
}
layer {
name: "relu1"
type: "ReLU" # 激活层的一种 # 目前使用最多的激活函数;收敛快并且能保持同样效果;f(x)=max(x, 0)
bottom: "pool1"
top: "pool1"
# negative_slope # 可选参数 # 默认为0,如果设置这个值,则数据为负时,就不再设置为0,而是原始数据乘以 negative_slope
}
layer {
name: "conv2"
type: "Convolution"
bottom: "pool1"
top: "conv2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 32
pad: 2
kernel_size: 5
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu2"
type: "ReLU"
bottom: "conv2"
top: "conv2"
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: AVE
kernel_size: 3
stride: 2
}
}
layer {
name: "conv3"
type: "Convolution"
bottom: "pool2"
top: "conv3"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 64
pad: 2
kernel_size: 5
stride: 1
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu3"
type: "ReLU"
bottom: "conv3"
top: "conv3"
}
layer {
name: "pool3"
type: "Pooling"
bottom: "conv3"
top: "pool3"
pooling_param {
pool: AVE
kernel_size: 3
stride: 2
}
}
layer {
name: "ip1"
type: "InnerProduct" # 全连接层 # 把输入当做一个向量,输出是一个简单向量(吧输入数据的blobs的width与height全变为1)
bottom: "pool3" # 输入 # n*c0*h*w
top: "ip1" # 输出 # n*c0*1*1
param {
lr_mult: 1 # 学习率系数 # 第一个表示权值学习率 # 最终学习率是这个数乘以solver.prototex配置文件中的base_lr
}
param {
lr_mult: 2 # 学习率系数 # 第二个表示偏置项学习率,一般偏置项学习率是 权值学习率的2倍
}
inner_product_param {
num_output: 64 # 过滤器(filfter)个数
weight_filler { # 权值初始化
type: "gaussian"
std: 0.1
}
bias_filler { # 偏置项初始化
type: "constant"
}
}
}
layer {
name: "ip2"
type: "InnerProduct"
bottom: "ip1"
top: "ip2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 10
weight_filler {
type: "gaussian"
std: 0.1
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "accuracy"
type: "Accuracy" # 输出分类(预测)精确度,只有test阶段才有
bottom: "ip2"
bottom: "label"
top: "accuracy"
include { # 表示在什么阶段使用
phase: TEST # 只有test阶段才有
}
}
layer {
name: "loss"
type: "SoftmaxWithLoss" # softmax-loss/softmax 层,是分类器,计算类别的概率(Likelihood),是二分类Logistics Regression的多分类推广
bottom: "ip2"
bottom: "label"
top: "loss" # SoftmaxWithLoss -> 输出 loss 值; Softmax -> 输出 似然值
}
2、solver学习笔记:(lenet_solver.prototxt为例)
solver是caffe的核心,它协调着整个模型的运作。caffe程序运行必带的一个参数就是solver配置文件。
# The train/test net protocol buffer definition
net: "examples/mnist/lenet_train_test.prototxt"
# test_iter specifies how many forward passes the test should carry out.
# In the case of MNIST, we have test batch size 100 and 100 test iterations,
# covering the full 10,000 testing images.
test_iter: 100 # batch_size 为100,则 batch_size * test_iter = 10000样本总数,这样将测试数据分为几个批次来执行(100批),每个批次数量为100,为了提高全部数据执行效率
# Carry out testing every 500 training iterations.
test_interval: 500 # 测试间隔,这里每训练500次,才进行一次测试
# The base learning rate, momentum and the weight decay of the network.
base_lr: 0.01 # 学习率(步长)设置,在迭代过程中进行调整,调整策略由 lr_policy 设置
momentum: 0.9
weight_decay: 0.0005
# The learning rate policy
lr_policy: "inv" # fixed: 保持 base_lr 不变; inv: 还需要设置一个power;step-stepsize; exp; multistep; poly; sigmoid
gamma: 0.0001 # base_lr * (1+gamma*iter) ^ (-power)
power: 0.75 # base_lr * (1+gamma*iter) ^ (-power)
# Display every 100 iterations
display: 100 # 每训练 100 次在屏幕上显示一次,如果设置为 0 则不显示;
# The maximum number of iterations
max_iter: 10000 # 最大迭代次数,设置太小则会不收敛,精确度很低;太大会导致震荡,浪费时间;
# snapshot intermediate results
snapshot: 5000 # 快照,将训练出来的 model 和 solver 状态进行保存,这里设置训练多少次后进行保存,默认为0不保存
snapshot_prefix: "examples/mnist/lenet" # 设置保存快照的路径
# solver mode: CPU or GPU
solver_mode: GPU
参考链接:https://www.cnblogs.com/denny402/tag/caffe/