神经网络——非线性激活

目录

非线性激活

非线性激活代码举例(ReLU)

综合代码案例


非线性激活

在神经网络中,非线性激活函数是核心组件之一,它赋予了神经网络拟合复杂非线性关系的能力。如果没有非线性激活函数,无论神经网络有多少层,最终都只能实现线性映射,无法处理图像识别、自然语言处理等复杂任务。

在神经网络中,"激活函数" 的名称源于神经科学的类比,它模拟了生物神经元的 "激活" 机制。

激活函数的核心功能是:

  1. 引入非线性:让神经网络能拟合复杂函数(如 异或问题)
  2. 控制信号传递:决定哪些信息被增强(高激活)、哪些被抑制(低激活)
  3. 归一化输出:将输入映射到特定范围(如 Sigmoid 的 (0,1)、Tanh 的 (-1,1))

为什么需要非线性激活?

神经网络的本质是通过 "线性变换 + 激活" 的堆叠来学习数据规律:

  • 线性变换(如 y = Wx + b)只能表示直线(或高维空间中的超平面),无法拟合曲线、分类边界不规则的数据(比如 "异或问题")。
  • 激活函数通过非线性变换,让神经网络可以组合多个线性变换结果,最终形成任意复杂的非线性函数。

简单说:没有非线性激活,神经网络就退化为 "多层线性回归",失去深度的意义


常见的非线性激活函数

不同激活函数有不同的特性,适用场景也不同。以下是最常用的几种:

  1. ReLU(Rectified Linear Unit,修正线性单元)
  • 公式f(x) = max(0, x)

  • 特性

    • 计算简单(仅判断是否为正),训练速度快;

    • 解决了早期 "Sigmoid 梯度消失" 问题(正区间梯度为 1,不衰减);

  • 缺点

    • "死亡 ReLU 问题":当输入长期为负时,神经元会永久 "失效"(梯度为 0,无法更新);
  • 适用场景:几乎所有深度学习模型的默认选择(尤其是卷积神经网络 CNN)。

  1. Sigmoid
  • 公式f(x) = 1 / (1 + e^(-x))

  • 特性

    • 输出范围在 (0,1) 之间,可表示 "概率"(如二分类的预测概率);

    • 非线性平滑,适合早期浅层网络;

  • 缺点

    • 梯度消失:当 x 很大或很小时,导数接近 0,深层网络中参数难以更新;

    • 输出非零均值(偏向 0.5),可能影响训练稳定性;

  • 适用场景:仅用于二分类任务的输出层(如判断 "是 / 否")。

  1. Tanh(双曲正切)
  • 公式f(x) = (e^x - e^(-x)) / (e^x + e^(-x))(输出范围 (-1,1))

  • 特性

    • 解决了 Sigmoid 的 "非零均值" 问题(输出以 0 为中心);

    • 非线性更强,适合浅层网络的隐藏层;

  • 缺点

    • 仍存在梯度消失问题(x 绝对值大时,导数接近 0);
  • 适用场景:循环神经网络(RNN)的早期版本,或对输出对称性有要求的场景。

  1. Leaky ReLU(带泄漏的 ReLU)
  • 公式f(x) = max(αx, x)(α 通常取 0.01,即 x<0 时输出 0.01x)

  • 特性

    • 解决了 ReLU 的 "死亡神经元" 问题(负区间保留微小梯度);

    • 计算简单,性能通常优于 ReLU;

  • 缺点:α 是超参数,需要手动调整;

  • 适用场景:替代 ReLU 的常用选择(尤其当训练中出现大量死亡神经元时)。

  1. Swish
  • 公式f(x) = x * sigmoid(βx)(β 是可训练参数或固定值)

  • 特性

    • 平滑的非线性函数,负区间有微小输出(类似 Leaky ReLU,但更平滑);

    • 在深层网络(如 ResNet)中表现常优于 ReLU;

  • 适用场景:需要更高精度的深层模型。

  1. Softmax
  • 公式f(x_i) = e^x_i / Σ(e^x_j)(对所有输入归一化,输出和为 1)

  • 特性

    • 将多分类的 "得分" 转换为概率分布(如判断图像是 "猫 / 狗 / 鸟" 的概率);
  • 适用场景:多分类任务的输出层。


激活函数的选择原则

  1. 隐藏层:优先用 ReLU 或其变种(Leaky ReLU、Swish),计算快且不易梯度消失;

  2. 输出层

    • 二分类:Sigmoid(输出单个概率值);

    • 多分类:Softmax(输出概率分布);

    • 回归任务:可不用激活(直接输出连续值)或用 ReLU(确保输出非负);

  3. 特殊场景

    • 循环神经网络(RNN):避免用 ReLU(可能导致梯度爆炸),可用 Tanh 或 Sigmoid;

    • 深层模型:优先用 Swish 等更平滑的函数,减少训练波动。


非线性激活代码举例(ReLU)

参数inplace的作用:是否直接在原内存地址上修改输入数据,还是创建新的内存空间存储输出。

inplace默认是False

python 复制代码
import torch
from torch import nn
from torch.nn import ReLU

input = torch.tensor([[1, -0.5],
                      [-1, 3]])
intput = torch.reshape(input, (-1, 1, 2, 2))
print(intput.shape)


class MyModule(nn.Module):
    def __init__(self):
        super().__init__()
        self.relu = ReLU()

    def forward(self, input):
        output = self.relu(input)
        return output


module = MyModule()
output = module(input)
print("input", input)
print("output", output)

运行结果:


综合代码案例

python 复制代码
import torchvision
from torch import nn
from torch.nn import Sigmoid
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10("../torchvision_dataset", train=False,
                                       transform=torchvision.transforms.ToTensor(),
                                       download=True)

dataloader = DataLoader(dataset, batch_size=64)


class MyModule(nn.Module):
    def __init__(self):
        super().__init__()
        self.sigmoid = Sigmoid()

    def forward(self, input):
        output = self.sigmoid(input)
        return output


writer = SummaryWriter("logs_test7")
module = MyModule()
step = 1
for data in dataloader:
    imgs, targets = data
    writer.add_images("激活前", imgs, step)
    output = module(imgs)
    writer.add_images("激活后", output, step)
    step += 1

writer.close()
相关推荐
Mintopia14 小时前
OpenClaw 对软件行业产生的影响
人工智能
陈广亮15 小时前
构建具有长期记忆的 AI Agent:从设计模式到生产实践
人工智能
会写代码的柯基犬15 小时前
DeepSeek vs Kimi vs Qwen —— AI 生成俄罗斯方块代码效果横评
人工智能·llm
Mintopia15 小时前
OpenClaw 是什么?为什么节后热度如此之高?
人工智能
爱可生开源社区15 小时前
DBA 的未来?八位行业先锋的年度圆桌讨论
人工智能·dba
叁两18 小时前
用opencode打造全自动公众号写作流水线,AI 代笔太香了!
前端·人工智能·agent
敏编程18 小时前
一天一个Python库:jsonschema - JSON 数据验证利器
python
前端付豪18 小时前
LangChain记忆:通过Memory记住上次的对话细节
人工智能·python·langchain
strayCat2325518 小时前
Clawdbot 源码解读 7: 扩展机制
人工智能·开源