Caffe中im2col的实现解析
这里,我是将Caffe中im2col的解析过程直接拉了出来,使用C++进行了输出,方便理解。代码如下:
#include<iostream> using namespace std; bool is_a_ge_zero_and_a_lt_b(int a,int b)
{
if(a>= && a <b) return true;
return false;
} void im2col_cpu(const float* data_im, const int channels,
const int height, const int width, const int kernel_h, const int kernel_w,
const int pad_h, const int pad_w,
const int stride_h, const int stride_w,
const int dilation_h, const int dilation_w,
float* data_col) {
const int output_h = (height + * pad_h -
(dilation_h * (kernel_h - ) + )) / stride_h + ;
const int output_w = (width + * pad_w -
(dilation_w * (kernel_w - ) + )) / stride_w + ;
const int channel_size = height * width;
for (int channel = channels; channel--; data_im += channel_size) {
for (int kernel_row = ; kernel_row < kernel_h; kernel_row++) {
for (int kernel_col = ; kernel_col < kernel_w; kernel_col++) {
int input_row = -pad_h + kernel_row * dilation_h;
for (int output_rows = output_h; output_rows; output_rows--) {
if (!is_a_ge_zero_and_a_lt_b(input_row, height)) {
for (int output_cols = output_w; output_cols; output_cols--) {
*(data_col++) = ;
}
} else {
int input_col = -pad_w + kernel_col * dilation_w;
for (int output_col = output_w; output_col; output_col--) {
if (is_a_ge_zero_and_a_lt_b(input_col, width)) {
*(data_col++) = data_im[input_row * width + input_col];
} else {
*(data_col++) = ;
}
input_col += stride_w;
}
}
input_row += stride_h;
}
}
}
}
} int main()
{
float* data_im;
int height=;
int width=;
int kernel_h=;
int kernel_w=;
int pad_h=;
int pad_w=;
int stride_h=;
int stride_w=;
int dilation_h=;
int dilation_w=;
float* data_col;
int channels =;
const int output_h = (height + * pad_h -
(dilation_h * (kernel_h - ) + )) / stride_h + ;
const int output_w = (width + * pad_w -
(dilation_w * (kernel_w - ) + )) / stride_w + ;
data_im = new float[channels*height*width];
data_col = new float[channels*output_h*output_w*kernel_h*kernel_w]; //init input image data
for(int m=;m<channels;++m)
{
for(int i=;i<height;++i)
{
for(int j=;j<width;++j)
{
data_im[m*width*height+i*width+j] = m*width*height+ i*width +j;
cout <<data_im[m*width*height+i*width+j] <<' ';
}
cout <<endl;
}
} im2col_cpu(data_im, channels,
height,width, kernel_h, kernel_w,
pad_h, pad_w,
stride_h, stride_w,
dilation_h, dilation_w,
data_col);
cout <<channels<<endl;
cout <<output_h<<endl;
cout <<output_w<<endl;
cout <<kernel_h<<endl;
cout <<kernel_w<<endl;
// cout <<"error"<<endl;
for(int i=;i<kernel_w*kernel_h*channels;++i)
{
for(int j=;j<output_w*output_h;++j)
{
cout <<data_col[i*output_w*output_h+j]<<' ';
}
cout <<endl;
} return ;
}
多通道卷积的图像别人已经给过很多了,大家可以搜到的基本都来自于一篇。这里附上一个我自己的理解过程,和程序的输出是完全一致的

Caffe中im2col的实现解析的更多相关文章
- caffe代码阅读10:Caffe中卷积的实现细节(涉及到BaseConvolutionLayer、ConvolutionLayer、im2col等)-2016.4.3
一. 卷积层的作用简单介绍 卷积层是深度神经网络中的一个重要的层,该层实现了局部感受野.通过这样的局部感受野,能够有效地减少參数的数目. 我们将结合caffe来解说详细是怎样实现卷积层的前传和反传的. ...
- caffe中ConvolutionLayer的前向和反向传播解析及源码阅读
一.前向传播 在caffe中,卷积层做卷积的过程被转化成了由卷积核的参数组成的权重矩阵weights(简记为W)和feature map中的元素组成的输入矩阵(简记为Cin)的矩阵乘积W * Cin. ...
- CAFFE中训练与使用阶段网络设计的不同
神经网络中,我们通过最小化神经网络来训练网络,所以在训练时最后一层是损失函数层(LOSS), 在测试时我们通过准确率来评价该网络的优劣,因此最后一层是准确率层(ACCURACY). 但是当我们真正要使 ...
- caffe 中base_lr、weight_decay、lr_mult、decay_mult代表什么意思?
在机器学习或者模式识别中,会出现overfitting,而当网络逐渐overfitting时网络权值逐渐变大,因此,为了避免出现overfitting,会给误差函数添加一个惩罚项,常用的惩罚项是所有权 ...
- caffe 中 plot accuracy和loss, 并画出网络结构图
plot accuracy + loss 详情可见:http://www.2cto.com/kf/201612/575739.html 1. caffe保存训练输出到log 并绘制accuracy l ...
- .NET Core中的认证管理解析
.NET Core中的认证管理解析 0x00 问题来源 在新建.NET Core的Web项目时选择“使用个人用户账户”就可以创建一个带有用户和权限管理的项目,已经准备好了用户注册.登录等很多页面,也可 ...
- OS中atomic的实现解析
OS中atomic的实现解析 转自:http://my.oschina.net/majiage/blog/267409 摘要 atomic属性线程安全,会增加一定开销,但有些时候必须自定义ato ...
- AngularJS中的指令全面解析(转载)
说到AngularJS,我们首先想到的大概也就是双向数据绑定和指令系统了,这两者也是AngularJS中最为吸引人的地方.双向数据绑定呢,感觉没什么好说的,那么今天我们就来简单的讨论下AngularJ ...
- Java中的static关键字解析
Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...
随机推荐
- NAT(地址转换技术)详解
目录 NAT产生背景ip地址基础知识NAT技术的工作原理和特点静态NAT动态NATNAT重载(经常应用到实际中)NAT技术的优缺点优点缺点NAT穿越技术应用层网关(ALG)ALG的实际应用NAT技术的 ...
- MySQL使用order by field()自定义排序
MySQL的自定义排序和Oracle相比,要简单得多. 假设在表v_education的列schoolRecord中,有以下字段:'小学','初中','高中','专科','本科','硕士','博士'. ...
- FSCalendar使用和注意事项
相信大家项目中或多或少都有日历这一块的内容吧,公司作为教育行业的软件公司,当然也是一定有的. 最近被日历这一块的内容弄得很头疼啊,改来改去的,不过还是学到了很多东西,至少FSCalendar的使用基本 ...
- 认识Redis持久化
一:为什么需要持久化 因为Redis是一个完全使用内存来存储数据的数据库,如果机器突然断电.服务器重启或进程挂掉了等等原因,那么存储在Redis中的数据就会丢失,从而引起业务的损失.为了保证存储在内存 ...
- Unity* 实体组件系统 (ECS)、C# 作业系统和突发编译器入门
Unity* 中的全新 C# 作业系统和实体组件系统不仅可以让您轻松利用以前未使用的 CPU 资源,还可以帮助您更高效地运行所有游戏代码.然后,您可以使用这些额外的 CPU 资源来添加更多场景动态和沉 ...
- ServletContainerInitializer
在web容器启动时为提供给第三方组件机会做一些初始化的工作,例如注册servlet或者filtes等,servlet规范中通过ServletContainerInitializer实现此功能. 每个框 ...
- Linux C/C++基础——变量作用域
1.局部变量 局部变量也叫auto自动变量(auto可写可不写),一般情况下代码块{}内部定义的变量都是自动变量,它有如下特点: 只有当执行到这句语句时,系统才为这个变量分配空间 在一个函数内定义,只 ...
- filter方法常用过滤条件
#encoding: utf-8 from sqlalchemy import create_engine,Column,Integer,String,Float,func,and_,or_ from ...
- Elasticsearch-更新现有文档
ES-更新现有文档 ES的更新API允许发送文档所需要做的修改,而且API会返回一个答复,告知操作是否成功.更新流程如下 1. 检索现有的文档.为了使这步奏效,必须打开_source字段,否则ES并不 ...
- PTA(Basic Level)1042.字符统计
请编写程序,找出一段给定文字中出现最频繁的那个英文字母. 输入格式: 输入在一行中给出一个长度不超过 1000 的字符串.字符串由 ASCII 码表中任意可见字符及空格组成,至少包含 1 个英文字母, ...