Caffe中crop_layer层的理解和使用
2016-10-23 11:03
302 查看
前段时间一直忙着找工作博客已经很久没有写了,看到了很多人的留言没有回复,在这里和大家说声抱歉。Caffe也是很久没有使用了,前天突然发现Caffe更新了,出现了一些新层,于是就挑着在论文中使用到的新层研究了一下。
本片博客主要是说明crop_layer(我叫他剪裁层)的理解和使用。在此申明博客中的内容部分引用其他博客我会给出连接地址,大家可以详细看原博客。
1、Crop_layer有什么作用呢?
Crop_layer的主要作用就是进行剪裁。Caffe中的数据是以 blobs形式存在的,blob是四维数据,即 (Batch size, number of Chennels, Height, Width)=(N, C, H, W)。---(0,1,2,3)。
Crop层的输入(bottom blobs)有两个,让我们假设为A和B,输出(top)为C。
(1)A是要进行裁切的bottom,他的size是
(20,50,512,512);
(2)B是剪裁的参考输入,它的size是(20,10,256,256);
(3)C是输出,由A剪裁而来,那么他的size是(20,10,256,256)。
Crop_layer里有两个重要的参数axis,offsets。axis决定从哪个轴开始剪裁,offsets决定A的偏移,从偏移位置开始剪裁,剪裁的长度就是B中对应轴的长度。举例如下:
(1)axis=1,offset=(25,128,128)
(2)corp operation:C=A[:,25:25+B.shape[1],128:128+B.shape[2],128:128+B.shape[3]].
以上内容出自http://www.cnblogs.com/kunyuanjushi/p/5937083.html
2、Crop_layer在那篇论文里具体应用了呢?
看过Fully Convolutional Networks for Semantic Segmentation 这篇论文的同学应该有印象。没错我也是研究这篇论文时,发现作者提供的网络配置文件里使用了Crop_layer层。
那么他在这篇论文里有什么作用呢?可参考:https://www.zhihu.com/question/48260036
主要是全卷积时原始图像加了pad,比原图大一些,最后要把pad剪裁掉。
3、重磅来袭,源码解读。
首先,给出源码中重要的部分crop_copy函数
void CropLayer<Dtype>::crop_copy(const vector<Blob<Dtype>*>& bottom,// bottom[0]
const vector<Blob<Dtype>*>& top,
const vector<int>& offsets,
vector<int> indices,//初始化时都是0
int cur_dim,//默认从0开始
const Dtype* src_data,
Dtype* dest_data,
bool is_forward) {
if (cur_dim + 1 < top[0]->num_axes()) {
// We are not yet at the final dimension, call copy recursively
// 还没到最后一个维度,递归调用crop_copy()
for (int i = 0; i < top[0]->shape(cur_dim); ++i) {
indices[cur_dim] = i;
crop_copy(bottom, top, offsets, indices, cur_dim+1,
src_data, dest_data, is_forward);
}
} else {
// We are at the last dimensions, which is stored continously(连续) in memory
for (int i = 0; i < top[0]->shape(cur_dim); ++i) {
// prepare index vector reduced(red) and with offsets(off) 准备索引向量
std::vector<int> ind_red(cur_dim, 0); //顶层的偏移向量
std::vector<int> ind_off(cur_dim+1, 0);//底层的偏移向量
for (int j = 0; j < cur_dim; ++j) {//注意这里的cur_dim=3,因此j最大为2,ind_red[0]初始化时是0
ind_red[j] = indices[j];
ind_off[j] = indices[j] + offsets[j];
}
ind_off[cur_dim] = offsets[cur_dim];//ind_off最后一维
// do the copy 复制操作
if (is_forward) {
caffe_copy(top[0]->shape(cur_dim),
src_data + bottom[0]->offset(ind_off),
dest_data + top[0]->offset(ind_red));
} else {
// in the backwards pass the src_data is top_diff
// and the dest_data is bottom_diff
// 后向过程src_data是top_diff,dest_data是bottom_diff
caffe_copy(top[0]->shape(cur_dim),
src_data + top[0]->offset(ind_red),
dest_data + bottom[0]->offset(ind_off));
}
}
}
}由于解释起来较为复杂,特把我的笔记贴出,如有错误望留言告知
OK!到这里基本就完了。欢迎大家留言讨论!
本片博客主要是说明crop_layer(我叫他剪裁层)的理解和使用。在此申明博客中的内容部分引用其他博客我会给出连接地址,大家可以详细看原博客。
1、Crop_layer有什么作用呢?
Crop_layer的主要作用就是进行剪裁。Caffe中的数据是以 blobs形式存在的,blob是四维数据,即 (Batch size, number of Chennels, Height, Width)=(N, C, H, W)。---(0,1,2,3)。
Crop层的输入(bottom blobs)有两个,让我们假设为A和B,输出(top)为C。
(1)A是要进行裁切的bottom,他的size是
(20,50,512,512);
(2)B是剪裁的参考输入,它的size是(20,10,256,256);
(3)C是输出,由A剪裁而来,那么他的size是(20,10,256,256)。
Crop_layer里有两个重要的参数axis,offsets。axis决定从哪个轴开始剪裁,offsets决定A的偏移,从偏移位置开始剪裁,剪裁的长度就是B中对应轴的长度。举例如下:
(1)axis=1,offset=(25,128,128)
(2)corp operation:C=A[:,25:25+B.shape[1],128:128+B.shape[2],128:128+B.shape[3]].
以上内容出自http://www.cnblogs.com/kunyuanjushi/p/5937083.html
2、Crop_layer在那篇论文里具体应用了呢?
看过Fully Convolutional Networks for Semantic Segmentation 这篇论文的同学应该有印象。没错我也是研究这篇论文时,发现作者提供的网络配置文件里使用了Crop_layer层。
那么他在这篇论文里有什么作用呢?可参考:https://www.zhihu.com/question/48260036
主要是全卷积时原始图像加了pad,比原图大一些,最后要把pad剪裁掉。
3、重磅来袭,源码解读。
首先,给出源码中重要的部分crop_copy函数
void CropLayer<Dtype>::crop_copy(const vector<Blob<Dtype>*>& bottom,// bottom[0]
const vector<Blob<Dtype>*>& top,
const vector<int>& offsets,
vector<int> indices,//初始化时都是0
int cur_dim,//默认从0开始
const Dtype* src_data,
Dtype* dest_data,
bool is_forward) {
if (cur_dim + 1 < top[0]->num_axes()) {
// We are not yet at the final dimension, call copy recursively
// 还没到最后一个维度,递归调用crop_copy()
for (int i = 0; i < top[0]->shape(cur_dim); ++i) {
indices[cur_dim] = i;
crop_copy(bottom, top, offsets, indices, cur_dim+1,
src_data, dest_data, is_forward);
}
} else {
// We are at the last dimensions, which is stored continously(连续) in memory
for (int i = 0; i < top[0]->shape(cur_dim); ++i) {
// prepare index vector reduced(red) and with offsets(off) 准备索引向量
std::vector<int> ind_red(cur_dim, 0); //顶层的偏移向量
std::vector<int> ind_off(cur_dim+1, 0);//底层的偏移向量
for (int j = 0; j < cur_dim; ++j) {//注意这里的cur_dim=3,因此j最大为2,ind_red[0]初始化时是0
ind_red[j] = indices[j];
ind_off[j] = indices[j] + offsets[j];
}
ind_off[cur_dim] = offsets[cur_dim];//ind_off最后一维
// do the copy 复制操作
if (is_forward) {
caffe_copy(top[0]->shape(cur_dim),
src_data + bottom[0]->offset(ind_off),
dest_data + top[0]->offset(ind_red));
} else {
// in the backwards pass the src_data is top_diff
// and the dest_data is bottom_diff
// 后向过程src_data是top_diff,dest_data是bottom_diff
caffe_copy(top[0]->shape(cur_dim),
src_data + top[0]->offset(ind_red),
dest_data + bottom[0]->offset(ind_off));
}
}
}
}由于解释起来较为复杂,特把我的笔记贴出,如有错误望留言告知
OK!到这里基本就完了。欢迎大家留言讨论!
相关文章推荐
- caffe中使用crop_size剪裁训练图片
- Caffe中的crop_layer层
- caffe中使用crop_size剪裁训练图片
- caffe中使用crop_size剪裁训练图片
- FCN网络中使用的caffe类型层汇总--Convolution/Deconvolution/Crop/Eltwise/SoftmaxWithLoss
- 理解和使用aix的日志系统
- [原创]面向对象理解·抽象类和派生类理解和使用
- 深入理解Display类的使用
- JSON 之我的理解跟使用
- 使用Hibernate的项目中对VO的理解(转)
- 使用Hibernate的项目中对VO的理解
- 委托的理解和使用
- 深入理解Canvas类的使用(一)
- 理解并使用ASP.NET的高级配置
- 网络基础知识讲座之七:理解和使用ICMP协议
- 对事件与委托的理解(1) 使用事件
- 使用Managed DirectX编写游戏----理解sample framework 之事件处理
- 如何正确的理解使用posix1提供的信号量
- 使用Hibernate的项目中对VO的理解
- SQL Server 索引结构及其使用(一)--深入浅出理解索引结构第1/4页