Caffe源码导读(1):LRN层的实现

详解LRN(local response normalization--局部响应标准化)缓解过拟合 局部响应归一化层(Local Response Normalization) LRN全称为Local Response Normalization,即局部响应归一化层,LRN函数类似Dropout和数据增强作为relu激活函数之后防止数据过拟合而提出的一种处理方法。这个函数很少使用,基本上被类似Dropout这样的方法取代. 为什么要引入LRN层? 首先要引入一个神经生物学的概念:侧抑制(lateral inhibitio),即指被激活的神经元抑制相邻的神经元。归一化(normaliazation)的目的 阅读详情

LRN全称为Local Response Normalization,即局部响应归一化层,具体实现在CAFFE_ROOT/src/caffe/layers/lrn_layer.cpp和同一目录下lrn_layer.cu中。


该层需要参数有:

norm_region: 选择对相邻通道间归一化还是通道内空间区域归一化,默认为ACROSS_CHANNELS,即通道间归一化;

local_size:两种表示(1)通道间归一化时表示求和的通道数;(2)通道内归一化时表示求和区间的边长;默认值为5;

alpha:缩放因子(详细见后面),默认值为1;

beta:指数项(详细见后面), 默认值为5;


局部响应归一化层完成一种“临近抑制”操作,对局部输入区域进行归一化。


在通道间归一化模式中,局部区域范围在相邻通道间,但没有空间扩展(即尺寸为 local_size x 1 x 1);

在通道内归一化模式中,局部区域在空间上扩展,但只针对独立通道进行(即尺寸为 1 x local_size x local_size);

每个输入值都将除以Caffe源码导读(7):LRN层的实现0

其中 n 为局部尺寸大小local_size, alpha和beta前面已经定义。

求和将在当前值处于中间位置的局部区域内进行(如果有必要则进行补零)。


下面我们看Caffe代码如何实现。打开CAFFE_ROOT/include/caffe/vision_layers.hpp,从第242行开始看起:

  // Forward declare PoolingLayer and SplitLayer for use in LRNLayer.
template <typename Dtype> class PoolingLayer;
template <typename Dtype> class SplitLayer;


/**
 * @brief Normalize the input in a local region across or within feature maps.
 *
 * TODO(dox): thorough documentation for Forward, Backward, and proto params.
 */
template <typename Dtype>
class LRNLayer : public Layer<Dtype> {
 public:
  explicit LRNLayer(const LayerParameter& param)
      : Layer<Dtype>(param) {}
  virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
      vector<Blob<Dtype>*>* top);
  virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
      vector<Blob<Dtype>*>* top);


  virtual inline LayerParameter_LayerType type() const {
    return LayerParameter_LayerType_LRN;
  }
  virtual inline int ExactNumBottomBlobs() const { return 1; }
  virtual inline int ExactNumTopBlobs() const { return 1; }


 protected:
  virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
      vector<Blob<Dtype>*>* top);
  virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom,
      vector<Blob<Dtype>*>* top);
  virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
      const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom);
  virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
      const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom);

  virtual void CrossChannelForward_cpu(const vector<Blob<Dtype>*>& bottom,
      vector<Blob<Dtype>*>* top);
  virtual void CrossChannelForward_gpu(const vector<Blob<Dtype>*>& bottom,
      vector<Blob<Dtype>*>* top);
  virtual void WithinChannelForward(const vector<Blob<Dtype>*>& bottom,
      vector<Blob<Dtype>*>* top);
  virtual void CrossChannelBackward_cpu(const vector<Blob<Dtype>*>& top,
      const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom);
  virtual void CrossChannelBackward_gpu(const vector<Blob<Dtype>*>& top,
      const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom);
  virtual void WithinChannelBackward(const vector<Blob<Dtype>*>& top,
      const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom);

  int size_;
  int pre_pad_;
  Dtype alpha_;
  Dtype beta_;
  int num_;
  int channels_;
  int height_;
  int width_;

  // Fields used for normalization ACROSS_CHANNELS
  // scale_ stores the intermediate summing results
  Blob<Dtype> scale_;

  // Fields used for normalization WITHIN_CHANNEL
  shared_ptr<SplitLayer<Dtype> > split_layer_;
  vector<Blob<Dtype>*> split_top_vec_;
  shared_ptr<PowerLayer<Dtype> > square_layer_;
  Blob<Dtype> square_input_;
  Blob<Dtype> square_output_;
  vector<Blob<Dtype>*> square_bottom_vec_;
  vector<Blob<Dtype>*> square_top_vec_;
  shared_ptr<PoolingLayer<Dtype> > pool_layer_;
  Blob<Dtype> pool_output_;
  vector<Blob<Dtype>*> pool_top_vec_;
  shared_ptr<PowerLayer<Dtype> > power_layer_;
  Blob<Dtype> power_output_;
  vector<Blob<Dtype>*> power_top_vec_;
  shared_ptr<EltwiseLayer<Dtype> > product_layer_;
  Blob<Dtype> product_input_;
  vector<Blob<Dtype>*> product_bottom_vec_;
};

内容较多,可能看一眼记不住所有的成员变量和函数,但记住一点,凡是Layer类型肯定都包含Forward()和Backward(),以及LayerSetUp()和Reshape(),这些在头文件中不必细看。关注的是以“_”结尾的成员变量,这些是和算法息息相关的。

很高兴看到了num_, height_, width_, channels_,这四个变量定义了该层输入图像的尺寸信息,是一个num_ x channels_ x height_ x width_的四维Blob矩阵(想不通?就当作视频流吧,前两维是宽高,第三维是颜色,第四维是时间)。

另外看到了alpha_, beta_, 这两个就是我们上面公式中的参数。

公式中的n(local_size)在类中用size_表示。

上面提到过需要补零,所以定义了pre_pad_变量。

在ACROSS_CHANNELS模式下,我们只需要用到scale_这个Blob矩阵,后面定义都可以忽略了~~好开森~~


读完了头文件中的声明,是不是觉得挺简单?我们接着看下实现细节,打开CAFFE_ROOT/src/caffe/layers/lrn_layer.cpp,从头看起,第一个实现函数为LayerSetUp(),代码如下:

template <typename Dtype>
void LRNLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom,
      vector<Blob<Dtype>*>* top) {
  size_ = this->layer_param_.lrn_param().local_size();
  CHECK_EQ(size_ % 2, 1) << "LRN only supports odd values for local_size";
  pre_pad_ = (size_ - 1) / 2;
  alpha_ = this->layer_param_.lrn_param().alpha();
  beta_ = this->layer_param_.lrn_param().beta();
  if (this->layer_param_.lrn_param().norm_region() ==
      LRNParameter_NormRegion_WITHIN_CHANNEL) {
    // Set up split_layer_ to use inputs in the numerator and denominator.
    split_top_vec_.clear();
    split_top_vec_.push_back(&product_input_);
    split_top_vec_.push_back(&square_input_);
    LayerParameter split_param;
    split_layer_.reset(new SplitLayer<Dtype>(split_param));
    split_layer_->SetUp(bottom, &split_top_vec_);
    // Set up square_layer_ to square the inputs.
    square_bottom_vec_.clear();
    square_top_vec_.clear();
    square_bottom_vec_.push_back(&square_input_);
    square_top_vec_.push_back(&square_output_);
    LayerParameter square_param;
    square_param.mutable_power_param()->set_power(Dtype(2));
    square_layer_.reset(new PowerLayer<Dtype>(square_param));
    square_layer_->SetUp(square_bottom_vec_, &square_top_vec_);
    // Set up pool_layer_ to sum over square neighborhoods of the input.
    pool_top_vec_.clear();
    pool_top_vec_.push_back(&pool_output_);
    LayerParameter pool_param;
    pool_param.mutable_pooling_param()->set_pool(
        PoolingParameter_PoolMethod_AVE);
    pool_param.mutable_pooling_param()->set_pad(pre_pad_);
    pool_param.mutable_pooling_param()->set_kernel_size(size_);
    pool_layer_.reset(new PoolingLayer<Dtype>(pool_param));
    pool_layer_->SetUp(square_top_vec_, &pool_top_vec_);
    // Set up power_layer_ to compute (1 + alpha_/N^2 s)^-beta_, where s is
    // the sum of a squared neighborhood (the output of pool_layer_).
    power_top_vec_.clear();
    power_top_vec_.push_back(&power_output_);
    LayerParameter power_param;
    power_param.mutable_power_param()->set_power(-beta_);
    power_param.mutable_power_param()->set_scale(alpha_);
    power_param.mutable_power_param()->set_shift(Dtype(1));
    power_layer_.reset(new PowerLayer<Dtype>(power_param));
    power_layer_->SetUp(pool_top_vec_, &power_top_vec_);
    // Set up a product_layer_ to compute outputs by multiplying inputs by the
    // inverse demoninator computed by the power layer.
    product_bottom_vec_.clear();
    product_bottom_vec_.push_back(&product_input_);
    product_bottom_vec_.push_back(&power_output_);
    LayerParameter product_param;
    EltwiseParameter* eltwise_param = product_param.mutable_eltwise_param();
    eltwise_param->set_operation(EltwiseParameter_EltwiseOp_PROD);
    product_layer_.reset(new EltwiseLayer<Dtype>(product_param));
    product_layer_->SetUp(product_bottom_vec_, top);
  }
}

这个函数实现了参数的初始化过程。首先从layer_param_对象中提取出size_的值,并检查是否为奇数,如果不是则报错;之后用size_计算pre_pad_的值,在前后各补一半0。接着alpha_和beta_也被初始化。如果是WITHIN_CHANNEL模式,那么还需要初始化一系列中间子层,这里我们不关心,因为我们用 ACROSS_CHANNELS模式。这么简单,还是好开森~~

接下来看Reshape()函数的实现:

template <typename Dtype>
void LRNLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom,
      vector<Blob<Dtype>*>* top) {
  num_ = bottom[0]->num();
  channels_ = bottom[0]->channels();
  height_ = bottom[0]->height();
  width_ = bottom[0]->width();
  switch (this->layer_param_.lrn_param().norm_region()) {
  case LRNParameter_NormRegion_ACROSS_CHANNELS:
    (*top)[0]->Reshape(num_, channels_, height_, width_);
    scale_.Reshape(num_, channels_, height_, width_);
    break;
  case LRNParameter_NormRegion_WITHIN_CHANNEL:
    split_layer_->Reshape(bottom, &split_top_vec_);
    square_layer_->Reshape(square_bottom_vec_, &square_top_vec_);
    pool_layer_->Reshape(square_top_vec_, &pool_top_vec_);
    power_layer_->Reshape(pool_top_vec_, &power_top_vec_);
    product_layer_->Reshape(product_bottom_vec_, top);
    break;
  }
}

首先根据bottom的尺寸初始化了num_, channels_, height_, width_这四个尺寸参数,之后根据归一化模式进行不同设置。在 ACROSS_CHANNELS 模式中,将top尺寸设置为和bottom一样大(num_, channels_, height_, width_),然后将scale_的尺寸也设置为一样大,这样我们在进行归一化时,只要逐点将scale_值乘以bottom值,就得到相应的top值。scale_值需要根据文章开头的计算公式得到,我们进一步考察怎么实现。

看下一个函数:

template <typename Dtype>
void LRNLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
    vector<Blob<Dtype>*>* top) {
  switch (this->layer_param_.lrn_param().norm_region()) {
  case LRNParameter_NormRegion_ACROSS_CHANNELS:
    CrossChannelForward_cpu(bottom, top);
    break;
  case LRNParameter_NormRegion_WITHIN_CHANNEL:
    WithinChannelForward(bottom, top);
    break;
  default:
    LOG(FATAL) << "Unknown normalization region.";
  }
}

很简单,根据归一化模式调用相应的Forward函数。我们这里看CrossChannelForward_cpu()这个函数,代码如下:

template <typename Dtype>
void LRNLayer<Dtype>::CrossChannelForward_cpu(
    const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top) {
  const Dtype* bottom_data = bottom[0]->cpu_data();
  Dtype* top_data = (*top)[0]->mutable_cpu_data();
  Dtype* scale_data = scale_.mutable_cpu_data();//用指针获取每个Blob对象的内存地址,便于后面操作
  // start with the constant value
  for (int i = 0; i < scale_.count(); ++i) {//初始化值为1.0
    scale_data[i] = 1.;
  }
  Blob<Dtype> padded_square(1, channels_ + size_ - 1, height_, width_);//补零后的Blob,第三维尺寸比bottom大了size_ - 1;
  Dtype* padded_square_data = padded_square.mutable_cpu_data();
  caffe_set(padded_square.count(), Dtype(0), padded_square_data);//先清零
  Dtype alpha_over_size = alpha_ / size_;//预先计算公式中的alpha/n
  // go through the images
  for (int n = 0; n < num_; ++n) {//bottom的第四维尺寸num_,需要分解为单个来做归一化
    // compute the padded square
    caffe_sqr(channels_ * height_ * width_,
        bottom_data + bottom[0]->offset(n),
        padded_square_data + padded_square.offset(0, pre_pad_));//计算bottom的平方,放入padded_square矩阵中,前pre_pad_个位置依旧0
    // Create the first channel scale
    for (int c = 0; c < size_; ++c) {//对n个通道平方求和并乘以预先算好的(alpha/n),累加至scale_中(实现计算 1 + sum_under_i(x_i^2))
      caffe_axpy<Dtype>(height_ * width_, alpha_over_size,
          padded_square_data + padded_square.offset(0, c),
          scale_data + scale_.offset(n, 0));
    }
    for (int c = 1; c < channels_; ++c) {//这里使用了类似FIFO的形式计算其余scale_参数,每次向后移动一个单位,加头去尾,避免重复计算求和
      // copy previous scale
      caffe_copy<Dtype>(height_ * width_,
          scale_data + scale_.offset(n, c - 1),
          scale_data + scale_.offset(n, c));
      // add head
      caffe_axpy<Dtype>(height_ * width_, alpha_over_size,
          padded_square_data + padded_square.offset(0, c + size_ - 1),
          scale_data + scale_.offset(n, c));
      // subtract tail
      caffe_axpy<Dtype>(height_ * width_, -alpha_over_size,
          padded_square_data + padded_square.offset(0, c - 1),
          scale_data + scale_.offset(n, c));
    }
  }

  // In the end, compute output
  caffe_powx<Dtype>(scale_.count(), scale_data, -beta_, top_data);//计算求指数,由于将除法转换为乘法,故指数变负
  caffe_mul<Dtype>(scale_.count(), top_data, bottom_data, top_data);//bottom .* scale_ -> top
}

可能你对caffe_axpy, caffe_sqr, caffe_powx, caffe_mul还不熟悉,其实都是很简单的数学计算,在CAFFE_ROOT/include/caffe/util/math_functions.hpp中有声明。

template <typename Dtype>
void caffe_axpy(const int N, const Dtype alpha, const Dtype* X,
    Dtype* Y);

实现如下操作:Y = alpha * X + Y;其中X, Y为N个元素的向量。

template <typename Dtype>
void caffe_powx(const int n, const Dtype* a, const Dtype b, Dtype* y);

实现如下操作:y = a^b, 其中a, y为n个元素的向量,b为标量。

其余请自己推导。


交换机背板带宽、交换容量与包转发率到底是啥? 在网络工程中,交换机是核心设备之一,而关于它的性能指标,背板带宽、交换容量、以及包转发率往往成为人们衡量其性能的重要参数。这些术语的定义、关系、以及在实际场景中的应用,都对交换机的选型与部署有着重要意义。本文将为您全面解读这些概念,帮助您深入了解交换机的核心性能指标。 阅读详情

相关推荐

Vmware Vcenter7.0证书web续期发生错误

生成证书,选择第三个(PS,如果没有域名的,一定要写IP,不然很容易卡在85%,服务不能起来)这里大概率可能是证书里面的FQDN和主机不匹配,又或者是主机解析FQDN有问题。vCenter _MACHINE_CERT快到期了,通过web界面更新证书失败。vSphere Client 版本 7.0.2.00200。登陆ssh到vcenter,重新生成证书。先关掉HA,不然证书管理会报错。第一步先这样,重新续订一下证书。

m0_74823595的博客 3944

LRN ( Local Response Normalization) 局部响应归一化层

LRN全称为Local Response Normalization,即局部响应归一化层,LRN函数类似DROPOUT和数据增强作为relu激励之后防止数据过拟合而提出的一种处理方法。这个函数很少使用,基本上被类似DROPOUT这样的方法取代,见最早的出处AlexNet论文。 首先在弄懂原理之前,希望读者能够认真的看两边公式,而不是直接看别人解释的原理 bix,ybxi,y是归一化后的值,i...

qq_32172681的博客 1032

Docker部署 SRS rtmp/flv流媒体服务器

SRS(Simple Realtime Server)是一款开源的流媒体服务器,具有高性能、高可靠性、高灵活性的特点,能够支持直播、点播、转码等多种流媒体应用场景。SRS 不仅提供了流媒体服务器,还提供了适用于多种平台的客户端 SDK 和在线转码等辅助服务,是一款十分强大的流媒体解决方案。

m0_56659620的博客 4869

LRN-局部相应层

LRN是Local Response Normalization的缩写,局部相应层。 这类层应用得并不多,在vgg那个论文中比较网络深度时候有用。 局部响应归一层的基本思路是,假如这是网络的一块,比如是 9×9×256,LRN 要做的就是选取一个位置(注意是一个位置),比如说这样一个位置,从这个位置穿过整个通道,能得到 256 个数字,并进行归一化。 进行局部响应归一化的动机是,对于这张 9...

Loong Cheng的博客 1511

抖音X-Medusa风控逆向:unidbg环境重建与魔改AES还原

X-Medusa并非传统加密算法,而是深度耦合运行时环境的动态混淆系统,其核心是硬件指纹感知、线程上下文绑定与非标AES变异。理解其原理需跳出‘找密钥’思维,转向对CPU型号、系统属性、微秒级时间及内存布局的综合建模。技术价值在于将不可控的客户端风控,转化为可复现、可配置、可运维的服务化能力;典型应用场景包括合规数据采集、API协议适配与移动安全研究。本文聚焦Android native层逆向实践,基于unidbg实现高保真环境模拟,并完整还原S-Box动态生成、MixColumns矩阵变异与轮密钥XOR扰

weixin_33783283的博客 685

Midscene.js(1):Chrome 插件实战之基于 AI 驱动 WEB UI 自动化测试「喂饭教程」

Midscene.js 是一款开源的AI驱动UI自动化工具,支持自然语言交互、数据提取、断言验证等多种功能。自然语言交互。本文将以 Midscene.js Chrome 插件为例,带你从零上手,体验如何用最简单的方式实现高效、智能的UI自动化测试。

blues_C的博客 4404

【深度学习】计算机视觉(五)——卷积神经网络详解

在之前学习的基础上,对神经网络进一步学习

RK_Dangerous的博客 1万+

LabVIEW进行MQTT通信及数据解析

该文章介绍了LabVIEW的MQTT通信的开源VI控制,以及如果进行数据的解析,特别是一些需要注意的点

heda3的博客 4105

Caffe源码导读(7):LRN层的实现

LRN全称为Local Response Normalization,即局部响应归一化层,具体实现在CAFFE_ROOT/src/caffe/layers/lrn_layer.cpp和同一目录下lrn_layer.cu中。该层需要参数有:norm_region: 选择对相邻通道间归一化还是通道内空间区域归一化,默认为ACROSS_CHANNELS,即通道间归一化;local_size:两种表示(1...

卜居 2万+

YOLOv11改进,YOLOv11引入B2CNet的BFAM(双时相特征聚合模块),JSTARS 2024,二次创新C3k2结构

YOLOv11改进,YOLOv11引入B2CNet的BFAM(双时相特征聚合模块),JSTARS 2024,二次创新C3k2结构

在职AI算法工程师,擅长计算机视觉,YOLO目标检测、分割等,擅长web、pyqt界面可视化,好内容持续更新中,来这里跟大家一起学习,共同进步 406

财务数字化——解读美的战略规划之财务组织体系建设【附全文阅读】

本文提出适用于集团企业的财务管控方案,面向财务负责人、HR及战略规划人员。方案整合四种管控模式,结合500强案例,构建"职能定位-架构设计-权责划分-人才发展"体系,涵盖财务五大模块。通过明确总部与事业部权责边界,提供组织架构等实操框架,旨在平衡财务管控与业务支持,提升效率与风控能力,满足集团财务体系规范化建设需求。

cdfunlove的博客 663

简谈caffe中的LRN层

昨日面试,被问道BN层和LRN层,一直以来用的都是bn,所以当时对LRN只剩下点印象,事后弥补了一下这边知识点的不足,浅谈自己对LRN层的理解,如果误导,欢迎指正. LRN层的作用是对局部区域进行归一化,对响应比较大的值变得更大,对响应比较小的值抑制.先看一下caffe的代码 可以看到四个参数. layer { name: "norm1" type: "LRN" bottom:...

hjxu2016的博客 3201

近五年体内微/纳米机器人赋能肿瘤精准治疗综述:以 GBM 为重点

摘要 微/纳米机器人在实体瘤治疗领域展现出突破性潜力,通过主动运动能力解决传统纳米药物递送效率低、渗透不足等核心问题。2021-2025年间形成三条技术路线:1) 磁驱、声驱等运动增强递送实现深层渗透;2) 与免疫治疗融合实现原位免疫唤醒;3) 针对胶质母细胞瘤开发跨屏障递送系统。研究重点从单一运动性能转向"运动-分布-疗效"的系统评价,需建立标准化指标评估运动学参数、肿瘤分布均匀性和安全性。未来挑战在于临床转化的可制造性、闭环操控及生物相容性优化,特别是对血脑屏障穿透等复杂场景的系统集

AllenLV的博客 5131

LRN 局部响应归一化层(Local Response Normalization)

局部响应归一化层(Local Response Normalization) 局部响应归一化层简称LRN,是在深度学习中提高准确度的技术方法。一般是在激活、池化后进行的一中处理方法,因在Alexnet中运用到,故做一下整理。 为什么要引入LRN层? 首先要引入一个神经生物学的概念:侧抑制(lateral inhibitio),即指被激活的神经元抑制相邻的神经元。归一化(normaliazation)的目的就是“抑制”,LRN就是借鉴这种侧抑制来实现局部抑制,尤其是我们使用RELU的时候,这种“侧抑制

FY_2018的博客 1768

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

LRN (Local Response Normalization,即局部响应归一化层)

LRN (Local Response Normalization,即局部响应归一化层) (一)先看看归一化吧 什么是归一化? 归一化化是归纳统一样本的统计分布性。就是要把你需要处理的数据经过处理后(通过某种算法)限制在你需要的一定范围内。 为什么要归一化,归一化目的是什么? (1)为了后面数据处理的方便,归一化的确可以避免一些不必要的数值问题。 (2)为了

Learning by doing 1万+

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Alexnet中的LRN

LRN全称为Local Response Normalization,即局部响应归一化层,LRN函数类似Dropout,是一种防止过拟合的方法。这个函数很少使用,基本上被类似Dropout这样的方法取代,见最早的出处AlexNet论文对它的定义, 《ImageNet Classification with Deep ConvolutionalNeural Networks》。 是归一化后...

Loong Cheng的博客 1714

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

LRN(局部响应归一化)

原理: LRN层模仿了生物神经系统的“侧抑制”机制,对局部神经元的活动创建竞争环境,使得其中响应比较大的值变得相对更大,并抑制其他反馈较小的神经元,增强模型的泛化能力。 LRN对于ReLU这种没有上限边界的激活函数会比较有用,因为它会从附近的多个卷积核的响应中挑选比较大的反馈,但不适合Sigmoid之中有固定边界并且能抑制过大值的激活函数。 是归一化后的值。 表示第i个核位置(x,y)运用ReL...

AI.PLAY 2836

LRN局部相应归一化

本笔记记录学习 LRN(Local Response Normalization),若有错误,欢迎批评指正,学习交流。1.侧抑制(lateral inhibition)2.计算公式Hinton在2012年的Alexnet网络中给出其具体的计算公式如下:公式看上去比较复杂,但理解起来非常简单。i表示第i个核在位置(x,y)运用激活函数ReLU后的输出,n是同一位置上临近的kernal map的数目,...

一路向北 1096

ImageNet中的LRN(Local Response Normalization)

LRN(Local Response Normalization) 神经网络初学者,没有什么理论基础,偶然看到个ImageNet,就准备从其入手,先弄懂每层的含义,其中这个LRN层真是让人百思不得其解,搜索了下,给出的介绍比较少。为什么会比较少呢,搜索到最后我得出的结论是,这货似乎没什么多少卵用。。。  ImageNet中的LRN层是按下述公式计算的: 但似乎,在后来的设

searobbers_duck的博客 4万+

CNN中的LRN层

LRN层是按下述公式计算的:(用处不大 可被dropout normalization替代)转自:https://blog.youkuaiyun.com/searobbers_duck/article/details/51645941

yan的博客 4179

LRN归一化

LRN全称为LocalResponse Normalization,即局部响应归一化层。局部响应归一化层完成一种“临近抑制”操作,对局部输入区域进行归一化 具体实现在CAFFE_ROOT/src/caffe/layers/lrn_layer.cpp和同一目录下lrn_layer.cu中。   该层需要参数有: norm_region: 选择对相邻通道间归一化还是通道内空间区域归一化,默认为

nongfu_spring的专栏 3504

深度学习饱受争议的局部响应归一化(LRN)详解

前言:Local Response Normalization(LRN)技术主要是深度学习训练时的一种提高准确度的技术方法。其中caffe、tensorflow等里面是很常见的方法,其跟激活函数是有区别的,LRN一般是在激活、池化后进行的一种处理方法。LRN归一化技术首次在AlexNet模型中提出这个概念。通过实验确实证明它可以提高模型的泛化能力,但是提升的很少,以至于后面不再使用,甚至有...

MIss-Y的博客 3万+

Caffe 中的 LRNLayer

Caffe 中的 LRNLayer 支持两种模式: CrossChannel:为人们所熟知的局部响应归一化,在 AlexNet 中提出,在一些早期网络中使用; WithinChannel: Caffe 中独有的实现,未见网络中应用。本文略过。 ReLU 具有不需要输入归一化以防止其饱和的理想特性。但 AlexNet 论文中发现 LRN 有助于提高泛化性。LRN CrossChannel 模式公式如下:

yiran103的专栏 548

Caffe源码解读:lrn_layer层原理

LRN全称为Local Response Normalization,即局部响应归一化层,具体实现在CAFFE_ROOT/src/caffe/layers/lrn_layer.cpp和同一目录下lrn_layer.cu中。 该层需要参数有: norm_region: 选择对相邻通道间归一化还是通道内空间区域归一化,默认为ACROSS_CHANNELS,即通道间归一化;

zyf19930610的专栏 927
上一篇: Caffe系列(2):视觉层(Vision Layers)及参数
下一篇: Caffe系列(3):激活层(Activiation Layers)及参数
2014wzy
博客等级 码龄13年 759粉丝 85原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值