caffe 代码阅读笔记1
首先查看caffe.cpp里的train函数:
// Train / Finetune a model.
//训练,微调一个网络模型
int train() {
// google的glog库,检查--solver、--snapshot和--weight并输出消息;必须有指定solver,snapshot和weight两者指定其一;
CHECK_GT(FLAGS_solver.size(), ) << "Need a solver definition to train.";
CHECK(!FLAGS_snapshot.size() || !FLAGS_weights.size())
<< "Give a snapshot to resume training or weights to finetune "
"but not both."; caffe::SolverParameter solver_param; //实例化SolverParameter类,该类保存solver参数和相应的方法
caffe::ReadSolverParamsFromTextFileOrDie(FLAGS_solver, &solver_param); //将-solver指定solver.prototxt文件内容解析到solver_param中 // If the gpus flag is not provided, allow the mode and device to be set
// in the solver prototxt.
// 根据命令参数-gpu或者solver.prototxt提供的信息设置GPU
if (FLAGS_gpu.size() ==
&& solver_param.solver_mode() == caffe::SolverParameter_SolverMode_GPU) {
if (solver_param.has_device_id()) {
FLAGS_gpu = "" +
boost::lexical_cast<string>(solver_param.device_id());
} else { // Set default GPU if unspecified
FLAGS_gpu = "" + boost::lexical_cast<string>(); // boost::lexical_cast(0)是将数值0转换为字符串'“0”;
}
} // 多GPU下,将GPU编号存入vector容器中(get_gpus()函数通过FLAGS_gpu获取);
vector<int> gpus;
get_gpus(&gpus);
if (gpus.size() == ) {
LOG(INFO) << "Use CPU.";
Caffe::set_mode(Caffe::CPU);
} else {
ostringstream s;
for (int i = ; i < gpus.size(); ++i) {
s << (i ? ", " : "") << gpus[i];
}
LOG(INFO) << "Using GPUs " << s.str();
#ifndef CPU_ONLY
cudaDeviceProp device_prop;
for (int i = ; i < gpus.size(); ++i) {
cudaGetDeviceProperties(&device_prop, gpus[i]);
LOG(INFO) << "GPU " << gpus[i] << ": " << device_prop.name;
}
#endif
solver_param.set_device_id(gpus[]);
Caffe::SetDevice(gpus[]);
Caffe::set_mode(Caffe::GPU);
Caffe::set_solver_count(gpus.size());
} // 处理snapshot, stop or none信号,其声明在include/caffe/util/signal_Handler.h中;
// GetRequestedAction在caffe.cpp中,将‘stop’,‘snapshot’,‘none’转换为标准信号,即解析;
caffe::SignalHandler signal_handler(
GetRequestedAction(FLAGS_sigint_effect),
GetRequestedAction(FLAGS_sighup_effect)); //指向caffe::Solver对象,该对象由CreateSolver创建
shared_ptr<caffe::Solver<float> >
solver(caffe::SolverRegistry<float>::CreateSolver(solver_param)); //solver设置操作函数
solver->SetActionFunction(signal_handler.GetActionFunction()); // 从snapshot或caffemodel中恢复train;
if (FLAGS_snapshot.size()) {
LOG(INFO) << "Resuming from " << FLAGS_snapshot;
solver->Restore(FLAGS_snapshot.c_str());
} else if (FLAGS_weights.size()) {
CopyLayers(solver.get(), FLAGS_weights);
} if (gpus.size() > ) {
caffe::P2PSync<float> sync(solver, NULL, solver->param());
sync.Run(gpus);
} else {
LOG(INFO) << "Starting Optimization";
solver->Solve(); // // 初始化完成,开始优化网络
}
LOG(INFO) << "Optimization Done.";
return ;
}
RegisterBrewFunction(train);
// Test: score a model.
//测试网络模型
int test() {
CHECK_GT(FLAGS_model.size(), ) << "Need a model definition to score.";
CHECK_GT(FLAGS_weights.size(), ) << "Need model weights to score."; // Set device id and mode
vector<int> gpus;
get_gpus(&gpus);
if (gpus.size() != ) {
LOG(INFO) << "Use GPU with device ID " << gpus[];
#ifndef CPU_ONLY
cudaDeviceProp device_prop;
cudaGetDeviceProperties(&device_prop, gpus[]);
LOG(INFO) << "GPU device name: " << device_prop.name;
#endif
Caffe::SetDevice(gpus[]);
Caffe::set_mode(Caffe::GPU);
} else {
LOG(INFO) << "Use CPU.";
Caffe::set_mode(Caffe::CPU);
}
// Instantiate the caffe net.
//实例化caffe网络
Net<float> caffe_net(FLAGS_model, caffe::TEST);
caffe_net.CopyTrainedLayersFrom(FLAGS_weights);
LOG(INFO) << "Running for " << FLAGS_iterations << " iterations."; vector<int> test_score_output_id;
vector<float> test_score;
float loss = ;
for (int i = ; i < FLAGS_iterations; ++i) {
float iter_loss;
const vector<Blob<float>*>& result =
caffe_net.Forward(&iter_loss);
loss += iter_loss;
int idx = ;
for (int j = ; j < result.size(); ++j) {
const float* result_vec = result[j]->cpu_data();
for (int k = ; k < result[j]->count(); ++k, ++idx) {
const float score = result_vec[k];
if (i == ) {
test_score.push_back(score);
test_score_output_id.push_back(j);
} else {
test_score[idx] += score;
}
const std::string& output_name = caffe_net.blob_names()[
caffe_net.output_blob_indices()[j]];
LOG(INFO) << "Batch " << i << ", " << output_name << " = " << score;
}
}
}
loss /= FLAGS_iterations;
LOG(INFO) << "Loss: " << loss;
for (int i = ; i < test_score.size(); ++i) {
const std::string& output_name = caffe_net.blob_names()[
caffe_net.output_blob_indices()[test_score_output_id[i]]];
const float loss_weight = caffe_net.blob_loss_weights()[
caffe_net.output_blob_indices()[test_score_output_id[i]]];
std::ostringstream loss_msg_stream;
const float mean_score = test_score[i] / FLAGS_iterations;
if (loss_weight) {
loss_msg_stream << " (* " << loss_weight
<< " = " << loss_weight * mean_score << " loss)";
}
LOG(INFO) << output_name << " = " << mean_score << loss_msg_stream.str();
} return ;
}
RegisterBrewFunction(test);
caffe 代码阅读笔记1的更多相关文章
- Linux协议栈代码阅读笔记(二)网络接口的配置
Linux协议栈代码阅读笔记(二)网络接口的配置 (基于linux-2.6.11) (一)用户态通过C库函数ioctl进行网络接口的配置 例如,知名的ifconfig程序,就是通过C库函数sys_io ...
- [置顶] Linux协议栈代码阅读笔记(一)
Linux协议栈代码阅读笔记(一) (基于linux-2.6.21.7) (一)用户态通过诸如下面的C库函数访问协议栈服务 int socket(int domain, int type, int p ...
- [置顶] Linux协议栈代码阅读笔记(二)网络接口的配置
Linux协议栈代码阅读笔记(二)网络接口的配置 (基于linux-2.6.11) (一)用户态通过C库函数ioctl进行网络接口的配置 例如,知名的ifconfig程序,就是通过C库函数sys_io ...
- Linux-3.0.8 input subsystem代码阅读笔记
先乱序记录一下阅读Linux input subsystem代码的笔记. 在input device driver的入口代码部分,需要分配并初始化input device结构,内核提供的API是inp ...
- caffe卷积层代码阅读笔记
卷积的实现思想: 通过im2col将image转为一个matrix,将卷积操作转为矩阵乘法运算 通过调用GEMM完毕运算操作 以下两个图是我在知乎中发现的,"盗"用一下,确实非常好 ...
- Typecho 代码阅读笔记(二) - 数据库访问
转载请注明出处:http://blog.csdn.net/jh_zzz 这一块比较复杂,我还没有完全理解为什么要把 SQL 语句的组装搞这么复杂. 从一个普通皮肤页面开始 themes/default ...
- 第一行代码阅读笔记---AndroidMainfest.xml分析
按照这本书的指引,我随作者一样创建了一个安卓应用,开始了安卓开发的启程. 找到AndroidMainfest.xml这个文件,打开后看到了我创建的Activity在这个文件里被成功注册,文件内容如下: ...
- <<梦断代码>>阅读笔记三
看完了这最后三分之一的<梦断代码>,意味着这本软件行业的著作已经被我粗略地过了一遍. 在这最后三分之一的内容中,我深入了解了在大型软件项目的运作过程中存在的困难和艰辛.一个大型软件项目的成 ...
- <<梦断代码>>阅读笔记一
没有想象中的枯燥,甚至有些有趣.这就是我对<梦断代码>这一本书的第一印象.而且,作为一本面向程序员的书籍,作者很有意义地从第0章开始,那我也从第0章开始说.这第一次读书笔记是针对0~2 章 ...
随机推荐
- Android中播放本地SD卡中歌曲须要的加入的权限
使用MediaPlayer播放本地Mp3文件时.须要注意的訪问路径的问题以及訪问权限的问题. 1.訪问路径:/storage/emulated/0 此路径即为手机的根路径,能够通过下载ES文件浏览器软 ...
- oracle 存储过程循环体中的return和exit区别:
oracle 存储过程循环体中的return和exit区别: (1) return 跳出整个循环,终止该循环, 后面的不再执行. 相当于 Java 中的break; (2) exit ...
- blkblock工具1
http://www.ibm.com/developerworks/cn/linux/l-cn-perf1/ http://blog.chinaunix.net/uid-24774106-id-409 ...
- shell中的括号(小括号,中括号,大括号)及单引号、 双引号,反引号(``)
一.小括号,园括号() 1.单小括号 () ①命令组.括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用.括号中多个命令之间用分号隔开,最后一个命令可以没有分号, ...
- Swift之沙盒与数据存储
应用沙盒结构分析 1.应用程序包:包含了所有的资源文件和可执行文件 2.Documents:保存应用运行时生成的需要持久化的数据,iTunes同步设备时会备份该目录 3.tmp:保存应用运行时所需要的 ...
- C#程序集系列08,设置程序集版本
区别一个程序集,不仅仅是程序集名称,还包括程序集版本.程序集公匙.程序集文化等,本篇体验通过界面和编码设置程序集版本. □ 通过Visual Studio设置程序集版本 →右键项目,选择"属 ...
- ArcEngine 连接sql server sde
前言 本想在soe中进行sde for sqlserver数据获取.由于soe的调试不方便,为了测试的简便,先在桌面上写了个arcengine连接sde for sqlserver的程序,但是本以为是 ...
- Objective-C:NSDectionary字典的常见操作
NSDectionary字典:它是一个存储键值的容器,每一个键key都对应着一个值value,可以通过键key一次性找到目标值value,这是一个比较好的存储器,相比于数组而言,它明显提高了查询效率. ...
- Sublime Text2格式化HMTL/CSS/JS插件HTML-CSS-JS Prettify
之前格式化用过JSFormat,今天在GitHub发现了一个比较好的插件HTML-CSS-JS Prettify,具体的地址https://github.com/victorporof/Sublime ...
- Android中Dialog对话框的调用及监听
Android中经常会需要在Android界面上弹出一些对话框提示用户,比如App的退出的时候都会有各种框来挽留你的心,支付宝的时候输入密码的密码框,非常常见及其实用的功能,类似于JS中的alter, ...