您的神经网络是否一直卡在 60% 的准确率,怎么调都不见好?
您调过学习率、加过层数、也尝试了不同的批大小,但都无济于事。训练损失在头几个 epoch 后几乎不再下降。您开始怀疑整套方案:也许数据不好、也许架构不对。但真正的问题在于,您的激活函数把输出都推向了同一侧,使得网络无法学习到平衡的模式。
Tanh(双曲正切)通过将输出居中于零、范围在 -1 到 1 之间来解决这一问题。这能帮助模型更快收敛,并在反向传播时让梯度以对称的方式流动。
在本文中,您将了解 tanh 是什么、其数学机理、何时优于 ReLU 或 sigmoid,以及如何在 PyTorch 中实现它。如果您是深度学习新手,建议先阅读我们的深入指南:神经网络中的激活函数 。
什么是 Tanh 函数?
tanh 函数将任意输入映射到 -1 与 1 之间的数值。
它是一条平滑的 S 形曲线,由以下公式定义:
Tanh 函数。图片来源:作者
该函数在极端输入下行为可预期:当输入是一个很大的正数时,输出接近 1;当输入是一个很大的负数时,输出接近 -1。
在零附近,tanh 近似线性。这意味着在反向传播 过程中,梯度能够顺畅流动,而不会被压扁或扭曲。
相比之下,sigmoid 只输出 0 到 1 的正值;tanh 则输出正负两侧的值。它让激活以零为中心保持平衡,这在许多网络架构中有助于更快收敛。
tanh 最常用于循环网络,以及任何需要居中激活以提高稳定性的场景。
数学与计算特性
tanh 有一些每位机器学习工程师都应了解的数学特性。
平滑且可微
tanh 在各处都是无限可微且光滑的。
这对基于梯度的优化至关重要。您不会像使用 ReLU 那样遇到尖角,后者的导数会在 0 与 1 之间瞬间跳变。平滑的梯度意味着在反向传播中更加可预期的权重更新。
零中心输出
Sigmoid 的输出介于 0 到 1;tanh 的输出介于 -1 到 1。
当激活围绕零保持平衡时,网络收敛更快。权重更新不会向某一侧偏置,梯度也能在各层间更均匀地流动。
有界且稳定
tanh 的输出范围固定在 -1 到 1 之间。
有界性可防止数值不稳定。如果您使用的网络无法处理激活爆炸,tanh 能在无需裁剪或特殊处理的情况下将其控制住。
极端处的行为
对于较大的正值,tanh 趋近于 1;对于较大的负值,则趋近于 -1。
这种对称性让激活保持居中,避免了像 sigmoid 这类非零中心函数所产生的偏置偏移。在深层网络中,这一特性有助于权重更新在各层间更均匀地传播——网络不会对正值或负值产生偏好。
tanh 的导数
tanh 的导数为:
Tanh 的导数。图片来源:作者。
这意味着在零附近梯度较强,而在函数饱和的边缘会变小。当 tanh(x) 接近 1 或 -1 时,导数趋近于零,从而减慢这些神经元的学习。
在实践中,您会在中等输入范围内获得稳定学习,而当输入过大或过小时可能出现梯度消失。这也是深层网络常偏好 ReLU 的原因——它在正值上不会饱和。
Tanh 与其他函数对比
tanh 并非唯一的激活函数,了解它与替代方案的对比,有助于为您的网络选择合适的函数。
Sigmoid 与 tanh 关系密切。事实上,tanh 只是 sigmoid 的缩放和平移版本:
其中 σ(x) 为 sigmoid 函数。
Sigmoid 函数。图片来源:作者
关键差异在于,Sigmoid 的输出介于 0 到 1,而 tanh 的输出介于 -1 到 1。这个零中心特性让 tanh 在多数情况下收敛更快。
ReLU 采用不同的方法。对负输入输出 0,对正输入则原样传递。这带来稀疏性——许多神经元保持不激活,从而加速训练。但 ReLU 会在负值上“杀死”梯度。tanh 不存在此问题,因为它对负输入仍保持非零梯度。不过它在两端都会饱和,当输入过大或过小时可能减慢学习。
ReLU 函数。图片来源:作者
Softsign 看起来与 tanh 相似,二者都是平滑的 S 形曲线。但 tanh 在零附近收敛更快,因为其斜率更陡。这意味着在训练早期能获得更强的梯度,有助于在输入尚未进入饱和区之前更快学习。
Softsign 函数。图片来源:作者
以上对这些激活函数只是浅尝辄止。如果您对 Tanh 与 ReLU 的替代方案感兴趣,请阅读我们关于 sSoftmax 和 Softplus 的深入指南。
Tanh 的优势
如果您在考虑是否值得尝试 Tanh,下面这些优势或许能帮助您在最终获得更准确的模型。
零中心输出
tanh 产生以零为中心的平衡输出。
这能减少权重更新的偏置。当激活围绕零分布而不是像 sigmoid 那样全部偏正时,梯度不会将权重更多地拉向某一侧。结果就是更快的收敛与更稳定的训练。
零附近梯度更强
tanh 在零附近斜率较陡。
与 sigmoid 相比,这意味着反向传播时的梯度更强。当大多数激活位于零附近时,网络在训练早期会学得更快;相反,sigmoid 的斜率更缓,使得初期更新更弱、更慢。
平滑的梯度流
tanh 的导数在各处连续。
没有突变或不连续点。与 ReLU 等分段函数相比,这带来更稳定的优化过程;ReLU 在零点附近导数会从 0 突然切换到 1。平滑的梯度意味着训练过程中的权重更新更可预期。
适合循环网络
RNN、LSTM 和 GRU 的隐藏层通常依赖 tanh。
这些架构需要在时间步之间维持平滑的内部状态。tanh 允许正负信号同时流动并保持值有界。这种平衡既能避免激活爆炸,又有助于网络在更长序列上保留信息。
局限与取舍
在动手写代码之前,我们先看看 Tanh 可能存在的几个短板。
梯度消失
当输入远离零时,梯度会趋近于零。
这是由于 tanh 在 -1 与 1 处饱和所致。一旦激活达到这些极值,导数会变得极小,权重更新也会极其缓慢。在非常深的网络中,这个问题会被层层叠加,因为梯度在每一层反传时都会缩小,直到学习几乎停止。
训练更慢
tanh 不会产生稀疏性。
与 ReLU 在负输入时输出为零不同,tanh 几乎所有神经元都会在某种程度上保持激活。这意味着每次前向传播要处理更多信息,听起来不错,但实际上会拖慢速度。ReLU 的稀疏性能加速训练,因为不激活的神经元会完全跳过计算。
硬件优化较少
现代框架与硬件加速器更偏好 ReLU。
tanh 运算涉及指数函数,计算开销比 ReLU 的简单 max(0, x) 更大。GPU 内核与专用 AI 芯片常针对 ReLU 优化,因为它已成为大多数架构中的默认选择。这意味着即使网络架构相同,tanh 在相同硬件上运行也会更慢。
PyTorch 中的 Tanh
PyTorch 原生提供了 Tanh 的实现,您无需从头编写。
以下是在一个简单神经网络中将其用作激活函数的方法:
import torch
import torch. nn as nn
model = nn. Sequential(
nn. Linear( 10 , 20 ) ,
nn. Tanh( ) ,
nn. Linear( 20 , 1 )
)
x = torch. randn( 5 , 10 )
output = model( x)
print ( output) 技术支持
tensor( [ [ 0.0910 ] ,
[ - 0.0994 ] ,
[ - 0.0583 ] ,
[ - 0.2177 ] ,
[ - 0.2546 ] ] , grad_fn= < AddmmBackward0> ) 技术支持
您也可以直接对张量应用 tanh:
x = torch. tensor( [ - 2.0 , - 1.0 , 0.0 , 1.0 , 2.0 ] )
output = torch. tanh( x)
print ( output) 技术支持
tensor( [ - 0.9640 , - 0.7616 , 0.0000 , 0.7616 , 0.9640 ] ) 技术支持
请注意输出如何围绕零对称——负输入产生负输出,函数在两侧的处理是等价的。这种平衡的分布能在训练期间保持网络稳定,并避免像 sigmoid 那样的偏置偏移。
何时使用 Tanh
当您的模型从居中激活中获益,或当您在处理中小型或循环网络时,可选择 Tanh 函数。
它在以下情境中特别有效:
您在训练 RNN 或 LSTM ,需要平衡的激活。这些架构依赖 Tanh 在时间步之间维持平滑的内部状态,同时允许正负信号通过。
您在建模连续或平滑的目标。 tanh 的平滑梯度流适用于输出需要连续且有界的情形,例如预测自然落在某个范围内的数值。
您需要稳定、可微的梯度,但不需要 ReLU 的稀疏性。 如果您的网络不够深,难以从 ReLU 的速度优势中获益,tanh 能带来更可预期的训练行为。
相反,在非常深的架构中应避免使用 tanh,因为梯度消失风险更大。那时 ReLU 或 GELU 更合适,因为它们在正值上不会饱和。
结语
总而言之,Tanh 介于 Sigmoid 的简洁与 ReLU 的速度之间。
它平滑、对称,并且在深度学习中仍然适用,尤其是在需要平衡激活的场景中。尽管不是每个现代架构都会用到它,但当您需要以零为中心的输出和稳定的梯度流时,它自有一席之地。
如果您拿不准是否使用 Tanh,可遵循以下原则:
大型、深层网络用 ReLU。 它更快、与现代硬件契合度更高,并且在正值上避免梯度消失。
当您需要稳定性、对称性与更平滑的梯度流时用 Tanh。 如循环网络、更小的架构,以及零中心激活能提升收敛的情形。
动手做实验、比较结果,让数据来决定哪种激活函数最适合您的任务。 想要了解更多?报名我们的 Machine Learning Scientist in Python 学习路径,系统掌握监督学习、无监督学习与深度学习的要点。
您的神经网络是否一直卡在 60% 的准确率,怎么调都不见好?
您调过学习率、加过层数、也尝试了不同的批大小,但都无济于事。训练损失在头几个 epoch 后几乎不再下降。您开始怀疑整套方案:也许数据不好、也许架构不对。但真正的问题在于,您的激活函数把输出都推向了同一侧,使得网络无法学习到平衡的模式。
Tanh(双曲正切)通过将输出居中于零、范围在 -1 到 1 之间来解决这一问题。这能帮助模型更快收敛,并在反向传播时让梯度以对称的方式流动。
在本文中,您将了解 tanh 是什么、其数学机理、何时优于 ReLU 或 sigmoid,以及如何在 PyTorch 中实现它。如果您是深度学习新手,建议先阅读我们的深入指南:神经网络中的激活函数。
什么是 Tanh 函数?
tanh 函数将任意输入映射到 -1 与 1 之间的数值。
它是一条平滑的 S 形曲线,由以下公式定义:
Tanh 函数。图片来源:作者
该函数在极端输入下行为可预期:当输入是一个很大的正数时,输出接近 1;当输入是一个很大的负数时,输出接近 -1。
在零附近,tanh 近似线性。这意味着在反向传播过程中,梯度能够顺畅流动,而不会被压扁或扭曲。
相比之下,sigmoid 只输出 0 到 1 的正值;tanh 则输出正负两侧的值。它让激活以零为中心保持平衡,这在许多网络架构中有助于更快收敛。
tanh 最常用于循环网络,以及任何需要居中激活以提高稳定性的场景。
数学与计算特性
tanh 有一些每位机器学习工程师都应了解的数学特性。
平滑且可微
tanh 在各处都是无限可微且光滑的。
这对基于梯度的优化至关重要。您不会像使用 ReLU 那样遇到尖角,后者的导数会在 0 与 1 之间瞬间跳变。平滑的梯度意味着在反向传播中更加可预期的权重更新。
零中心输出
Sigmoid 的输出介于 0 到 1;tanh 的输出介于 -1 到 1。
当激活围绕零保持平衡时,网络收敛更快。权重更新不会向某一侧偏置,梯度也能在各层间更均匀地流动。
有界且稳定
tanh 的输出范围固定在 -1 到 1 之间。
有界性可防止数值不稳定。如果您使用的网络无法处理激活爆炸,tanh 能在无需裁剪或特殊处理的情况下将其控制住。
极端处的行为
对于较大的正值,tanh 趋近于 1;对于较大的负值,则趋近于 -1。
这种对称性让激活保持居中,避免了像 sigmoid 这类非零中心函数所产生的偏置偏移。在深层网络中,这一特性有助于权重更新在各层间更均匀地传播——网络不会对正值或负值产生偏好。
tanh 的导数
tanh 的导数为:
Tanh 的导数。图片来源:作者。
这意味着在零附近梯度较强,而在函数饱和的边缘会变小。当 tanh(x) 接近 1 或 -1 时,导数趋近于零,从而减慢这些神经元的学习。
在实践中,您会在中等输入范围内获得稳定学习,而当输入过大或过小时可能出现梯度消失。这也是深层网络常偏好 ReLU 的原因——它在正值上不会饱和。
Tanh 与其他函数对比
tanh 并非唯一的激活函数,了解它与替代方案的对比,有助于为您的网络选择合适的函数。
Sigmoid 与 tanh 关系密切。事实上,tanh 只是 sigmoid 的缩放和平移版本:
其中 σ(x) 为 sigmoid 函数。
Sigmoid 函数。图片来源:作者
关键差异在于,Sigmoid 的输出介于 0 到 1,而 tanh 的输出介于 -1 到 1。这个零中心特性让 tanh 在多数情况下收敛更快。
ReLU 采用不同的方法。对负输入输出 0,对正输入则原样传递。这带来稀疏性——许多神经元保持不激活,从而加速训练。但 ReLU 会在负值上“杀死”梯度。tanh 不存在此问题,因为它对负输入仍保持非零梯度。不过它在两端都会饱和,当输入过大或过小时可能减慢学习。
ReLU 函数。图片来源:作者
Softsign 看起来与 tanh 相似,二者都是平滑的 S 形曲线。但 tanh 在零附近收敛更快,因为其斜率更陡。这意味着在训练早期能获得更强的梯度,有助于在输入尚未进入饱和区之前更快学习。
Softsign 函数。图片来源:作者
以上对这些激活函数只是浅尝辄止。如果您对 Tanh 与 ReLU 的替代方案感兴趣,请阅读我们关于sSoftmax 和 Softplus 的深入指南。
Tanh 的优势
如果您在考虑是否值得尝试 Tanh,下面这些优势或许能帮助您在最终获得更准确的模型。
零中心输出
tanh 产生以零为中心的平衡输出。
这能减少权重更新的偏置。当激活围绕零分布而不是像 sigmoid 那样全部偏正时,梯度不会将权重更多地拉向某一侧。结果就是更快的收敛与更稳定的训练。
零附近梯度更强
tanh 在零附近斜率较陡。
与 sigmoid 相比,这意味着反向传播时的梯度更强。当大多数激活位于零附近时,网络在训练早期会学得更快;相反,sigmoid 的斜率更缓,使得初期更新更弱、更慢。
平滑的梯度流
tanh 的导数在各处连续。
没有突变或不连续点。与 ReLU 等分段函数相比,这带来更稳定的优化过程;ReLU 在零点附近导数会从 0 突然切换到 1。平滑的梯度意味着训练过程中的权重更新更可预期。
适合循环网络
RNN、LSTM 和 GRU 的隐藏层通常依赖 tanh。
这些架构需要在时间步之间维持平滑的内部状态。tanh 允许正负信号同时流动并保持值有界。这种平衡既能避免激活爆炸,又有助于网络在更长序列上保留信息。
局限与取舍
在动手写代码之前,我们先看看 Tanh 可能存在的几个短板。
梯度消失
当输入远离零时,梯度会趋近于零。
这是由于 tanh 在 -1 与 1 处饱和所致。一旦激活达到这些极值,导数会变得极小,权重更新也会极其缓慢。在非常深的网络中,这个问题会被层层叠加,因为梯度在每一层反传时都会缩小,直到学习几乎停止。
训练更慢
tanh 不会产生稀疏性。
与 ReLU 在负输入时输出为零不同,tanh 几乎所有神经元都会在某种程度上保持激活。这意味着每次前向传播要处理更多信息,听起来不错,但实际上会拖慢速度。ReLU 的稀疏性能加速训练,因为不激活的神经元会完全跳过计算。
硬件优化较少
现代框架与硬件加速器更偏好 ReLU。
tanh 运算涉及指数函数,计算开销比 ReLU 的简单 max(0, x) 更大。GPU 内核与专用 AI 芯片常针对 ReLU 优化,因为它已成为大多数架构中的默认选择。这意味着即使网络架构相同,tanh 在相同硬件上运行也会更慢。
PyTorch 中的 Tanh
PyTorch 原生提供了 Tanh 的实现,您无需从头编写。
以下是在一个简单神经网络中将其用作激活函数的方法:
您也可以直接对张量应用 tanh:
请注意输出如何围绕零对称——负输入产生负输出,函数在两侧的处理是等价的。这种平衡的分布能在训练期间保持网络稳定,并避免像 sigmoid 那样的偏置偏移。
何时使用 Tanh
当您的模型从居中激活中获益,或当您在处理中小型或循环网络时,可选择 Tanh 函数。
它在以下情境中特别有效:
相反,在非常深的架构中应避免使用 tanh,因为梯度消失风险更大。那时 ReLU 或 GELU 更合适,因为它们在正值上不会饱和。
结语
总而言之,Tanh 介于 Sigmoid 的简洁与 ReLU 的速度之间。
它平滑、对称,并且在深度学习中仍然适用,尤其是在需要平衡激活的场景中。尽管不是每个现代架构都会用到它,但当您需要以零为中心的输出和稳定的梯度流时,它自有一席之地。
如果您拿不准是否使用 Tanh,可遵循以下原则:
动手做实验、比较结果,让数据来决定哪种激活函数最适合您的任务。 想要了解更多?报名我们的 Machine Learning Scientist in Python 学习路径,系统掌握监督学习、无监督学习与深度学习的要点。