激活函数大汇总(十)(Hard Shrink & Soft Shrink附代码和详细公式)

更多激活函数见激活函数大汇总列表

一、引言

欢迎来到我们深入探索神经网络核心组成部分——激活函数的系列博客。在人工智能的世界里,激活函数扮演着不可或缺的角色,它们决定着神经元的输出,并且影响着网络的学习能力与表现力。鉴于激活函数的重要性和多样性,我们将通过几篇文章的形式,本篇详细介绍两种激活函数,旨在帮助读者深入了解各种激活函数的特点、应用场景及其对模型性能的影响。

在接下来的文章中,我们将逐一探讨各种激活函数,从经典到最新的研究成果。

限于笔者水平,对于本博客存在的纰漏和错误,欢迎大家留言指正,我将不断更新。

二、Hard Swish

Hard Shrink激活函数是一种非线性激活函数,主要用于稀疏编码和去噪等应用中。它通过应用一个固定的阈值来“收缩”输入值,这有助于减少网络中的小幅度噪声。

1. 数学定义

Hard Shrink激活函数定义如下:

HardShrink ⁡ ( x ) = { x  if  x < − λ 0  if  − λ ≤ x ≤ λ x  if  x > λ \operatorname{HardShrink}(x)= \begin{cases}x & \text { if } x<-\lambda \\ 0 & \text { if }-\lambda \leq x \leq \lambda \\ x & \text { if } x>\lambda\end{cases} HardShrink(x)= x0x if x<λ if λxλ if x>λ
其中, x x x是输入值, λ \lambda λ是一个预定义的非负阈值。函数的作用是,只有当输入的绝对值大于 λ \lambda λ时,输入才会被保留,否则输出为0。
【DL经典回顾】激活函数大汇总(十)(Hard Shrink &amp; Soft Shrink附代码和详细公式)-LMLPHP

2. 函数特性

  • 非线性和稀疏激活:Hard Shrink通过将输入值的小幅度变化压缩为0,促进了输出的稀疏性。
  • 去噪和正则化:这种激活函数能够帮助模型忽略微小的变化或噪声,有助于正则化和去噪。
  • 简单高效:Hard Shrink函数由于其简单的数学形式,在计算上非常高效,易于实现。

3. 导数

Hard Shrink函数的导数是分段常数:

d d x HardShrink ⁡ ( x ) = { 1  if  ∣ x ∣ > λ 0  otherwise  \frac{d}{d x} \operatorname{HardShrink}(x)= \begin{cases}1 & \text { if }|x|>\lambda \\ 0 & \text { otherwise }\end{cases} dxdHardShrink(x)={10 if x>λ otherwise 
这意味着,在非零输出区间,梯度为1,允许梯度通过;在其它区间,梯度为0,阻止梯度更新。

4. 使用场景与局限性

使用场景

  • 去噪:在处理含有微小噪声的数据时,如图像去噪或信号处理应用。
  • 稀疏编码:在需要促进模型输出稀疏性的场景,如某些压缩和特征选择任务。

局限性

  • 信息丢失:由于将输入值的小幅度变化设为0,可能会导致模型丢失重要的信息。
  • 训练困难:在训练过程中,由于梯度在大部分区域为0,可能会导致梯度消失问题,影响模型学习。

5.代码实现

import numpy as np

def hard_shrink(x, lambd=0.5):
    """计算Hard Shrink激活函数的值。
    
    参数:
    x -- 输入值,可以是一个数值、NumPy数组或者多维数组。
    lambd -- 阈值,决定了何时将输入压缩到0,默认为0.5。
    
    返回:
    Hard Shrink激活后的结果。
    """
    return x * ((x > lambd) | (x < -lambd))
解读
  • 阈值过滤:此实现中,通过逻辑运算((x > lambd) | (x < -lambd))来判断输入值x是否在阈值\(\lambda\)之外。如果x的绝对值大于\(\lambda\),这个表达式的结果为True(对应于NumPy中的1),否则为False(对应于0)。
  • 乘法操作:通过与输入x相乘,实现了如果x的绝对值小于等于\(\lambda\),则输出为0;否则,保持原值的效果。这正是Hard Shrink函数的定义。
  • 向量化操作:该实现支持向量化操作,意味着可以直接对单个数值、一维数组或多维数组应用此函数,无需显式循环,这对于处理整个数据批次非常高效。
示例使用

以下是如何使用定义的hard_shrink函数来计算一组输入值的Hard Shrink激活:

x = np.array([-1, -0.5, 0, 0.3, 0.8])
hard_shrink_values = hard_shrink(x, lambd=0.5)

print("Hard Shrink Values:", hard_shrink_values)

这段代码计算了数组x的Hard Shrink激活值。

三、Soft Shrink

Soft Shrink激活函数是深度学习中用于实现稀疏编码的一种激活函数,类似于Hard Shrink,但提供了一个平滑的过渡。它主要用于去噪和特征选择,通过引入一个固定的阈值来压缩输入值,促进输出的稀疏性。

1. 数学定义

Soft Shrink激活函数定义为:

SoftShrink ⁡ ( x ) = { x − λ  if  x > λ 0  if  − λ ≤ x ≤ λ x + λ  if  x < − λ \operatorname{SoftShrink}(x)= \begin{cases}x-\lambda & \text { if } x>\lambda \\ 0 & \text { if }-\lambda \leq x \leq \lambda \\ x+\lambda & \text { if } x<-\lambda\end{cases} SoftShrink(x)= xλ0x+λ if x>λ if λxλ if x<λ
其中, x x x是输入值, λ \lambda λ是预定义的非负阈值。
【DL经典回顾】激活函数大汇总(十)(Hard Shrink &amp; Soft Shrink附代码和详细公式)-LMLPHP

2. 函数特性

  • 平滑稀疏激活:与Hard Shrink提供突变的阈值不同,Soft Shrink通过平滑过渡减少输入值,更加平滑地促进输出的稀疏性。
  • 去噪能力:通过将小于阈值 λ \lambda λ的输入压缩到0,Soft Shrink有助于去除输入数据中的噪声。
  • 保留和增强重要特征:对于绝对值大于阈值 λ \lambda λ的输入,Soft Shrink通过减去或加上 λ \lambda λ来调整其值,有助于保留和增强重要的特征。

3. 导数

Soft Shrink函数的导数是分段常数:

d d x SoftShrink ⁡ ( x ) = { 1  if  ∣ x ∣ > λ 0  otherwise  \frac{d}{d x} \operatorname{SoftShrink}(x)= \begin{cases}1 & \text { if }|x|>\lambda \\ 0 & \text { otherwise }\end{cases} dxdSoftShrink(x)={10 if x>λ otherwise 
这意味着,在非零输出区间,梯度为1,允许梯度通过;在其它区间,梯度为0。

4. 使用场景与局限性

使用场景

  • 信号处理和去噪:Soft Shrink激活函数在处理含有微小噪声的信号时尤其有用,例如,在图像处理和音频去噪中。
  • 稀疏编码和特征选择:在需要促进数据稀疏性的应用中,如压缩和特征选择任务。

局限性

  • 信息可能丢失:虽然Soft Shrink有助于去噪和促进稀疏性,但对于接近阈值的输入,可能会导致一些重要信息的丢失。
  • 超参数敏感:Soft Shrink函数的效果很大程度上依赖于阈值 λ \lambda λ的选择,不合适的阈值可能会导致性能不佳。

5.代码实现

import numpy as np

def soft_shrink(x, lambd=0.5):
    """计算Soft Shrink激活函数的值。
    
    参数:
    x -- 输入值,可以是一个数值、NumPy数组或者多维数组。
    lambd -- 阈值,控制压缩强度,默认为0.5。
    
    返回:
    Soft Shrink激活后的结果。
    """
    return np.sign(x) * np.maximum(np.abs(x) - lambd, 0)
解读
  • 平滑减少:通过np.sign(x) * np.maximum(np.abs(x) - lambd, 0),当输入绝对值大于阈值 λ \lambda λ时,输入被减小 λ \lambda λ,否则设为0。这实现了Soft Shrink的平滑压缩效果。
  • 保持符号np.sign(x)保留了输入 x x x的符号,确保了压缩后的值保持原始输入的符号方向。
  • 支持向量化:该实现通过NumPy自然支持向量化操作,允许函数直接作用于整个数组,无需显式循环。
示例使用
x = np.array([-1.5, -0.5, 0, 0.5, 1.5])
soft_shrink_values = soft_shrink(x, lambd=0.5)

print("Soft Shrink Values:", soft_shrink_values)

这段代码展示了如何对一个包含正负值的数组应用Soft Shrink函数。

四、参考文献

  • Donoho, D. L., & Johnstone, I. M. (1994). “Ideal spatial adaptation by wavelet shrinkage.” biometrika, 81(3), 425-455. 这篇文章主要讨论了在小波变换领域的shrinkage技术,为Soft Shrink提供了理论基础。虽然它并非直接讨论Soft Shrink在深度学习中的应用,但其在信号处理中的使用为深度学习中的稀疏表示技术奠定了基础。
  • Tibshirani, R. (1996). “Regression shrinkage and selection via the lasso.” Journal of the Royal Statistical Society. Series B (Methodological). 这篇论文介绍了Lasso回归,一种利用稀疏性进行特征选择和正则化的技术。虽然它直接关注的是回归模型,但Lasso的核心概念与在深度学习模型中应用Soft Shrink的动机有着紧密的联系。
03-15 12:25