caffe实现Mish层的

Mish激活函数介绍

Mish函数的表达式如下所示:
M i s h ( x ) = x ∗ t a n h ( s o f t ( x ) ) Mish(x)=x*tanh(soft(x)) Mish(x)=xtanh(soft(x)) t a n h ( x ) = e x − e − x e x + e − x tanh(x)=\frac{e^{x}-e^{-x}} {e^{x}+e^{-x}} tanh(x)=ex+exexex s o f t ( x ) = l n ( 1 + e x ) soft(x)=ln(1+e^x) soft(x)=ln(1+ex)
为简化计算,将 s o f t ( x ) soft(x) soft(x)带入 t a n h ( x ) tanh(x) tanh(x)中去,可得到 t a n h ( s o f t ( x ) ) tanh(soft(x)) tanh(soft(x))的表达式如下所示:
t a n h ( s o f t ( x ) ) = ( 1 + e x ) 2 − 1 ( 1 + e x ) 2 + 1 = 1 − 2 ( 1 + e x ) 2 + 1 tanh(soft(x))=\frac{(1+e^x)^2-1} {(1+e^x)^2+1}=1-\frac{2} {(1+e^x)^2+1} tanh(soft(x))=(1+ex)2+1(1+ex)21=1(1+ex)2+12
所以 M i s h ( x ) Mish(x) Mish(x)可用如下表达式计算:
M i s h ( x ) = x ∗ ( 1 − 2 ( 1 + e x ) 2 + 1 ) = x − 2 x ( 1 + e x ) 2 + 1 Mish(x)=x*(1-\frac{2} {(1+e^x)^2+1})=x-\frac{2x} {(1+e^x)^2+1} Mish(x)=x(1(1+ex)2+12)=x(1+ex)2+12x
对其求导可得到其导函数表达式如下:
M i s h ′ ( x ) = 1 − − 2 ( 1 + e x ) 2 + 1 + 4 x ∗ e x ∗ ( 1 + e x ) ( ( 1 + e x ) 2 + 1 ) 2 Mish ^\prime(x)=1--\frac{2} {(1+e^x)^2+1}+\frac{4x*e^x*(1+e^x)} {((1+e^x)^2+1)^2} Mish(x)=1(1+ex)2+12+((1+ex)2+1)24xex(1+ex) = 1 − 2 ( 1 + e x ) 2 + 1 + 4 x ∗ ( 1 + e x ) 2 − ( 1 + e x ) ( ( 1 + e x ) 2 + 1 ) 2 =1-\frac{2} {(1+e^x)^2+1}+4x*\frac{(1+e^x)^2-(1+e^x)} {((1+e^x)^2+1)^2} =1(1+ex)2+12+4x((1+ex)2+1)2(1+ex)2(1+ex)

M i s h ′ ( x ) Mish ^\prime(x) Mish(x)写成如上形式后,可将 ( e x + 1 ) (e^x+1) (ex+1)作为临时变量,从而减少运算。

caffe实现Mish激活层

caffe中的激活层如Relu,PRelu,Sigmoid等激活层继承于NeuronLayer层,NeuronLayer层主要定义了Reshape函数,我们如需实现Mish层,则同样继承于NeuronLayer。
Mish层无可学习参数,但反向传播计算梯度时需要利用到bottom的数据,而激活层常使用In-place操作,从而导致bottom数据被覆盖,故需要将bottom拷贝出来。
其中, M i s h ( x ) Mish(x) Mish(x)的前向和反向传播主要代码如下:

template <typename Dtype>
inline Dtype mish(Dtype x) {
  Dtype tmp=exp(x)+1;
  return x-2*x/(tmp*tmp+1);
}
template <typename Dtype>
inline Dtype mish_back(Dtype x) {
  Dtype tmp=exp(x)+1;
  Dtype tmp1=tmp*tmp+1;

  return 1-2/tmp1+4*x*(tmp*tmp-tmp)/(tmp1*tmp1);
}
template <typename Dtype>
void MishLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
    const vector<Blob<Dtype>*>& top) {
  const Dtype* bottom_data = bottom[0]->cpu_data();
  Dtype* top_data = top[0]->mutable_cpu_data();
  const int count = bottom[0]->count();  
  Dtype* backward_buff_data=backward_buff_.mutable_cpu_data();
  if(bottom[0] == top[0]){
    // caffe_set(count,static_cast<Dtype>(0),backward_buff_data);
    caffe_copy(count,bottom_data,backward_buff_data);
  }
  for (int i = 0; i < count; ++i) {
      Dtype x_bottom=bottom_data[i];
      top_data[i]=mish(x_bottom);
      }
  }

template <typename Dtype>
void MishLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
    const vector<bool>& propagate_down,
    const vector<Blob<Dtype>*>& bottom) {

  const Dtype* top_diff = top[0]->cpu_diff();
  const int count = bottom[0]->count();
  const Dtype* bottom_data = bottom[0]->cpu_data();
  if (top[0] == bottom[0]) {
    bottom_data = backward_buff_.cpu_data();
  }

  Dtype* bottom_diff= bottom[0]->mutable_cpu_diff();
  
  if (this->param_propagate_down_[0]) {
   
    for(int i=0;i<count;i++){
      bottom_diff[i]=mish_back(bottom_data[i])*top_diff[i];
    }
  }
}

所有代码以上传至 https://github.com/zhaokai5/MishLayer_caffe
该版本实现的 M i s h ( x ) Mish(x) Mish(x)前向和反向均为原始版本,没有使用快速算法,快速算法后期有时间再优化。

参考资料

  1. Mish: A Self Regularized Non-Monotonic Neural Activation Function
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值