dropout随机失活
"""
案例:
dropout正则化解释:
概述:
让神经元以 p概率 随机失活, 防止模型训练时过度依赖某些特征.
p的值一般是: 0.2 ~ 0.5, 如果是简单模型可以小一点, 如果是复杂模型可以大一点.
细节:
1. 未被失活的数据(神经元)会被缩放, 缩放比例是: 1 / (1 - p)
2. dropout一般应用于 激活层之后, 即: 加权求和 -> 激活函数 -> dropout
3. dropout只应用于 训练阶段, 在测试阶段失效.
设置模型状态的两个函数如下:
model.train() -> 训练阶段
model.eval() -> 测试阶段
"""
# 导包
import torch
import torch.nn as nn
# 1. 准备数据集.
# 参1: 随机生成1 ~ 10之间的数据, 形状为: 1行4列, 即: 1条样本 4个特征.
x = torch.randint(1, 10, (1, 4), dtype=torch.float)
# 2. 创建隐藏层.
linear1 = nn.Linear(4, 5)
# 3. 先对特征进行 加权求和, 再进行 激活函数处理.
x = linear1(x) # 加权求和
x = torch.tanh(x) # 激活函数
print(f'未被失活的数据: {x}')
# 4. 创建dropout层(随机失活层), 设置p值(每个神经元随机失活的概率)
dp = nn.Dropout(p=0.5)
# 5. 对激活函数处理后的结果进行随机失活.
out = dp(x)
print(f'被随机失活的数据: {out}')
可以看到未失活的权重大了一倍
批量归一化
"""
批量归一正则化解释:
概述:
当数据量比较大的时候, 我们会分批次对数据进行训练, 但是如果批次之间的差异较大,
导致 模型参数 需要大范围调整, 以便适应不同批次的"规律".
这样就会导致: 模型的收敛速度变慢, 甚至可能出现"梯度震荡, 梯度爆炸"...
解决思路:
1. 对批次数据进行 标准化操作, 相当于减少了 批次数据之间的 差异性, 让数据更稳定.
2. 弊端: 可能会丢失某些特征信息, 导致预测结果偏差, 所以引入了 λ(缩放, 当做: 权重) 和 β(平移, 当做: 偏置)
f(x) = λ * (标准化后的x) + β
批量归一化层, 常用的 3种方式:
BatchNorm1d:主要应用于全连接层或处理一维数据的网络,例如文本处理。它接收形状为 (N, num_features) 的张量作为输入。
BatchNorm2d:主要应用于卷积神经网络,处理二维图像数据或特征图。它接收形状为 (N, C, H, W) 的张量作为输入。
BatchNorm3d:主要用于三维卷积神经网络 (3D CNN),处理三维数据,例如视频或医学图像。它接收形状为 (N, C, D, H, W) 的张量作为输入。
"""
# 导包
import torch
import torch.nn as nn
# todo 1.定义函数, 演示 BatchNorm2d 处理图像. 输入(N个数, C通道数, H高, W宽)
def dm01():
# 1. 定义数据集 -> 充当输入数据, 模拟图片数据集.
# 1张图片, 2个通道, 高: 3像素, 宽: 4像素
x = torch.rand(size=(1, 2, 3, 4))
print(f'x: {x}')
# 2. 搭建 批量归一化层.
# 参1: 输入的特征数, 等价于: 图片的通道数.
# 参2: 小常数, 防止处理时, 分母变为0
# 参3: 动量因子, 默认是: 0.1
# 参4: 是否需要缩放, 默认是: True, 即: 是否计算λ 和 β
bn2d = nn.BatchNorm2d(num_features=2, eps=1e-5, momentum=0.1, affine=True)
# 3. 处理图像数据
y = bn2d(x)
print(f'y: {y}')
# todo 2. 定义函数, 演示 BatchNorm1d 处理文本. 输入(N, num_features)
def dm02():
# 1. 创建数据集 -> 充当输入数据, 模拟文本数据集.
# 2个文本, 2个特征 -> 不能创建1个样本, 无法统计均值和方差
input_1d = torch.rand(size=(2, 2))
print(f'input_1d: {input_1d}')
# 2. 创建线性层对象.
linear1 = nn.Linear(in_features=2, out_features=3)
# 3. 创建BN层对象.
# num_features: 输入的特征数.
bn1d = nn.BatchNorm1d(num_features=3)
# 4. 具体的处理动作.
# 4.1 线性层处理数据.
output_1d = linear1(input_1d)
# 4.2 批量归一化处理.
output = bn1d(output_1d)
# 5. 输出结果.
print(f'output: {output}')
# todo 3. 测试代码
if __name__ == '__main__':
# 1. 演示: BatchNorm2d 处理图像.
# dm01()
# 2. 演示: BatchNorm1d 处理文本.
dm02()