PyTorch入门:理解线性层(Linear)和激活层(ReLU)
·
作为深度学习初学者,理解神经网络中的 线性层(Linear) 和 激活层(ReLU)是构建模型的基础。本文将通过PyTorch代码示例,用通俗易懂的方式解释它们的原理、计算过程和应用场景。
1. 什么是线性层(Linear Layer)?
线性层(又称全连接层,Dense Layer)是神经网络中最基础的组件之一,用于对输入数据进行线性变换。
1.1 核心功能
-
数学公式:
output=input×weightT+bias \text{output} = \text{input} \times \text{weight}^T + \text{bias} output=input×weightT+biasinput:输入数据(形状[batch_size, input_dim])。weight:权重矩阵(形状[output_dim, input_dim])。bias:偏置向量(形状[output_dim])。
-
作用:将输入数据从
input_dim维映射到output_dim维。
1.2 代码示例
import torch
import torch.nn as nn
# 定义一个线性层:输入100维,输出64维
linear_layer = nn.Linear(100, 64)
# 随机生成输入数据(batch_size=5, 输入维度=100)
input_data = torch.randn(5, 100)
# 前向传播
output = linear_layer(input_data)
print("输出形状:", output.shape) # 输出: torch.Size([5, 64])
1.3 关键点
- 权重矩阵的形状:
[output_dim, input_dim]。 - 偏置的作用:为每个输出维度提供一个可学习的偏移量。
- 设备一致性:确保输入数据和模型在同一设备(CPU/GPU)。
2. 什么是激活层(ReLU)?
激活层引入非线性,使神经网络能够学习复杂模式。最常用的激活函数是 ReLU(Rectified Linear Unit)。
2.1 核心功能
-
数学公式:
ReLU(x)=max(0,x) \text{ReLU}(x) = \max(0, x) ReLU(x)=max(0,x)
如果输入x>0,输出x如果输入 x > 0 ,输出 x 如果输入x>0,输出x
如果输入x≤0,输出0如果输入 x \leq 0,输出 0 如果输入x≤0,输出0 -
作用:
- 解决线性模型的局限性。
- 加速训练(相比Sigmoid/Tanh,ReLU计算更快)。
2.2 代码示例
relu = nn.ReLU()
# 假设线性层输出包含正负值
linear_output = torch.tensor([[-0.5, 1.2], [0.3, -0.1]])
# 应用ReLU
activated_output = relu(linear_output)
print("ReLU输出:", activated_output)
输出:
ReLU输出: tensor([[0.0000, 1.2000],
[0.3000, 0.0000]])
2.3 关键点
- 稀疏性:ReLU会将负值置零,可能使部分神经元“死亡”。
- 变体:
- LeakyReLU:允许负值有小幅输出(如
max(0.01x, x))。 - Parametric ReLU (PReLU):将负区斜率作为可学习参数。
- LeakyReLU:允许负值有小幅输出(如
3. 线性层 + ReLU 的完整示例
3.1 定义一个简单的MLP
class MLP(nn.Module):
def __init__(self, input_dim, hidden_dim, output_dim):
super().__init__()
self.linear1 = nn.Linear(input_dim, hidden_dim) # 输入层 → 隐藏层
self.relu = nn.ReLU()
self.linear2 = nn.Linear(hidden_dim, output_dim) # 隐藏层 → 输出层
def forward(self, x):
x = self.linear1(x)
x = self.relu(x)
x = self.linear2(x)
return x
# 初始化模型
model = MLP(input_dim=100, hidden_dim=64, output_dim=10)
input_data = torch.randn(5, 100) # batch_size=5
output = model(input_data)
print("MLP输出形状:", output.shape) # 输出: torch.Size([5, 10])
3.2 计算过程分解
- 输入数据:
[5, 100](5个样本,每个100维)。 - 第一层线性变换:
[5, 100] @ [64, 100].T → [5, 64]。 - ReLU激活:负值置零,保持正值。
- 第二层线性变换:
[5, 64] @ [10, 64].T → [5, 10]。
4. 常见问题解答
Q1:为什么线性层的权重形状是 [output_dim, input_dim]?
- 约定俗成:PyTorch和大多数框架采用这种设计,便于直接使用
input @ weight.T + bias。 - 数学一致性:确保矩阵乘法维度匹配(输入列数 = 权重行数)。
Q2:ReLU会丢失信息吗?
- 会的,但这是有意为之!
- 优点:
- 稀疏性可以减少过拟合。
- 计算高效(无需指数运算)。
- 缺点:可能导致“神经元死亡”(可通过LeakyReLU缓解)。
Q3:如何初始化权重和偏置?
PyTorch默认使用均匀初始化,但可以手动修改:
nn.init.xavier_uniform_(model.linear1.weight) # Xavier初始化
nn.init.zeros_(model.linear1.bias) # 偏置初始化为0
5. 总结
- 线性层:完成输入数据的维度变换(
input_dim → output_dim)。 - ReLU:引入非线性,增强模型表达能力。
- 组合使用:是构建深度神经网络的基础模块(如MLP、CNN)。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)