【Caffe代码解析】compute_image_mean
功能:
计算训练数据库的平均图像。
由于平均归一化训练图像会对结果有提升,所以Caffe里面,提供了一个可选项。
用法:
compute_image_mean [FLAGS] INPUT_DB [OUTPUT_FILE]\n”)
參数:INPUT_DB: 数据库
參数(可选):OUTPUT_FILE: 输出文件名称,不提供的话,不保存平均图像blob
实现方法:
数据源:求平均图像的方法是直接从数据库(LevelDB或者LMDB)里面直接读取出来的,而不是直接用图像数据库里面求出,意味着,必须先进行图像到数据库的转换后,才干求平均图像这一步。
接下来就是遍历KV数据库的每个值while (cursor->valid())
将每个数据值转换为Datum,datum.ParseFromString(cursor->value());
接着将Datum阶码到sum_blob
中。sum_blob
是一个num=1,channels=图像.channel,height=图像.height ,width=图像.width 的blob
累加:
sum_blob.set_data(i, sum_blob.data(i) + (uint8_t)data[i]);
最后求平均:
sum_blob.set_data(i, sum_blob.data(i) / count);
存在的问题:上述代码仅仅是先累加在处于数目求和,显然,假设须要求平均的图像的数目相当多的话,就有可能溢出(浮点溢出)。
最后,假设要求简单一点的话,也能够直接求每个通道的平均值。
源码://2015.06.04版本号
#include <stdint.h>
#include <algorithm>
#include <string>
#include <utility>
#include <vector>
#include "boost/scoped_ptr.hpp"
#include "gflags/gflags.h"
#include "glog/logging.h"
#include "caffe/proto/caffe.pb.h"
#include "caffe/util/db.hpp"
#include "caffe/util/io.hpp"
using namespace caffe; // NOLINT(build/namespaces)
using std::max;
using std::pair;
using boost::scoped_ptr;
DEFINE_string(backend, "lmdb",
"The backend {leveldb, lmdb} containing the images");
int main(int argc, char** argv) {
::google::InitGoogleLogging(argv[0]);
#ifndef GFLAGS_GFLAGS_H_
namespace gflags = google;
#endif
gflags::SetUsageMessage("Compute the mean_image of a set of images given by"
" a leveldb/lmdb\n"
"Usage:\n"
" compute_image_mean [FLAGS] INPUT_DB [OUTPUT_FILE]\n");
gflags::ParseCommandLineFlags(&argc, &argv, true);
if (argc < 2 || argc > 3) {
gflags::ShowUsageWithFlagsRestrict(argv[0], "tools/compute_image_mean");
return 1;
}
scoped_ptr<db::DB> db(db::GetDB(FLAGS_backend));
db->Open(argv[1], db::READ);
scoped_ptr<db::Cursor> cursor(db->NewCursor());
BlobProto sum_blob;
int count = 0;
// load first datum
Datum datum;
datum.ParseFromString(cursor->value());
if (DecodeDatumNative(&datum)) {
LOG(INFO) << "Decoding Datum";
}
sum_blob.set_num(1);
sum_blob.set_channels(datum.channels());
sum_blob.set_height(datum.height());
sum_blob.set_width(datum.width());
const int data_size = datum.channels() * datum.height() * datum.width();
int size_in_datum = std::max<int>(datum.data().size(),
datum.float_data_size());
for (int i = 0; i < size_in_datum; ++i) {
sum_blob.add_data(0.);
}
LOG(INFO) << "Starting Iteration";
while (cursor->valid()) {
Datum datum;
datum.ParseFromString(cursor->value());
DecodeDatumNative(&datum);
const std::string& data = datum.data();
size_in_datum = std::max<int>(datum.data().size(),
datum.float_data_size());
CHECK_EQ(size_in_datum, data_size) << "Incorrect data field size " <<
size_in_datum;
if (data.size() != 0) {
CHECK_EQ(data.size(), size_in_datum);
for (int i = 0; i < size_in_datum; ++i) {
sum_blob.set_data(i, sum_blob.data(i) + (uint8_t)data[i]);
}
} else {
CHECK_EQ(datum.float_data_size(), size_in_datum);
for (int i = 0; i < size_in_datum; ++i) {
sum_blob.set_data(i, sum_blob.data(i) +
static_cast<float>(datum.float_data(i)));
}
}
++count;
if (count % 10000 == 0) {
LOG(INFO) << "Processed " << count << " files.";
}
cursor->Next();
}
if (count % 10000 != 0) {
LOG(INFO) << "Processed " << count << " files.";
}
for (int i = 0; i < sum_blob.data_size(); ++i) {
sum_blob.set_data(i, sum_blob.data(i) / count);
}
// Write to disk
if (argc == 3) {
LOG(INFO) << "Write to " << argv[2];
WriteProtoToBinaryFile(sum_blob, argv[2]);
}
const int channels = sum_blob.channels();
const int dim = sum_blob.height() * sum_blob.width();
std::vector<float> mean_values(channels, 0.0);
LOG(INFO) << "Number of channels: " << channels;
for (int c = 0; c < channels; ++c) {
for (int i = 0; i < dim; ++i) {
mean_values[c] += sum_blob.data(dim * c + i);
}
LOG(INFO) << "mean_value channel [" << c << "]:" << mean_values[c] / dim;
}
return 0;
}
【Caffe代码解析】compute_image_mean的更多相关文章
- 【Caffe代码解析】Layer网络层
Layer 功能: 是全部的网络层的基类,当中.定义了一些通用的接口,比方前馈.反馈.reshape,setup等. #ifndef CAFFE_LAYER_H_ #define CAFFE_LAYE ...
- 【Caffe代码解析】Blob
主要功能: Blob 是Caffe作为传输数据的媒介,不管是网络权重參数,还是输入数据,都是转化为Blob数据结构来存储,网络,求解器等都是直接与此结构打交道的. 其直观的能够把它看成一个有4纬的结构 ...
- VBA常用代码解析
031 删除工作表中的空行 如果需要删除工作表中所有的空行,可以使用下面的代码. Sub DelBlankRow() DimrRow As Long DimLRow As Long Dimi As L ...
- [nRF51822] 12、基础实验代码解析大全 · 实验19 - PWM
一.PWM概述: PWM(Pulse Width Modulation):脉冲宽度调制技术,通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形. PWM 的几个基本概念: 1) 占空比:占空比是指 ...
- [nRF51822] 11、基础实验代码解析大全 · 实验16 - 内部FLASH读写
一.实验内容: 通过串口发送单个字符到NRF51822,NRF51822 接收到字符后将其写入到FLASH 的最后一页,之后将其读出并通过串口打印出数据. 二.nRF51822芯片内部flash知识 ...
- [nRF51822] 10、基础实验代码解析大全 · 实验15 - RTC
一.实验内容: 配置NRF51822 的RTC0 的TICK 频率为8Hz,COMPARE0 匹配事件触发周期为3 秒,并使能了TICK 和COMPARE0 中断. TICK 中断中驱动指示灯D1 翻 ...
- [nRF51822] 9、基础实验代码解析大全 · 实验12 - ADC
一.本实验ADC 配置 分辨率:10 位. 输入通道:5,即使用输入通道AIN5 检测电位器的电压. ADC 基准电压:1.2V. 二.NRF51822 ADC 管脚分布 NRF51822 的ADC ...
- java集合框架之java HashMap代码解析
java集合框架之java HashMap代码解析 文章Java集合框架综述后,具体集合类的代码,首先以既熟悉又陌生的HashMap开始. 源自http://www.codeceo.com/arti ...
- Kakfa揭秘 Day8 DirectKafkaStream代码解析
Kakfa揭秘 Day8 DirectKafkaStream代码解析 今天让我们进入SparkStreaming,看一下其中重要的Kafka模块DirectStream的具体实现. 构造Stream ...
随机推荐
- chardet的下载及安装
1.chardet下载地址 https://pypi.python.org/pypi/chardet/3.0.4#downloads 2.解压至安装路径 D:\Program Files (x86)\ ...
- sql server 学习分享
http://www.cnblogs.com/liu-chao-feng/p/6144872.html
- javascript学习笔记 - 引用类型 Function
五 Function类型 每个函数都时Function类型的实例.函数也是对象. 声明函数: function func_name () {} //javascript解析器会在程序执行时率先读取函数 ...
- Response.End报错
以下摘抄自博问:https://q.cnblogs.com/q/31506/ try catch中使用Response.End() 我在WebForm中用ajax发送请求到页面index. ...
- hibernate缓存机制【转】
一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数 ...
- 【Luogu】P2445动物园(最大流)
题目链接 题目本身还是比较水的吧……容易发现是最大流套上dinic跑一遍就好了,并不会超时. 比较不偷税的一点是关于某动物的所有目击报告都符合才能连边……qwqqwqqwq #include<c ...
- SVN改地址eclipse怎么同步
步骤有3 : 首先保证:Windows-> preservences->SVN的接口Client为 1.8以上的 1 ) 打开eclipse中SVN资源库 在Eclipse中选择Win ...
- uva 12723 概率dp
Dudu is a very starving possum. He currently stands in the first shelf of a fridge. This fridge isco ...
- 20深入理解C指针之---程序的栈和堆
一.程序在内存中的存储分段: 程序段主要包括:code段.data段.内核段.堆段和栈段 1.code段: 1).存储程序汇编后程序指令 2).此段中的数据是只读的 3).不能用于存储变量,可以存储常 ...
- 观察者模式在MVP中的应用
先简单写下观察者模式.观察者模式,又叫做发布-订阅模式.观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,是他们能够自动 ...