Caffe 实战:Brewing ImageNet——从数据准备到训练 CaffeNet 的完整配方 📅 发布时间:2026/9/19 8:40:18 👁 浏览次数: Caffe 实战Brewing ImageNet——从数据准备到训练 CaffeNet 的完整配方【免费下载链接】caffeCaffe: a fast open framework for deep learning.项目地址: https://gitcode.com/gh_mirrors/ca/caffeCaffe 官方仓库中的 ImageNet 教程examples/imagenet/readme.md以 Brewing ImageNet 为题给出了一条从零开始、在自己的数据上训练分类网络的完整路径数据整理、生成 LMDB、计算图像均值、编写网络与求解器定义、启动训练以及从快照恢复训练。本文以该教程为核心骨架结合仓库中的实际脚本、prototxt 配置与工具源码逐项展开读完你不仅能按步骤跑通 CaffeNet 在 ILSVRC12 上的训练还能理解每一份配置和每条命令背后的实现原理并把它迁移到自己的数据集上。教程目标与适用前提这篇指南的定位是让你准备好在自己数据上训练自己的模型。如果你并不想亲自训练而只是想直接使用一个已在 ImageNet 上训练好的模型仓库提供了按本教程流程训练得到的 CaffeNet 模型详见 model_zoo——毕竟训练耗能巨大直接复用是更环保的选择。教程默认的数据集是 ILSVRC12 挑战赛数据集但整套流程同样适用于完整的 ImageNet 乃至任意图片分类数据无非是需要更多磁盘空间和稍长的训练时间。需要特别说明两点前提教程中所有路径与命令默认都在 Caffe 仓库根目录下执行教程假设你已经自行下载好 ImageNet 的训练集与验证集并按如下形式存放在磁盘上/path/to/imagenet/train/n01440764/n01440764_10026.JPEG /path/to/imagenet/val/ILSVRC2012_val_00000001.JPEG第一步数据准备下载辅助数据正式训练前需要准备一批辅助数据通过脚本一键下载./data/ilsvrc12/get_ilsvrc12_aux.sh注意当前仓库中的脚本文件名为data/ilsvrc12/get_ilsvrc_aux.sh其内容用wget -c下载caffe_ilsvrc12.tar.gz并解压包含均值 binaryproto、synset 名称与 id 映射、训练/验证划分文件等。如果你手上的版本提示文件不存在请以仓库实际文件名为准。辅助数据中最重要的两个文本文件是train.txt与val.txt它们逐行列出了所有图片的相对路径与标签是构建 LMDB 时的输入清单。这里有一个容易踩坑的细节教程使用的标签索引与 ILSVRC devkit 不同——它把 synset 名称按 ASCII 顺序排序后再依次编号为 0 到 999。synset 与类别名称的对应关系可以在synset_words.txt中查到。可选提前缩放图像到 256×256教程默认不会显式做图像缩放原因是集群环境下用 mapreduce 等方式并行缩放更高效。如果你希望流程简单也可以在命令行里直接用 ImageMagick 逐张处理for name in /path/to/imagenet/val/*.JPEG; do convert -resize 256x256\! $name $name done注意256x256\!中的!表示强制拉伸到精确尺寸不等比。如果希望保留宽高比可去掉!。用 create_imagenet.sh 生成 LMDB查看 examples/imagenet/create_imagenet.sh按需修改两个关键变量TRAIN_DATA_ROOT/path/to/imagenet/train/VAL_DATA_ROOT/path/to/imagenet/val/如果此前没有提前缩放图像把脚本中的RESIZEtrue打开对应RESIZE_HEIGHT256、RESIZE_WIDTH256如果已经缩放完毕保持RESIZEfalse对应宽高均为 0即不缩放。脚本对两个路径做了目录存在性检查路径配置错误时会给出明确提示并退出。然后直接执行./examples/imagenet/create_imagenet.sh脚本内部依次调用两次convert_imageset第一次生成训练 LMDB第二次生成验证 LMDB核心命令形如GLOG_logtostderr1 build/tools/convert_imageset \ --resize_height$RESIZE_HEIGHT \ --resize_width$RESIZE_WIDTH \ --shuffle \ $TRAIN_DATA_ROOT \ data/ilsvrc12/train.txt \ examples/imagenet/ilsvrc12_train_lmdbGLOG_logtostderr1只是把日志直接输出到终端便于检查可安全忽略。教程特别提醒执行前examples/imagenet/ilsvrc12_train_leveldb与ilsvrc12_val_leveldb当前脚本生成的是ilsvrc12_train_lmdb/ilsvrc12_val_lmdb不能已经存在脚本会负责创建它们。convert_imageset 的可用参数结合 tools/convert_imageset.cpp 中的命令行定义convert_imageset还支持以下开关DEFINE_*声明位于该文件约 31–43 行参数类型默认值作用--grayboolfalse是否按灰度图读取并存储通道数变为 1--shuffleboolfalse是否随机打乱样本顺序再写入数据库--backendstringlmdb输出数据库类型可选lmdb或leveldb--resize_width/--resize_heightint320图像缩放目标尺寸为 0 表示不缩放--check_sizeboolfalse是否校验所有图片尺寸一致--encodedboolfalse是否以编码形式如 JPEG 原样存储图像数据而非解码后的像素--encode_typestring与--encoded配合指定编码类型教程原稿写作时数据库还是 LevelDB因此正文提到创建 leveldbs当前仓库的脚本默认产出 LMDB网络配置中data_param.backend也统一使用LMDB这一点在后文网络定义中可以看到。第二步计算图像均值模型要求从每张图中减去图像均值因此需要先算出均值。tools/compute_image_mean.cpp实现了这一功能——教程还顺带提醒如果你想熟悉 Caffe 中 protocol buffers、leveldbs、日志等多个组件的配合方式这个工具本身就是很好的阅读样本。一条命令即可完成均值计算./examples/imagenet/make_imagenet_mean.sh查看 examples/imagenet/make_imagenet_mean.sh 可以看到它执行的实质是build/tools/compute_image_mean examples/imagenet/ilsvrc12_train_lmdb \ data/ilsvrc12/imagenet_mean.binaryproto即把训练 LMDB 的逐像素均值统计结果写成data/ilsvrc12/imagenet_mean.binaryproto供后面的网络定义引用。第三步模型定义本教程复现的是 Krizhevsky、Sutskever 与 Hinton 在 NIPS 2012 论文中首次提出的经典网络结构AlexNetCaffe 中的这一参考实现被命名为CaffeNet。网络定义在 models/bvlc_reference_caffenet/train_val.prototxt。如果你在前面步骤中偏离了本教程约定的路径记得同步修改 prototxt 中对应的路径字段。include 段一份文件定义两套网络仔细看train_val.prototxt会发现多处include { phase: TRAIN }或include { phase: TEST }段。它们让同一份文件能够表达两个高度关联的网络训练网络与测试网络。两套网络几乎完全相同共享除带 phase 标记层之外的所有层在本例中不同的只是输入层和一个输出层。输入层的差异训练网络的data层include { phase: TRAIN }从examples/imagenet/ilsvrc12_train_lmdb取数batch_size: 256且transform_param中mirror: true——即随机水平翻转做数据增强同时crop_size: 227从 256×256 图像中随机裁剪 227×227 区域测试网络的data层include { phase: TEST }从examples/imagenet/ilsvrc12_val_lmdb取数batch_size: 50mirror: false不做随机翻转。两层都通过mean_file: data/ilsvrc12/imagenet_mean.binaryproto引入上一步计算的均值。prototxt 中还注释了另一种更省事的做法用mean_value: 104 / 117 / 123直接指定每个通道的均值常数BGR 通道顺序从而免去均值文件。输出层的差异两套网络都输出softmax_loss层SoftmaxWithLoss训练时它既作为损失函数又作为反向传播的起点验证阶段它的损失仅被报告出来。测试网络还额外多一个accuracy层Accuracy带include { phase: TEST }用来报告测试集准确率。训练过程中Caffe 会按test_interval周期性实例化测试网络并在验证集上评测输出形如Test score #0: xxx Test score #1: xxx其中 score 0 是准确率未训练的网络初始值约为 1/1000 0.001score 1 是损失初始约为 7。CaffeNet 的逐层结构从 train_val.prototxt 可以看到完整的 CaffeNet 结构输入 227×227×3层名类型关键参数输出维度约conv1Convolution96 个 11×11 卷积核stride 455×55×96relu1 / pool1 / norm1ReLU / Pooling(MAX, 3×3, stride 2) / LRN(5, α1e-4, β0.75)—27×27×96conv2Convolution256 个 5×5 卷积核pad 2group 227×27×256relu2 / pool2 / norm2同上—13×13×256conv3Convolution384 个 3×3 卷积核pad 113×13×384conv4Convolution384 个 3×3 卷积核pad 1group 213×13×384conv5Convolution256 个 3×3 卷积核pad 1group 213×13×256relu5 / pool5ReLU / Pooling(MAX, 3×3, stride 2)—6×6×256fc6InnerProduct4096 输出后接 ReLU Dropout(0.5)4096fc7InnerProduct4096 输出后接 ReLU Dropout(0.5)4096fc8InnerProduct1000 输出对应 1000 类1000accuracy / lossAccuracy / SoftmaxWithLoss仅 accuracy 限定 TEST phase1值得注意的实现细节卷积层与全连接层都配置了两组param第一组对应权重lr_mult: 1, decay_mult: 1第二组对应偏置lr_mult: 2, decay_mult: 0——即偏置的学习率是权重的两倍且不做权重衰减。权重填充统一用高斯初始化gaussianstd 0.01 或 0.005偏置多数初始化为常数 1conv1 与 fc8 为 0。group: 2表示把输入通道分成两组分别卷积对应 AlexNet 的双 GPU 设计。这些细节直接关系到训练能否收敛也是迁移到自定义网络时最常需要调整的地方。求解器Solver规划教程在动手前先做出一份训练计划并把它实现在 models/bvlc_reference_caffenet/solver.prototxt 中计划对应配置项值每批 256 张共 450,000 次迭代约 90 epochsbatch_size在 net 中/max_iter256 / 450000每 1,000 次迭代在验证集上测试一次test_iter/test_interval1000 / 1000初始学习率 0.01每 100,000 次迭代约 20 epochs衰减一次base_lr/lr_policy/gamma/stepsize0.01 / step / 0.1 / 100000每 20 次迭代显示一次信息display20动量 0.9、权重衰减 0.0005momentum/weight_decay0.9 / 0.0005每 10,000 次迭代保存一次快照snapshot/snapshot_prefix10000 /models/bvlc_reference_caffenet/caffenet_train使用 GPU 训练solver_modeGPUsolver.prototxt的完整内容即上述字段的逐一映射net: models/bvlc_reference_caffenet/train_val.prototxt。注意test_iter: 1000与测试batch_size: 50相乘正好覆盖 50,000 张验证图。第四步训练 ImageNet一切就绪启动训练./build/tools/caffe train --solvermodels/bvlc_reference_caffenet/solver.prototxt仓库也提供了对应的便捷脚本 examples/imagenet/train_caffenet.sh其内部即执行上述命令并把额外参数透传给caffe train$。然后等待即可。关于训练速度按教程在 K40 上的实测数据每 20 次迭代约耗时 26.5 秒K20 上约 36 秒折合单张图像完整 forward-backward 约 5.2 ms其中前向约 2 ms、其余为反向。如果你想拆分统计计算耗时可以运行./build/tools/caffe time --modelmodels/bvlc_reference_caffenet/train_val.prototxtcaffe time会逐层报告前向与反向的耗时是分析性能瓶颈的常用工具。需要说明的是上述数字是教程撰写时的特定硬件环境数据实际表现取决于你的 GPU 型号与驱动配置。第五步从快照恢复训练训练途中难免遇到断电、或者想奖励自己打会游戏的时刻。由于训练过程会定期保存快照随时可以从断点恢复./build/tools/caffe train \ --solvermodels/bvlc_reference_caffenet/solver.prototxt \ --snapshotmodels/bvlc_reference_caffenet/caffenet_train_iter_10000.solverstatecaffenet_train_iter_10000.solverstate是求解器状态快照保存了恢复训练所需的全部信息网络参数权重、学习率调度状态、动量历史等因此可以精确还原当时的求解器状态。仓库中对应的便捷脚本是 examples/imagenet/resume_training.sh其示例快照名caffenet_train_10000.solverstate.h5对应 HDF5 快照格式具体文件名以你实际训练产生的快照为准。训练之后部署与继续探索训练完成后得到的就是可用于推理的 CaffeNet 模型。仓库同时提供了去掉数据层、以Input层接 227×227×3 输入的部署定义 models/bvlc_reference_caffenet/deploy.prototxt供加载权重后做前向推理使用其中input_param的 batch 维度 10 可按需修改。教程还推荐了后续实践用 Python 接口对 ImageNet 图片进行分类对应的入门示例可参考 examples/00-classification.ipynb。教程的结语也值得重申自 ILSVRC 2012 以来研究者们通过改变网络结构、微调各类参数来适配新数据与新任务而 Caffe 的价值恰恰在于——通过简单地编写不同的 prototxt 文件你就能自由探索不同的网络结构选择。这正是本教程想传递的核心能力数据管线、网络描述与求解策略三者解耦让改写配置而非改写代码成为日常实验的基本姿势。【免费下载链接】caffeCaffe: a fast open framework for deep learning.项目地址: https://gitcode.com/gh_mirrors/ca/caffe创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考