当前位置: 首页 > news >正文

是否每一层之间都要线性变换和激活函数?

1. 神经网络层的基本组成

一个典型的神经网络层通常包含两个步骤:

  1. 线性变换(加权求和)
    z = Wx}+ b
    其中W 是权重矩阵,b是偏置向量,是输入,z 是线性输出。
  2. 激活函数
    其中,非线性激活函数(如ReLU、Sigmoid等),a是该层的输出。

2. 何时需要激活函数?

(1) 隐藏层(Hidden Layers)
  • 必须使用激活函数
    激活函数引入非线性,使神经网络能够学习复杂的非线性关系。如果隐藏层没有激活函数,多层网络将退化为单层线性模型(无论有多少层,整体仍为线性变换)。
  • 常见激活函数:ReLU、LeakyReLU、Tanh、Sigmoid等。
(2) 输出层(Output Layer)
  • 根据任务选择激活函数
    • 回归任务(如预测房价):通常不使用激活函数(等效于线性激活)或使用恒等函数。
    • 二分类任务:使用Sigmoid函数,将输出压缩到[0,1]区间,表示概率。
    • 多分类任务:使用Softmax函数,将输出转换为概率分布。
    • 多标签分类:对每个类别独立使用Sigmoid函数。

3. 何时可以省略线性变换或激活函数?

(1) 特殊网络结构
  • 残差网络(ResNet)
    通过跳跃连接(Skip Connection)将输入直接传递到后续层,此时某些层可能仅包含激活函数或线性变换,而非两者都需要。

  • 注意力机制(Attention)
    在Transformer中,注意力层的输出可能直接传递到下一层,不立即应用激活函数。

(2) 无参数层
  • 池化层(Pooling Layer)
    如最大池化或平均池化,仅进行下采样操作,不涉及线性变换或激活函数。
  • 归一化层(Normalization Layer)
    如批量归一化(BatchNorm),仅对输入进行标准化,通常与激活函数结合使用(如先归一化,再激活)。

4. 实际应用中的常见模式

(1) 标准全连接网络
import torch.nn as nn

model = nn.Sequential(
    nn.Linear(in_features=784, out_features=256),  # 线性变换
    nn.ReLU(),                                     # 激活函数
    nn.Linear(256, 128),
    nn.ReLU(),
    nn.Linear(128, 10),
    nn.Softmax(dim=1)                              # 输出层激活函数
)
  • 隐藏层:线性变换 + 激活函数(如ReLU)。
  • 输出层:线性变换 + 任务相关激活函数(如Softmax)。
(2) 卷积神经网络(CNN)
model = nn.Sequential(
    nn.Conv2d(3, 32, kernel_size=3),  # 卷积(线性变换)
    nn.ReLU(),                        # 激活函数
    nn.MaxPool2d(2),                  # 池化(无参数)
    nn.Conv2d(32, 64, kernel_size=3),
    nn.ReLU(),
    nn.Flatten(),
    nn.Linear(64*12*12, 10)          # 输出层(可能无激活函数)
)
  • 卷积层:线性变换(卷积操作) + 激活函数。
  • 池化层:仅下采样,无线性变换或激活函数。
  • 输出层:根据任务选择是否添加激活函数。

5. 关键总结

层类型是否需要线性变换?是否需要激活函数?示例场景
隐藏层✔️ 必选✔️ 必选全连接层、卷积层
输出层✔️ 必选依任务选择Softmax(分类)、无(回归)
池化层❌ 无❌ 无下采样
归一化层❌ 无❌ 无BatchNorm、LayerNorm
残差连接层可能部分省略可能部分省略ResNet中的跳跃连接

6. 常见误区与注意事项

  1. 误区:认为所有层都必须包含线性变换和激活函数。

    • 纠正:池化层、归一化层等无参数层通常不涉及线性变换或激活函数。
  2. 输出层的激活函数选择

    • 错误使用激活函数可能导致训练困难(如回归任务使用Sigmoid,限制输出范围)。
  3. 激活函数的位置

    • 在残差网络中,激活函数通常应用在线性变换之后、跳跃连接相加之前。
    • 在批量归一化中,通常顺序为:线性变换 → 归一化 → 激活函数。

7. 代码验证

通过PyTorch代码验证不同层的输出特性:

import torch
import torch.nn as nn

# 定义一个包含线性层、ReLU、池化层的网络
model = nn.Sequential(
    nn.Linear(2, 4),
    nn.ReLU(),
    nn.MaxPool1d(kernel_size=2)  # 无参数操作
)

x = torch.randn(3, 2)  # 输入形状 (3,2)
output = model(x)
print("输出形状:", output.shape)  # 池化后形状变化验证

结论

  • 隐藏层必须包含线性变换和激活函数,以引入非线性能力。
  • 输出层需根据任务选择激活函数,可能省略(如回归任务)。
  • 特殊层(池化、归一化、残差连接) 可能省略线性变换或激活函数。
  • 设计网络时需明确每层的功能,避免机械堆砌操作。

相关文章:

  • 记一次snmp_exporter/generator生成yml报错问题修复
  • 【小兔鲜】day01 项目、Vue3介绍、组合式API、小案例
  • [python]minepy安装后测试代码
  • cpp栈操作
  • 计算机网络相关知识小结
  • 笔记 数字电路与计算机组成
  • 祥瑞金业:如果美股进入熊市,黄金会如何反应?
  • 基于Linux C++多线程服务器 + Qt上位机开发 + STM32 + 8266WIFI的智慧无人超市
  • .net GRPC服务搭建,跨进程调用。C#应用和Python应用之间的通信。
  • Chapter 9 Capacitive DC–DC Converters
  • 百度自动驾驶:我的学习笔记
  • Epub转PDF软件Calibre电子书管理软件
  • 3.3 元组
  • (四)队列族
  • Unity声音管理系统笔记
  • 【JavaScript】合体期功法——DOM(二)
  • Unidbg Trace 反 OLLVM 控制流平坦化(fla)
  • Linux命令-sed指令
  • notion访问慢notion卡顿怎么办,提升notion加载速度
  • Java全栈面试宝典:线程机制与Spring依赖注入深度解析