.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应该是兼容的。

最新文章

  1. linux常用命令-帮助命令man,whatis,apropos,info,help
  2. 如何安装Oracle Instant Client
  3. 设置word里的代码格式,使之有底纹的效果
  4. wex5 教程 之 图文讲解 登陆,注册,页面跳转
  5. 随机步法A-Z
  6. C++实现顺序表
  7. java 错误:找不到或无法加载主类的解决办法
  8. 微软职位内部推荐-Senior NLP Scientist & Developer
  9. Ubutn14.04下caffeine工具不显示在工具栏中的问题
  10. Burp_用户名密码爆破
  11. Unity3d开发中与oc交互之类型转换
  12. Vue学习笔记5
  13. 【原创】运维基础之Docker(4)实用工具ctop
  14. Python用上锁和解锁 lock lock.acquire lock.release 模拟抢火车票
  15. Nginx优化文件编写
  16. JS 单体内置对象
  17. Python - 列联表的独立性检验(卡方检验)
  18. mysql limit 性能问题分析
  19. centos下升级git版本的操作记录
  20. 16 利用Zabbix完成windows监控

热门文章

  1. 反射学习:(System.Reflection)
  2. 2014-11-1 NOIP模拟赛2
  3. Java代码读取文件
  4. JavaScript进阶 - 第6章 事件响应,让网页交互
  5. ubuntu 16.04 单用户____修改忘记密码
  6. Django之ORM跨表操作
  7. Luogu P1955 [NOI2015]程序自动分析
  8. java-可逆加密算法
  9. D. Array Division
  10. MS SqlServer之Exec和EXEC SP_EXECUTESQL