smooth_L1_loss_layer.cu解读 caffe源码初认识
.cpp是cpu上运行的代码,.cu是gpu上运行的代码。
这是smooth_L1_loss_layer.cu的前向传播部分
#include "caffe/fast_rcnn_layers.hpp" namespace caffe { template <typename Dtype>
__global__ void SmoothL1Forward(const int n, const Dtype* in, Dtype* out) {
// f(x) = 0.5 * x^2 if |x| < 1
// |x| - 0.5 otherwise
CUDA_KERNEL_LOOP(index, n) {
Dtype val = in[index];
Dtype abs_val = abs(val);
if (abs_val < ) {
out[index] = 0.5 * val * val;
} else {
out[index] = abs_val - 0.5;
}
}
} template <typename Dtype>
void SmoothL1LossLayer<Dtype>::Forward_gpu(const vector<Blob<Dtype>*>& bottom,
const vector<Blob<Dtype>*>& top) {
int count = bottom[]->count();
caffe_gpu_sub(
count,
bottom[]->gpu_data(),
bottom[]->gpu_data(),
diff_.mutable_gpu_data()); // d := b0 - b1
if (has_weights_) {
caffe_gpu_mul(
count,
bottom[]->gpu_data(),
diff_.gpu_data(),
diff_.mutable_gpu_data()); // d := w * (b0 - b1)
}
SmoothL1Forward<Dtype><<<CAFFE_GET_BLOCKS(count), CAFFE_CUDA_NUM_THREADS>>>(
count, diff_.gpu_data(), errors_.mutable_gpu_data());
CUDA_POST_KERNEL_CHECK; Dtype loss;
caffe_gpu_asum(count, errors_.gpu_data(), &loss);
top[]->mutable_cpu_data()[] = loss / bottom[]->num(); 注意:这里是bottom[0]->num(),不是bottom[0]->count()
}
blob的主要变量:
shared_ptr<SyncedMemory> data_;
shared_ptr<SyncedMemory> diff_;
vector<int> shape_;
int count_;
int capacity_;
blob只是一个基本的数据结构,因此内部的变量相对较少,首先是data_
指针,指针类型是shared_ptr,属于boost库的一个智能指针,这一部分主要用来申请内存存储data,data主要是正向传播的时候用的。同理,diff_
主要用来存储偏差,shape_
都是存储Blob的形状,count
表示Blob中的元素个数,也就是个数*通道数*高度*宽度
,capacity
表示当前的元素个数,因为Blob可能会reshape。count是一个迭代期参与的图片个数。带data的里面存储的是激活值和W、b,diff中存储的是残差和dW、db。
blob中除了数据成员之外,也有很多用于操作数据的函数成员,下面就说几个比较重要的:
void Blob<Dtype>::Reshape():这个函数是在原来分配的内存不够的情况下重新分配内存。
const Dtype* Blob<Dtype>::cpu_data():这个是获取Blob结构体中的data_数据的指针,同时限制不能对返回的指针指向的内容进行更改。
const Dtype* Blob<Dtype>::cpu_diff():这个是获取Blob结构体中的diff_数据的指针,同时限制不能对返回的指针指向的内容进行更改。
Dtype* Blob<Dtype>::mutable_cpu_data():获取Blob结构体中的data_数据的指针,同时可以对指针指向的内容更改。
Dtype* Blob<Dtype>::mutable_cpu_diff():获取Blob结构体中的diff_数据的指针,同时可以对指针指向的内容更改。
void Blob<Dtype>::ShareData(const Blob& other):让其他Blob的data_数据和当前Blob共享。
void Blob<Dtype>::ShareDiff(const Blob& other):让其他Blob的diff_和当前的Blob共享。
blob类里面有重载很多个count()
函数,主要还是为了统计blob的容量(volume),或者是某一片(slice),从某个axis到具体某个axis的shape乘积。
inline int count(int start_axis, int end_axis)
int count = bottom[0]->count(); count()没带参数,计算的是bottom[0]这个输入blob所有的元素个数。这里就是计算一个迭代期的所有图片的所有通道的所有坐标点形成的blob数据结构元素的个数。
top[0]->mutable_cpu_data()[0] = loss / bottom[0]->num(); num()是计算一个迭代期参与的所有图片的个数。这里就是求一个迭代期所有几张图片的平均loss。
caffe_gpu_asum(count, errors_.gpu_data(), &loss); caffe_gpu_asum是对向量进行L1范数计算,实际上就是对向量求其每个元素绝对值的和。第一个参数是要计算的元素的个数。
caffe_gpu_sub(
count,
bottom[]->gpu_data(),
bottom[]->gpu_data(),
diff_.mutable_gpu_data()); // d := b0 - b1
if (has_weights_) {
caffe_gpu_mul(
count,
bottom[]->gpu_data(),
diff_.gpu_data(),
diff_.mutable_gpu_data()); // d := w * (b0 - b1)
}
caffe_gpu_sub,caffe_gpu_mul:这两个函数分别实现element-wise(即点乘,每个矩阵对应元素相乘)的乘减(y[i] = a[i] * - b[i])。第一个参数是要计算的元素个数。
总结; smooth_L1_loss_layer的loss计算是将所有对应元素(某张图片,某个通道的对应坐标)相减,判断绝对值是否小于1然后各个元素分别进行smooth_L1(x)这个函数的处理,各个元素都有一个loss,然后把所有的loss相加除以图片数,就得到每张图片box_loss的值。
loss的两个输入是1x84维的向量(fast中是这样,faster中的rpn是36*w*h),这个向量表示21类的dx,dy,dh,dw。count数出所有的个数,然后两个输入相对应的每一个进行这个计算,计算出84个loss,再对84个loss求和。当然这是单个图片,如果batch有多个图片,对多个图片loss求平均。
fast中使用的smoothL1和faster中使用的smoothL1有一点差别,但不大。faster中除了在rpn使用smoothl1,还要在fast那部分使用,所以faster中的smoothl1应该是兼容的。
smooth_L1_loss_layer.cu解读 caffe源码初认识的更多相关文章
- caffe源码学习之Proto数据格式【1】
前言: 由于业务需要,接触caffe已经有接近半年,一直忙着阅读各种论文,重现大大小小的模型. 期间也总结过一些caffe源码学习笔记,断断续续,这次打算系统的记录一下caffe源码学习笔记,巩固一下 ...
- RxJava系列6(从微观角度解读RxJava源码)
RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...
- 入口开始,解读Vue源码(一)-- 造物创世
Why? 网上现有的Vue源码解析文章一搜一大批,但是为什么我还要去做这样的事情呢?因为觉得纸上得来终觉浅,绝知此事要躬行. 然后平时的项目也主要是Vue,在使用Vue的过程中,也对其一些约定产生了一 ...
- Caffe源码理解2:SyncedMemory CPU和GPU间的数据同步
目录 写在前面 成员变量的含义及作用 构造与析构 内存同步管理 参考 博客:blog.shinelee.me | 博客园 | CSDN 写在前面 在Caffe源码理解1中介绍了Blob类,其中的数据成 ...
- caffe源码阅读
参考网址:https://www.cnblogs.com/louyihang-loves-baiyan/p/5149628.html 1.caffe代码层次熟悉blob,layer,net,solve ...
- Derek解读Bytom源码-持久化存储LevelDB
作者:Derek 简介 Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBlockchain/bytom ...
- Caffe源码中syncedmem文件分析
Caffe源码(caffe version:09868ac , date: 2015.08.15)中有一些重要文件,这里介绍下syncedmem文件. 1. include文件: (1).& ...
- Caffe源码中math_functions文件分析
Caffe源码(caffe version:09868ac , date: 2015.08.15)中有一些重要文件,这里介绍下math_functions文件. 1. include文件: ...
- Caffe源码中caffe.proto文件分析
Caffe源码(caffe version:09868ac , date: 2015.08.15)中有一些重要文件,这里介绍下caffe.proto文件. 在src/caffe/proto目录下有一个 ...
随机推荐
- 352. Data Stream as Disjoint Intervals (TreeMap, lambda, heapq)
Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen ...
- Web项目开发介绍及实战项目介绍
引言 本系列课程我们将学些Golang语言中的Web开发框架Iris的相关知识和用法.通过本系列视频课程,大家能够从零到一经历一个完整项目的开发,并在课程中了解实战项目开发的流程和项目设涉及的各个模块 ...
- 洛谷P2814 家谱
P2814 家谱 题目背景 现代的人对于本家族血统越来越感兴趣. 题目描述 给出充足的父子关系,请你编写程序找到某个人的最早的祖先. 输入输出格式 输入格式: 输入由多行组成,首先是一系列有关父子关系 ...
- FISCO BCOS WorkShop | 区块链开发特训营,开课啦!
FISCO BCOS是完全开源的联盟区块链底层技术平台,由金融区块链合作联盟(深圳)(简称金链盟)成立开源工作组通力打造.开源工作组成员包括博彦科技.华为.深证通.神州数码.四方精创.腾讯.微众银行. ...
- linux grep (转)
常用用法 [root@www ~]# grep [-acinv] [--color=auto] '搜寻字符串' filename 选项与参数: -a :将 binary 文件以 text 文件的方式搜 ...
- net core 2.0 web api + Identity Server 4 + angular 5
net core 2.0 web api + Identity Server 4 + angular 5前台使用angular 5, 后台是asp.net core 2.0 web api + ide ...
- 安卓第四次作业——简单校园二手交易APP
一.项目团队 团队成员 姓名:汤文涛 学号:1600802129 班级:计算机164班 博客地址:https://www.cnblogs.com/taotao01/ 姓名:杨圣豪 学号:1600802 ...
- 056 Merge Intervals 合并区间
给出一个区间的集合, 请合并所有重叠的区间.示例:给出 [1,3],[2,6],[8,10],[15,18],返回 [1,6],[8,10],[15,18].详见:https://leetcode.c ...
- airodump-ng 界面参数比较详细的解释
BSSID: AP(access point)的MAC地址,,如果在client section中BSSID显示为"not associated" ,那么意味着该客户端没有和AP连 ...
- replcation set (复制集)配置过程 --mongodb
一,配置规划 复制集原理(基本构成是1主2从的结构,自带互相监控投票机制(Raft(MongoDB) Paxos(mysql MGR 用的是变种))如果发生主库宕机,复制集内部会进行投票选举,选择一 ...