当前位置:   article > 正文

激活函数层 && 神经网络的基本组成 && Sigmoid、ReLU及Softmax函数

激活函数层

神经网络如果仅仅是由线性的卷积运算堆叠组成,则其无法形成复杂的表达空间,也就很难提取出高语义的信息,因此还需要加入非线性的映射,又称为激活函数,可以逼近任意的非线性函数,以提升整个神经网络的表达能力。

在物体检测任务中,常用的激活函数有Sigmoid、 ReLU及Softmax函数。

目录

一、常见的激活函数

(1)Sigmoid函数

(2)ReLU函数

(3)Leaky ReLU函数

(4)Softmax函数

 二、Pytorch官方文件激活函数总结

(1)涉及的激活函数,以及公式

(2)代码示例(含注释) 


一、常见的激活函数

(1)Sigmoid函数

Sigmoid型函数又称为Logistic函数,模拟了生物的神经元特性,即当神经元获得的输入信号累计超过一定的阈值后,神经元被激活而处于兴奋状态,否则处于抑制状态。表达式如下所示:

Sigmoid函数曲线与梯度曲线如图1所示。可以看到,Sigmoid函数将特征压缩到了(0,1)区间,0端对应抑制状态,而1对应激活状态,中间部分梯度较大。

图1 Sigmoid函数及其梯度曲线

Sigmoid函数可以用来做二分类,但其计算量较大,并且容易出现梯度消失现象。从曲线图(图1)中可以看出,在Sigmoid函数两侧的 特征导数接近于0,这将导致在梯度反传时损失的误差难以传递到前面 的网络层(因为根据链式求导,梯度接近于0)。

(2)ReLU函数

为了缓解梯度消失现象,修正线性单元(Rectified Linear Unit, ReLU)被引入到神经网络中。由于其优越的性能与简单优雅的实现, ReLU已经成为目前卷积神经网络中最为常用的激活函数之一。ReLU函数的表达式如下所示。

ReLU函数及其梯度曲线如图2 所示。可以看出,在小于0的部分, 值与梯度皆为0,而在大于0的部分中导数保持为1,避免了Sigmoid函数中梯度接近于0导致的梯度消失问题。

 图2 ReLU函数及其梯度曲线

ReLU函数计算简单,收敛快,并在众多卷积网络中验证了其有效性。

(3)Leaky ReLU函数

ReLU激活函数虽然高效,但是其将负区间所有的输入都强行置为 0,Leaky ReLU函数优化了这一点,在负区间内避免了直接置0,而是赋予很小的权重,其函数表达式如下所示。

以上公式中的 ai 代表权重,即小于0的值被缩小的比例。Leaky ReLU的函数曲线如图3 所示。

图3 Leaky ReLU函数曲线

虽然从理论上讲,Leaky ReLU函数的使用效果应该要比ReLU函数好,但是从大量实验结果来看并没有看出其效果比ReLU好。此外,对于ReLU函数的变种,除了Leaky ReLU函数之外,还有PReLU和RReLU 函数等,这里不做详细介绍。

(4)Softmax函数

在物体检测中,通常需要面对多物体分类问题,虽然可以使用 Sigmoid函数来构造多个二分类器,但比较麻烦,多物体类别较为常用的分类器是Softmax函数。

在具体的分类任务中,Softmax函数的输入往往是多个类别的得分,输出则是每一个类别对应的概率,所有类别的概率取值都在0~1之 间,且和为1。Softmax函数的表达式如下所示,其中,Vi表示第i 个类别的得分,C代表分类的类别总数,输出Si为第i个类别的概率。

 二、Pytorch官方文件激活函数总结

(1)涉及的激活函数,以及公式

  1. nn.ReLU                              # f(x)= max(0, x)
  2. nn.ReLU6                            # f(x) = min(max(0,x), 6)
  3. nn.ELU                                # f(x) = max(0,x) + min(0, alpha * (e^x - 1))
  4. nn.PReLU                            # f(x) = max(0,x) + a * min(0,x)
  5. nn.LeakyReLU                    # f(x) = max(0, x) + {negative_slope} * min(0, x)
  6. nn.Threshold                      # y=x,if x>=threshold y=value,if x<threshold
  7. nn.Hardtanh                       # f(x)=+1,if x>1; f(x)=−1,if x<−1; f(x)=x,otherwise
  8. nn.Sigmoid                         # f(x)=1/(1+e−x)
  9. nn.Tanh                               # f(x)=ex−e−xex+ex
  10. nn.LogSigmoid                  # f(x) = log( 1 / ( 1 + e^{-x}))
  11. nn.Softplus                         # f(x)=1beta∗log(1+e(beta∗xi))
  12. nn.Softshrink                     # f(x)=x−lambda,if x>lambda f(x)=x+lambda,  if x<−lambda  f(x)=0,otherwise
  13. nn.Softsign                        # f(x) = x / (1 + |x|)
  14. nn.Tanhshrink                   # f(x)=x−Tanh(x)
  15. nn.Softmin                         # fi(x)=e(−xi−shift)∑je(−xj−shift),shift=max(xi)
  16. nn.Softmax                        # fi(x)=e(xi−shift)∑je(xj−shift),shift=max(xi)
  17. nn.LogSoftmax                 # fi(x)=loge(xi)a,a=∑je(xj)

(2)代码示例(含注释) 

  1. import torch
  2. import torch.nn as nn
  3. from torch import autograd
  4. # torch.nn.ReLU(inplace=False)
  5. # 对输入运用修正线性单元函数${ReLU}(x)= max(0, x)$,
  6. # 参数: inplace-选择是否进行覆盖运算
  7. m = nn.ReLU()
  8. input = autograd.Variable(torch.randn(2))
  9. print(input)
  10. print(m(input))
  11. # torch.nn.ReLU6(inplace=False)
  12. # 对输入的每一个元素运用函数${ReLU6}(x) = min(max(0,x), 6)$,
  13. m = nn.ReLU6()
  14. input = autograd.Variable(torch.randn(2))
  15. print(input)
  16. print(m(input))
  17. # torch.nn.ELU(alpha=1.0, inplace=False)
  18. # 对输入的每一个元素运用函数$f(x) = max(0,x) + min(0, alpha * (e^x - 1))$
  19. m = nn.ELU()
  20. input = autograd.Variable(torch.randn(2))
  21. print(input)
  22. print(m(input))
  23. # torch.nn.PReLU(num_parameters=1, init=0.25)
  24. # 对输入的每一个元素运用函数$PReLU(x) = max(0,x) + a * min(0,x)$,a 是一个可学习参数。
  25. # 当没有声明时,nn.PReLU()在所有的输入中只有一个参数 a;
  26. # 如果是 nn.PReLU(nChannels),a 将应用到每个输入。
  27. # 注意:当为了表现更佳的模型而学习参数 a 时不要使用权重衰减(weight decay)
  28. # 参数:
  29. # num_parameters:需要学习的 a 的个数,默认等于 1
  30. # init:a 的初始值,默认等于 0.25
  31. m = nn.PReLU()
  32. input = autograd.Variable(torch.randn(2))
  33. print(input)
  34. print(m(input))
  35. # torch.nn.LeakyReLU(negative_slope=0.01, inplace=False)
  36. # 对输入的每一个元素运用$f(x) = max(0, x) + {negative_slope} * min(0, x)$
  37. # 参数:
  38. # negative_slope:控制负斜率的角度,默认等于 0.01
  39. # inplace-选择是否进行覆盖运算
  40. m = nn.LeakyReLU(0.1)
  41. input = autograd.Variable(torch.randn(2))
  42. print(input)
  43. print(m(input))
  1. import torch
  2. import torch.nn as nn
  3. from torch import autograd
  4. # torch.nn.Threshold(threshold, value, inplace=False)
  5. # Threshold 定义:y=x,if x>=threshold y=value,if x<threshold
  6. # 参数:
  7. # threshold:阈值
  8. # value:输入值小于阈值则会被 value 代替
  9. # inplace:选择是否进行覆盖运算
  10. m = nn.Threshold(0.1, 20)
  11. input = autograd.Variable(torch.Tensor([0.26, 0]))
  12. print(input)
  13. print(m(input))
  14. # torch.nn.Hardtanh(min_value=-1, max_value=1, inplace=False)
  15. # 对每个元素,f(x)=+1,if x>1; f(x)=−1,if x<−1; f(x)=x,otherwise
  16. # 线性区域的范围[-1,1]可以被调整
  17. # 参数:
  18. # min_value:线性区域范围最小值
  19. # max_value:线性区域范围最大值
  20. # inplace:选择是否进行覆盖运算
  21. m = nn.Hardtanh()
  22. input = autograd.Variable(torch.Tensor([0.2, -3, 5]))
  23. print(input)
  24. print(m(input))
  25. # torch.nn.Sigmoid
  26. # 对每个元素运用 Sigmoid 函数,Sigmoid 定义如下:f(x)=1/(1+e−x)
  27. m = nn.Sigmoid()
  28. input = autograd.Variable(torch.Tensor([0, 3, 10]))
  29. print(input)
  30. print(m(input))
  31. # torch.nn.Tanh
  32. # 对输入的每个元素,f(x)=ex−e−xex+ex
  33. m = nn.Tanh()
  34. input = autograd.Variable(torch.randn(2))
  35. print(input)
  36. print(m(input))
  37. # torch.nn.LogSigmoid
  38. # 对输入的每个元素,$LogSigmoid(x) = log( 1 / ( 1 + e^{-x}))$
  39. m = nn.LogSigmoid()
  40. input = autograd.Variable(torch.randn(2))
  41. print(input)
  42. print(m(input))
  43. # torch.nn.Softplus(beta=1, threshold=20)
  44. # 对每个元素运用 Softplus 函数,Softplus 定义如下:f(x)=1beta∗log(1+e(beta∗xi))
  45. # Softplus 函数是 ReLU 函数的平滑逼近,Softplus 函数可以使得输出值限定为正数。
  46. # 为了保证数值稳定性,线性函数的转换可以使输出大于某个值。
  47. # 参数:
  48. # beta:Softplus 函数的 beta 值
  49. # threshold:阈值
  50. m = nn.Softplus(beta=2, threshold=10)
  51. m1 = nn.Softplus()
  52. input = autograd.Variable(torch.randn(2))
  53. print(input)
  54. print(m(input))
  55. print(m1(input))
  56. # torch.nn.Softshrink(lambd=0.5)
  57. # 对每个元素运用 Softshrink 函数,Softshrink 函数定义如下:
  58. # f(x)=x−lambda,if x>lambda f(x)=x+lambda,if x<−lambda f(x)=0,otherwise
  59. # 参数:
  60. # lambd:Softshrink 函数的 lambda 值,默认为 0.5
  61. m = nn.Softshrink()
  62. input = autograd.Variable(torch.randn(2))
  63. print(input)
  64. print(m(input))
  65. # torch.nn.Softsign
  66. # $f(x) = x / (1 + |x|)$
  67. m = nn.Softsign()
  68. input = autograd.Variable(torch.Tensor([1, 2]))
  69. print(input)
  70. print(m(input))
  71. # torch.nn.Softshrink(lambd=0.5)
  72. # 对每个元素运用 Tanhshrink 函数,Tanhshrink 函数定义如下:
  73. # Tanhshrink(x)=x−Tanh(x)
  74. m = nn.Tanhshrink()
  75. input = autograd.Variable(torch.randn(2))
  76. m_tanh = nn.Tanh()
  77. print(input)
  78. print(m_tanh(input))
  79. print(m(input))
  80. # torch.nn.Softmin
  81. # 对 n 维输入张量运用 Softmin 函数,将张量的每个元素缩放到(0,1)区间且和为 1。Softmin 函数定义如下:
  82. # fi(x)=e(−xi−shift)∑je(−xj−shift),shift=max(xi)
  83. # dim (int):计算 Softmin 的维度(因此沿 dim 的每个切片的总和为 1)。
  84. m = nn.Softmin(dim=0)
  85. input = autograd.Variable(torch.randn(2, 3))
  86. print(input)
  87. print(m(input))
  88. # torch.nn.Softmax
  89. # 对 n 维输入张量运用 Softmax 函数,将张量的每个元素缩放到(0,1)区间且和为 1。
  90. # Softmax 函数定义如下:fi(x)=e(xi−shift)∑je(xj−shift),shift=max(xi)
  91. # 返回结果是一个与输入维度相同的张量,每个元素的取值范围在(0,1)区间。
  92. m = nn.Softmax(dim=0)
  93. input = autograd.Variable(torch.randn(2, 3))
  94. print(input)
  95. print(m(input))
  96. # torch.nn.LogSoftmax
  97. # 对 n 维输入张量运用 LogSoftmax 函数,LogSoftmax 函数定义如下:
  98. # fi(x)=loge(xi)a,a=∑je(xj)
  99. m = nn.LogSoftmax(dim=0)
  100. input = autograd.Variable(torch.randn(2, 3))
  101. print(input)
  102. print(m(input))

>>>本文参考:Pytoch官方文件 &&《深度学习之PyTorch物体检测实战》

>>>如有疑问,欢迎评论区一起探讨 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/874340
推荐阅读
相关标签
  

闽ICP备14008679号