深入理解 PyTorch 激活函数:从基础到高效实用技巧(1)

发布时间:2024年01月16日

目录

torch.nn.functional激活层详解

threshold

1. 参数详解

2. 注意事项

3. 使用示例

threshold_

1. 参数详解

2. 注意事项

3. 使用示例

relu

1. 函数用途

2. 参数详解

3. 注意事项

4. 使用示例

relu_

1. 函数用途

2. 参数详解

3. 注意事项

4. 使用示例

hardtanh

1. 函数用途

2. 参数详解

3. 注意事项

4. 使用示例

hardtanh_

1. 函数用途

2. 参数详解

3. 注意事项

4. 使用示例

hardswish

1. 函数用途

2. 参数详解

3. 硬件激活函数的定义

4. 使用示例

relu6

1. 函数用途

2. 参数详解

3. ReLU6函数的定义

4. 使用示例

elu

1. 函数用途

2. 参数详解

3. ELU函数的定义

4. 使用示例

elu_

1. 函数用途

2. 参数详解

3. ELU函数的定义及数学解释

4. 使用示例

总结


torch.nn.functional激活层详解

threshold

torch.nn.functional.threshold 函数用于对输入张量(Tensor)进行阈值处理。此函数将输入张量中的每个元素与设定的阈值进行比较,并根据比较结果替换元素值。这在神经网络中用于实现激活函数,如ReLU激活函数,是非常常见的操作。

1. 参数详解

  • input:输入的张量。
  • threshold:阈值,一个浮点数。当输入张量的元素小于或等于这个阈值时,将被替换。
  • value:替换值,一个浮点数。当输入张量的元素小于或等于阈值时,将用这个值替换。
  • inplace:布尔值,默认为False。如果设置为True,将会直接在原始输入张量上进行修改,而不是创建一个新的张量。

2. 注意事项

  • inplace=True时,原始输入的张量将被修改,这可能会影响到张量的其他引用。
  • 使用不当可能导致梯度反向传播问题,特别是在训练深度学习模型时。
  • 在实际应用中,通常使用torch.nn.ReLU或者torch.nn.functional.relu作为ReLU激活函数,而不直接使用threshold函数。

3. 使用示例

import torch
import torch.nn.functional as F

# 创建一个示例张量
input_tensor = torch.tensor([-1.0, -0.5, 0.0, 0.5, 1.0])

# 应用threshold函数
# 设置阈值为0,替换值为0
output_tensor = F.threshold(input_tensor, threshold=0.0, value=0.0)

print("原始张量:", input_tensor)
print("处理后的张量:", output_tensor)

## 原始张量: tensor([-1.0000, -0.5000,  0.0000,  0.5000,  1.0000])
## 处理后的张量: tensor([0., 0., 0., 0.5000, 1.0000])

在这个示例中,所有小于或等于0的元素都被替换为0,模拟了ReLU激活函数的效果。

threshold_

torch.nn.functional.threshold_ 函数是 torch.nn.functional.threshold 的原地(in-place)版本。这意味着它会直接修改输入张量,而不是创建一个新的张量作为输出。这个函数用于将输入张量中小于或等于某个阈值的元素替换为指定的值。

1. 参数详解

  • input:输入的张量。需要注意的是,这个张量将会被直接修改。
  • threshold:阈值,一个浮点数。输入张量中小于或等于此阈值的元素将被替换。
  • value:替换值,一个浮点数。输入张量中小于或等于阈值的元素将被替换成这个值。

2. 注意事项

  • 使用threshold_函数会改变原始张量。在某些情况下,如果原始张量还有其他用途或引用,这可能不是一个好选择。
  • 在使用原地操作时,需要特别注意梯度计算和反向传播,因为它们可能会受到原地操作的影响,尤其是在神经网络训练中。

3. 使用示例

import torch
import torch.nn.functional as F

# 创建一个示例张量
input_tensor = torch.tensor([-1.0, -0.5, 0.0, 0.5, 1.0])

# 原地应用threshold_函数
# 设置阈值为0,替换值为0
F.threshold_(input_tensor, threshold=0.0, value=0.0)

print("处理后的张量:", input_tensor)

## 处理后的张量: tensor([0., 0., 0., 0.5000, 1.0000])

在这个示例中,所有小于或等于0的元素都被替换为0,模拟了ReLU激活函数的效果,同时直接修改了原始张量。

relu

torch.nn.functional.relu 是 PyTorch 中实现的一个函数,用于应用逐元素的修正线性单元(Rectified Linear Unit,ReLU)激活函数。ReLU 函数是深度学习中非常常见的激活函数,特别适用于卷积神经网络和全连接层。

1. 函数用途

ReLU 激活函数的主要作用是增加网络的非线性。在不同的神经元上应用ReLU可以帮助网络学习复杂的模式。ReLU 函数的数学表达式是 f(x) = max(0, x),即如果输入是正数,则输出该数;如果输入是负数,则输出0。

2. 参数详解

  • input(Tensor):输入的张量。
  • inplace(bool,默认为False):是否进行原地操作。如果为True,将会直接在输入张量上修改,不创建新的张量。

3. 注意事项

  • inplace=True时,原始输入的张量将被修改。这可能会影响到张量的其他引用。
  • ReLU函数在处理负数输入时输出为0,这可能导致神经网络的某些部分在训练过程中“死亡”(即不再更新)。
  • ReLU通常在隐藏层中使用,而不是在网络的输出层。

4. 使用示例

import torch
import torch.nn.functional as F

# 创建一个示例张量
input_tensor = torch.tensor([-1.0, -0.5, 0.0, 0.5, 1.0])

# 应用ReLU激活函数
output_tensor = F.relu(input_tensor)

print("原始张量:", input_tensor)
print("ReLU处理后的张量:", output_tensor)

## 原始张量: tensor([-1.0000, -0.5000,  0.0000,  0.5000,  1.0000])
## ReLU处理后的张量: tensor([0.0000, 0.0000, 0.0000, 0.5000, 1.0000])

在这个示例中,所有小于0的元素都被置为0,而正数元素保持不变。

relu_

torch.nn.functional.relu_torch.nn.functional.relu 函数的原地(in-place)版本,在 PyTorch 框架中用于应用修正线性单元(Rectified Linear Unit, ReLU)激活函数。与普通的 relu 函数相比,relu_ 函数直接在输入的张量上进行修改,而不返回一个新的修改过的张量。这有助于减少内存使用,特别是在处理大型神经网络时。

1. 函数用途

ReLU 激活函数是深度学习中非常流行的激活函数之一,用于增加神经网络模型的非线性。在数学上,它的定义是 f(x) = max(0, x),即输入值小于0时输出为0,大于等于0时输出值不变。

2. 参数详解

  • input(Tensor):输入的张量。

由于这是一个原地操作函数,它没有inplace参数,因为其默认行为就是在原地修改输入的张量。

3. 注意事项

  • 使用原地操作的函数时,需要特别注意,因为它们会修改输入张量。在一些情况下,这可能导致意外的副作用,特别是在计算图的梯度传播时。
  • 原地操作在节省内存方面有优势,但也需要谨慎使用,以避免数据被意外更改。

4. 使用示例

import torch
import torch.nn.functional as F

# 创建一个示例张量
input_tensor = torch.tensor([-1.0, -0.5, 0.0, 0.5, 1.0])

# 原地应用ReLU激活函数
F.relu_(input_tensor)

print("处理后的张量:", input_tensor)

# 处理后的张量: tensor([0.0000, 0.0000, 0.0000, 0.5000, 1.0000])

hardtanh

torch.nn.functional.hardtanh 是 PyTorch 框架中的一个函数,用于应用逐元素的 HardTanh (硬双曲正切) 函数。HardTanh 是传统 Tanh 激活函数的分段线性近似,常用于深度学习中,特别是在需要更快的计算和简化的场景中。

1. 函数用途

HardTanh 激活函数类似于传统的 Tanh 函数,但在处理输入时更为简单和高效。它将输入张量中的每个元素限制在指定的最小值和最大值之间。具体来说,如果元素值小于最小值,则被设置为最小值;如果元素值大于最大值,则被设置为最大值;否则保持不变。

2. 参数详解

  • input(Tensor):输入的张量。
  • min_val(float,默认为-1.0):硬限制的最小值。
  • max_val(float,默认为1.0):硬限制的最大值。
  • inplace(bool,默认为False):是否进行原地操作。如果为True,则直接在输入张量上修改,而不是创建一个新的张量。

3. 注意事项

  • 使用原地操作 (inplace=True) 时需谨慎,因为它会修改输入张量的值。
  • HardTanh 在一些特定场景中(如简化的神经网络模型)可以作为传统 Tanh 函数的替代品。
  • 由于它是一个分段线性函数,因此在某些应用中可能无法捕获输入数据的复杂性。

4. 使用示例

import torch
import torch.nn.functional as F

# 创建一个示例张量
input_tensor = torch.tensor([-2.0, -1.0, 0.0, 1.0, 2.0])

# 应用HardTanh激活函数
output_tensor = F.hardtanh(input_tensor, min_val=-1.0, max_val=1.0)

print("原始张量:", input_tensor)
print("HardTanh处理后的张量:", output_tensor)

## 原始张量: tensor([-2.0000, -1.0000,  0.0000,  1.0000,  2.0000])
## HardTanh处理后的张量: tensor([-1.0000, -1.0000,  0.0000,  1.0000,  1.0000])

在这个示例中,所有小于-1的元素被设置为-1,所有大于1的元素被设置为1,其余元素保持不变。?

hardtanh_

torch.nn.functional.hardtanh_ 是 PyTorch 中 torch.nn.functional.hardtanh 函数的原地(in-place)版本。这个函数用于将输入张量中的每个元素限制在指定的最小值和最大值之间,但与标准的 hardtanh 不同的是,它直接在输入张量上修改,而不返回一个新的修改过的张量。

1. 函数用途

hardtanh_ 函数应用了分段线性的硬双曲正切激活函数(HardTanh)。这种激活函数在神经网络中用于引入非线性,同时由于其简化的性质,通常计算速度更快,且在某些场景下更有效。

2. 参数详解

  • input(Tensor):要进行处理的输入张量。
  • min_val(float,默认为-1.0):硬限制的最小值。
  • max_val(float,默认为1.0):硬限制的最大值。

由于 hardtanh_ 是一个原地操作函数,因此它没有 inplace 参数,因为其默认行为就是在原地修改输入的张量。

3. 注意事项

  • 使用原地操作函数时,原始输入张量将被直接修改。这在一些场景中可能导致数据损坏或意外的副作用。
  • 由于原地操作可以减少内存占用和提高性能,但同时也需要更加谨慎地处理数据。

4. 使用示例

import torch
import torch.nn.functional as F

# 创建一个示例张量
input_tensor = torch.tensor([-2.0, -1.0, 0.0, 1.0, 2.0])

# 原地应用HardTanh激活函数
F.hardtanh_(input_tensor, min_val=-1.0, max_val=1.0)

print("处理后的张量:", input_tensor)

## 处理后的张量: tensor([-1.0000, -1.0000,  0.0000,  1.0000,  1.0000])

在这个示例中,所有小于-1的元素被设置为-1,所有大于1的元素被设置为1,而中间的元素保持不变。请注意,input_tensor 的原始值已被修改。?

hardswish

torch.nn.functional.hardswish 是 PyTorch 中的一个函数,用于逐元素地应用 HardSwish 激活函数。这个函数是在论文 "Searching for MobileNetV3" 中描述的 Swish 函数的简化版本,它通过对输入张量中的元素进行特定的非线性变换来提高网络的性能和效率。

1. 函数用途

HardSwish 激活函数是一种高效的激活函数,它在保持类似于 Swish 函数性质的同时,减少了计算复杂度。这使得它特别适用于移动和轻量级网络,如 MobileNetV3。

2. 参数详解

  • input(Tensor):输入的张量。
  • inplace(bool,默认为False):是否进行原地操作。如果为True,则直接在输入张量上修改,而不是创建一个新的张量。

3. 硬件激活函数的定义

HardSwish 激活函数的数学表达式是:

  • 当 x ≤ -3,HardSwish(x) = 0
  • 当 x ≥ +3,HardSwish(x) = x
  • 否则,HardSwish(x) = x * (x + 3) / 6

4. 使用示例

import torch
import torch.nn.functional as F

# 创建一个示例张量
input_tensor = torch.tensor([-4.0, -3.0, 0.0, 3.0, 4.0])

# 应用HardSwish激活函数
output_tensor = F.hardswish(input_tensor)

# 输出结果
print("原始张量:", input_tensor)
print("HardSwish处理后的张量:", output_tensor)
# 输出将是:
# 原始张量: tensor([-4.0000, -3.0000,  0.0000,  3.0000,  4.0000])
# HardSwish处理后的张量: tensor([0.0000, 0.0000, 0.0000, 3.0000, 4.0000])

在这个示例中,张量中小于等于-3的元素被转换为0,大于等于3的元素保持不变,介于-3和3之间的元素按照 HardSwish 函数的定义进行转换。?

relu6

torch.nn.functional.relu6 是 PyTorch 框架中的一个函数,用于逐元素地应用 ReLU6 激活函数。ReLU6 是传统 ReLU (Rectified Linear Unit) 函数的变体,它在激活后将输出限制在 0 到 6 的范围内。

1. 函数用途

ReLU6 激活函数主要用于深度学习模型中,以增加网络的非线性,同时限制激活函数的输出不超过特定的上限(在这个情况下是 6)。这种限制有助于在一定程度上防止梯度消失和爆炸问题,特别是在训练深层网络时。

2. 参数详解

  • input(Tensor):输入的张量。
  • inplace(bool,默认为False):是否进行原地操作。如果为True,则直接在输入张量上修改,而不是创建一个新的张量。

3. ReLU6函数的定义

ReLU6 激活函数的数学表达式是:

  • ReLU6(x) = min(max(0, x), 6)

这意味着,如果输入 x 小于 0,输出为 0;如果输入 x 大于 6,输出为 6;否则输出为 x 本身。

4. 使用示例

import torch
import torch.nn.functional as F

# 创建一个示例张量
input_tensor = torch.tensor([-2.0, 0.0, 2.0, 6.0, 8.0])

# 应用ReLU6激活函数
output_tensor = F.relu6(input_tensor)

# 输出结果
print("原始张量:", input_tensor)
print("ReLU6处理后的张量:", output_tensor)
# 输出将是:
# 原始张量: tensor([-2.0000,  0.0000,  2.0000,  6.0000,  8.0000])
# ReLU6处理后的张量: tensor([0., 0., 2., 6., 6.])

在这个示例中,所有小于0的元素都被转换为0,所有大于6的元素被限制在6,其余元素保持不变。?

elu

torch.nn.functional.elu 是 PyTorch 框架中的一个函数,用于按元素应用指数线性单元(Exponential Linear Unit, 简称ELU)激活函数。

1. 函数用途

ELU 激活函数是一种常用于深度神经网络的非线性激活函数。与 ReLU 激活函数相比,ELU 通过引入负值,可以帮助减少神经元输出的平均值接近零,从而减少所谓的梯度消失问题。这有助于在某些情况下加速模型的学习速度。

2. 参数详解

  • input(Tensor):输入的张量。
  • alpha(float,默认为1.0):ELU 激活函数的α值。这个参数定义了当输入小于零时激活函数的饱和值。
  • inplace(bool,默认为False):是否进行原地操作。如果为True,则直接在输入张量上修改,而不是创建一个新的张量。

3. ELU函数的定义

ELU 激活函数的数学表达式是:

  • 当 x > 0 时,ELU(x) = x
  • 当 x ≤ 0 时,ELU(x) = α * (exp(x) - 1)

这个函数的目的是在保持 ReLU 正值特性的同时,为负输入值提供一个平滑的饱和转换。

4. 使用示例

import torch
import torch.nn.functional as F

# 创建一个示例张量
input_tensor = torch.tensor([-2.0, 0.0, 2.0])

# 应用ELU激活函数
output_tensor = F.elu(input_tensor, alpha=1.0)

# 输出结果
print("原始张量:", input_tensor)
print("ELU处理后的张量:", output_tensor)
# 输出将是:
# 原始张量: tensor([-2.0000,  0.0000,  2.0000])
# ELU处理后的张量: tensor([-0.8647,  0.0000,  2.0000])

在这个示例中,正值保持不变,而负值按照 ELU 函数的定义进行转换。?

elu_

torch.nn.functional.elu_ 是 PyTorch 中 torch.nn.functional.elu 函数的原地(in-place)版本。这个函数用于按元素应用指数线性单元(Exponential Linear Unit, ELU)激活函数,但与标准的 elu 函数不同的是,它直接在输入张量上进行修改,而不是返回一个新的修改过的张量。

1. 函数用途

ELU 激活函数是深度学习中用于增加网络非线性的常用激活函数。它与ReLU相似,但对负输入值提供了平滑的饱和转换,这有助于减少梯度消失问题,并改善模型训练过程中的数值稳定性。

2. 参数详解

  • input(Tensor):要进行处理的输入张量。
  • alpha(float,默认为1.0):ELU 激活函数的α值。这个参数定义了当输入小于零时激活函数的饱和值。

由于 elu_ 是一个原地操作函数,因此它没有 inplace 参数,因为其默认行为就是在原地修改输入的张量。

3. ELU函数的定义及数学解释

ELU 激活函数的数学表达式是:

  • 当 x > 0 时,ELU(x) = x
  • 当 x ≤ 0 时,ELU(x) = α * (exp(x) - 1)

这里的 exp(x) 表示 x 的指数函数 e^x(e 是自然对数的底数)。对于负值的输入,ELU函数提供了一个平滑的曲线,当输入值为负且非常小(接近负无穷)时,输出趋向于 -α,为负饱和状态。这避免了

ReLU函数在负值输入时的硬饱和(即输出为零),从而允许负值信息在一定程度上传递,有助于缓解神经网络训练过程中的梯度消失问题。

4. 使用示例

import torch
import torch.nn.functional as F

# 创建一个示例张量
input_tensor = torch.tensor([-2.0, 0.0, 2.0])

# 原地应用ELU激活函数
F.elu_(input_tensor, alpha=1.0)

# 输出结果
print("ELU处理后的张量:", input_tensor)
# 输出将是:
# ELU处理后的张量: tensor([-0.8647,  0.0000,  2.0000])

在这个示例中,正值保持不变,而负值按照 ELU 函数的定义进行转换。需要注意的是,由于 elu_ 是原地操作,input_tensor 的原始值已被修改。

这种原地操作的函数在处理大型数据集时尤其有用,因为它们可以减少内存的使用量。然而,也要小心使用,以避免不必要的数据修改。

总结

本篇博客探讨了 PyTorch 框架中多种重要的激活函数,包括 threshold、threshold_、relu、relu_、hardtanh、hardtanh_、hardswish、relu6、elu 和 elu_。每种激活函数都有其独特的用途和特性,旨在增强深度学习模型的非线性表达能力。我们通过详细解释每个函数的参数、用途和实际使用示例,提供了对这些激活函数深入理解的机会。特别注意到了原地(in-place)版本的函数,如 threshold_、relu_、hardtanh_ 和 elu_,它们在修改输入张量时节省内存,但需要谨慎使用以避免潜在的数据损坏风险。

文章来源:https://blog.csdn.net/qq_42452134/article/details/135615486
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。