Caffe入门:对于抽象概念的图解分析
Caffe的几个重要文件
用了这么久Caffe都没好好写过一篇新手入门的博客,最近应实验室小师妹要求,打算写一篇简单、快熟入门的科普文。
利用Caffe进行深度神经网络训练第一步需要搞懂几个重要文件:
- solver.prototxt
- train_val.prototxt
- train.sh
接下来我们按顺序一个个说明。
solver.prototxt
solver这个文件主要存放模型训练所用到的一些超参数:
- net := 指定待训练模型结构文件,即train_val.prototxt
- test_interval := 测试间隔,即每隔多少次迭代进行一次测试
- test_initialization := 指定是否进行初始测试,即模型未进行训练时的测试
- test_iteration := 指定测试时进行的迭代次数
- base_lr := 指定基本学习率
- lr_policy := 学习率变更策略,这里有介绍,可供参考
- gamma := 学习率变更策略需要用到的参数
- power := 同上
- stepsize := 学习率变更策略Step的变更步长(固定步长)
- stepvalue := 学习率变更策略Multistep的变更步长(可变步长)
- max_iter := 模型训练的最大迭代次数
- momentum := 动量,这是优化策略(Adam, SGD, … )用到的参数
- momentum2 := 优化策略Adam用到的参数
- weight_decay := 权重衰减率
- clip_gradients := 固定梯度范围
- display := 每隔几次迭代显示一次结果
- snapshot := 快照,每隔几次保存一次模型参数
- snapshot_prefix := 保存模型文件的前缀,可以是路径
- type := solver优化策略,即SGD、Adam、AdaGRAD、RMSProp、NESTROVE、ADADELTA等
- solver_mode := 指定训练模式,即GPU/CPU
- debug_info := 指定是否打印调试信息,这里有对启用该功能的输出作介绍
- device_id := 指定设备号(使用GPU模式),默认为0
用户根据自己的情况进行相应设置,黑体参数为必须指定的,其余参数为可选(根据情况选择)。
train_val.prototxt
train_val文件是用来存放模型结构的地方,模型的结构主要以layer为单位来构建。下面我们以LeNet为例介绍网络层的基本组成:
name: "LeNet"
layer {
name: "mnist" #网络层名称
type: "Data" #网络层类型,数据层
top: "data" #这一层的输出,数据
top: "label" #这一层的输出,标签
include { phase: TRAIN } #TRAIN:=用于训练,TEST:=用于测试
transform_param { scale: 0.00390625 } #对数据进行scale
data_param { #数据层配置
source: "examples/mnist/mnist_train_lmdb" #数据存放路径
batch_size: 64 #指定batch大小
backend: LMDB #指定数据库格式,LMDB/LevelDB
}
}
layer {
name: "mnist"
type: "Data"
top: "data"
top: "label"
include { phase: TEST }
transform_param { scale: 0.00390625 }
data_param {
source: "examples/mnist/mnist_test_lmdb"
batch_size: 100
backend: LMDB
}
}
layer{
name:"conv1"
type:"Convolution" #卷积层
bottom:"data" #上一层的输出作为输入
top:"conv1"
param{name:"conv1_w" lr_mult:1 decay_mult:1} #卷积层参数w的名称,学习率和衰减率(相对于base_lr和weight_decay的倍数)
param{name:"conv1_b" lr_mult:2 decay_mult:0} #卷积层参数b的名称,学习率和衰减率
convolution_param{
num_output:20 #卷积层输出的feature map数量
kernel_size:5 #卷积层的大小
pad:0 #卷积层的填充大小
stride:1 #进行卷积的步长
weight_filler{type:"xavier" } #参数w的初始话策略
weight_filler{type:"constant" value:0.1} #参数b的初始化策略
}
}
layer { #BatchNorm层,对feature map进行批规范化处理
name:"bn1"
type:"BatchNorm"
bottom:"conv1"
top:"conv1"
batch_norm_param{ use_global_stats:false} #训练时为false,测试时为true
}
layer { #池化层,即下采样层
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX #最大值池化,还有AVE均值池化
kernel_size: 2
stride: 2
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "pool1"
top: "conv2"
param { lr_mult: 1 }
param { lr_mult: 2 }
convolution_param {
num_output: 50
kernel_size: 5
stride: 1
weight_filler { type: "xavier" }
bias_filler { type: "constant" }
}
}
layer {
name:"bn2"
type:"BatchNorm"
bottom:"conv2"
top:"conv2"
batch_norm_param{ use_global_stats:false}
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer { #全连接层
name: "ip1"
type: "InnerProduct"
bottom: "pool2"
top: "ip1"
param { lr_mult: 1 }
param { lr_mult: 2 }
inner_product_param {
num_output: 500
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: 10
weight_filler { type: "xavier" }
bias_filler { type: "constant" }
}
}
layer { #损失函数层
name: "prob"
type: "SoftmaxWithLoss"
bottom: "ip2"
bottom: "label"
top: "prob"
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
网络结构和超参数都设计完了,接下来就可以进行模型训练了。这里我介绍最常用的模型训练脚本,也是Caffe官方文档给的例子。
train.sh
这个脚本文件可写,可不写。每次运行需要写一样的命令,所以建议写一下。
TOOLS=/path/to/your/caffe/build/tools
GLOG_logtostderr=0 GLOG_log_dir=log/ \ #该行用于调用glog进行训练日志保存,使用时请把该行注释删除,否则会出错
$TOOLS/caffe train --solver=/path/to/your/solver.prototxt #--snapshot=/path/to/your/snapshot or --weights=/path/to/your/caffemodel ,snapshot和weights两者只是选一,两个参数都可以用来继续训练,区别在于是否保存solver状态
- 1
- 2
- 3
数据准备
这里我们举个简单的例子,改代码是Caffe官方文档提供的,但只能用于单标签的任务,多标签得对源码进行修改。该脚本是对图片数据生成对应的lmdb文件,博主一般使用原图,即数据层类型用ImageData。
#!/usr/bin/env sh
# Create the imagenet lmdb inputs
# N.B. set the path to the imagenet train + val data dirs
set -e
EXAMPLE="" #存储路径
DATA="" #数据路径
TOOLS=/path/to/your/caffe/build/tools #caffe所在目录
TRAIN_DATA_ROOT="" #训练数据根目录
VAL_DATA_ROOT="" #测试数据根目录
# RESIZE=true to resize the images to 256x256. Leave as false if images have
# already been resized using another tool.
RESIZE=false #重新调整图片大小
if $RESIZE; then
RESIZE_HEIGHT=256
RESIZE_WIDTH=256
else
RESIZE_HEIGHT=0
RESIZE_WIDTH=0
fi
#检测路径是否存在
if [ ! -d "$TRAIN_DATA_ROOT" ]; then
echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT"
echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \
"where the ImageNet training data is stored."
exit 1
fi
if [ ! -d "$VAL_DATA_ROOT" ]; then
echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT"
echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \
"where the ImageNet validation data is stored."
exit 1
fi
echo "Creating train lmdb..."
GLOG_logtostderr=1 $TOOLS/convert_imageset \
--resize_height=$RESIZE_HEIGHT \
--resize_width=$RESIZE_WIDTH \
--shuffle \
$TRAIN_DATA_ROOT \
$DATA/train.txt \ #训练图片列表,运行时请把该行注释删除,否则会出错
$EXAMPLE/mnist_train_lmdb
echo "Creating val lmdb..."
GLOG_logtostderr=1 $TOOLS/convert_imageset \
--resize_height=$RESIZE_HEIGHT \
--resize_width=$RESIZE_WIDTH \
--shuffle \
$VAL_DATA_ROOT \
$DATA/val.txt \
$EXAMPLE/mnist_test_lmdb
echo "Done."
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
这样,我们就可以愉快的开始训练啦。
2017-05-15 记。
Caffe入门:对于抽象概念的图解分析的更多相关文章
- Linux Capabilities 入门教程:概念篇
原文链接:Linux Capabilities 入门教程:概念篇 Linux 是一种安全的操作系统,它把所有的系统权限都赋予了一个单一的 root 用户,只给普通用户保留有限的权限.root 用户拥有 ...
- 数学和物理太难?这些 GIF 让你秒懂抽象概念
把科学带回家,给孩子最好的科学教育 觉得数学和物理很抽象很难懂吗?今天我们来分享一组数学和物理相关的动图,让你秒懂抽象概念. 数学动图 △ 从椭圆的一个焦点射出的光线总会通过另一个焦点. △ 真人版. ...
- Caffe入门随笔
Caffe入门随笔 分享一下自己入门机器学习的一些资料:(1)课程,最推荐Coursera上的Andrew NG的Machine Learning,最好注册课程,然后跟下来.其次是华盛顿大学的Ma ...
- JavaScript入门几个概念
JavaScript入门几个概念 刚刚入门JavaScript的时候,搞懂DOM.BOM以及它们的对象document和window很有必要. DOM是为了操作文档出现的API,document是它的 ...
- Deep Learning 29: caffe入门学习
1.跑教程:深度学习(六)caffe入门学习,上面有比较好的注释 .prototxt文件:网络结构文件 solver.prototxt:网络求解文件 net: "examples/mnist ...
- YoyoGo微服务框架入门系列-基本概念
前言 Github开源:github.com/yoyofx/yoyogo 还请多多Star 之前简单介绍了YoyoGo微服务框架的基本内容,接下来了解下框架中的基本概念. 从一个简单Web服务Demo ...
- Spring Cloud (十五)Stream 入门、主要概念与自定义消息发送与接收
前言 不写随笔的日子仿佛就是什么都没有产出一般--上节说到要学Spring Cloud Bus,这里发现按照官方文档的顺序反而会更好些,因为不必去后边的章节去为当前章节去打基础,所以我们先学习Spri ...
- Linux快速入门01-基础概念
4年多前,刚到上海时报过一个关于Oracle的培训班,在那里接触到了Linux,不过一直都没真正去试着使用它.现在经过慢慢的成长,越来越觉得,Linux是每一个服务端工程师必须掌握的系统,即使是现在最 ...
- Html与CSS快速入门01-基础概念
Web前端技术一直是自己的薄弱环节,经常为了调节一个简单的样式花费大量的时间.最近趁着在做前端部分的开发,果断把这部分知识成体系的恶补一下.内容相对都比较简单,很类似工具手册的学习,但目标是熟练掌握. ...
随机推荐
- 1.5V转3.3V升压电路图和1.5V转3.3V的电源芯片
1.5V转3.3V的电路图需要材料:PW5100芯片,2个贴片电容,1个贴片电感.即可组成一个DC-DC同步升压高效率电路图,可提供稳定的3.3V输出电压. 1.5V转3.3V的电源芯片 1.5V转3 ...
- 【Android】报错 Please ensure Hyper-V is disabled in Windows Features, or refer to the Intel HAXM 的解决方案
参考文章 实测华为锐龙本(adm yes)安装Android avd虚拟机教程 环境 Android Studio 3.6; Windows 1909; AMD Ryzen 4800U with Ra ...
- jmeter跳过验证码登录配置:通过手动添加 Cookie 跳过带验证码的登录接口
目录 一.基本配置 二.HTTP请求默认值 三.HTTP信息头管理器 四.HTTP Cookie管理器 五.线程组下接口设置 一.基本配置 二.HTTP请求默认值 (1)jmeter的设置: (2)设 ...
- fiddler常用过滤
一.过滤器 过滤这块集中在request栏目的Filter部分,可以根据自己的需要过滤掉不需要的,里面的每个模块都可以设置,这里只说常用的和注意点. 1.假如我只关心某个域名下的抓包,这时可以利用fi ...
- GDB查看内存命令(x命令) 用gdb查看指定地址的内存内容
GDB查看内存命令(x命令) - super119 - 博客园 https://www.cnblogs.com/super119/archive/2011/11/18/2254382.html 可以使 ...
- WireGuard 教程:使用 DNS-SD 进行 NAT-to-NAT 穿透
原文链接:https://fuckcloudnative.io/posts/wireguard-endpoint-discovery-nat-traversal/ WireGuard 是由 Jason ...
- EasyExcel导出小结:动态标题、标题格式、相同值合并
1. 实列相关依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel& ...
- 六:SpringBoot-集成Druid连接池,配置监控界面
SpringBoot-集成Druid连接池,配置监控界面 1.Druid连接池 1.1 Druid特点 2.SpringBoot整合Druid 2.1 引入核心依赖 2.2 数据源配置文件 2.3 核 ...
- 将字符串进行md5加密
import java.security.MessageDigest; public class MD5Tools { /** * 将字符串进行md5加密 */ public static Strin ...
- jvm系列五-java内存模型初览(1)
本文转载自:再有人问你Java内存模型是什么,就把这篇文章发给他. 网上有很多关于Java内存模型的文章,在<深入理解Java虚拟机>和<Java并发编程的艺术>等书中也都有关 ...