目录
8. bert_num_blocks、bert_num_heads
1. 随机种子
什么是随机种子?
我们知道,随机数是通过一些复杂的数学算法得到的,那么 随机种子(Random Seed)就是这些随机数的初始值。
一般计算机里面产生的随机数都是伪随机数。 伪随机数,也是就一个一直不变的数。
import numpy as np
num = 0
while (num < 5):
np.random.seed(0)
print(np.random.rand(1,5)) # 得到一个范围从0到1的 1行5列的随机数
num += 1
print('-------------------------')
结果:
由结果可以看出来,这些都是伪随机数,也就是一直不变的随机数,所以我们可以通过输入随机种子,得到一个初始固定的随机数。随机种子的初始值,是一直不变的。
我们把随机种子的赋值,放到循环外面,意思是只初始化一次
import numpy as np
num = 0
np.random.seed(0)
while (num < 5):
print(np.random.rand(1,5))
num += 1
print('-------------------------')
看到,结果就不一样了,但是初始化第一行的结果还是一样的,这说明初始值一样 ,而且你会发现,无论你运行多少遍,有了随机种子,运行的结果都是一样的
但我们不需要随机种子的时候,把随机种子的赋值注释掉
import numpy as np
num = 0
#np.random.seed(0)
while (num < 5):
print(np.random.rand(1,5))
num += 1
print('-------------------------')
第一次结果:
第二次结果:
此时结果就是完全随机,没有一点章法。
所以我总结就是,通过随机种子,通过一些复杂的数学算法,你可以得到一组有规律的随机数,而随机种子就是这个随机数的初始值。随机种子相同,得到的随机数一定也相同。
参考文献:随机种子的详解-CSDN博客
代码复现具体例子:
def fix_random_seed_as(random_seed):
random.seed(random_seed)
np.random.seed(random_seed)
torch.manual_seed(random_seed)
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
- random.seed( ):设置 Python 内置随机数生成器的种子为指定的 random_seed,这可以确保后续使用 Python 内置的随机数相关操作具有确定性。
- np.random.seed( ):设置 numpy 库的随机数种子,使得生成的随机数也具有确定性。
- torch.manual_seed( ):为 PyTorch 的随机数生成设置种子,保证相关随机操作的可重复性。
- torch.backends.cudnn.deterministic = True:将 PyTorch 中与 CUDA 卷积神经网络相关的操作设置为确定性模式,减少因硬件等因素导致的不确定性。
- torch.backends.cudnn.benchmark = False:关闭 cudnn 的基准测试模式,进一步确保确定性。这样做通常是为了在需要可重复结果的场景中进行精确的控制。
2. min_uc、min_sc
一般来说,min_uc
可能代表 "minimum user constraint"(最小用户约束)或类似的概念。这可能是与用户相关的某种限制或条件,例如在推荐系统中,可能表示每个用户至少需要有一定数量的交互或历史数据,以便模型能够进行有效的学习和推荐。
类似地,min_sc
可能表示 "minimum specific constraint"(最小特定约束)。这可能是针对特定问题或数据集的约束条件,例如在图像分类任务中,可能要求每个类别至少有一定数量的样本,以确保模型能够学习到足够的特征和模式。
这些参数的目的是确保模型在训练过程中满足一定的条件或限制,以提高模型的性能、泛化能力或满足特定的业务需求。具体的含义和作用需要根据具体的模型和应用来确定。
3. 负样本negative samples
负样本是在机器学习等领域中与正样本相对应的概念。
在有监督学习中,通常会将数据分为正样本和负样本。正样本是符合我们期望的目标类别或具有特定特征的数据点,而负样本则是与正样本不同的、代表其他情况的数据点。通过同时使用正样本和负样本进行训练,可以让模型学习到区分不同类别或特征的能力,从而更好地进行预测、分类等任务。
例如,在图像识别中,识别猫的任务中,猫的图像可以作为正样本,而其他非猫的图像就是负样本。
4. 权值衰减 weight_decay
它是一种正则化技术,其作用是在训练过程中对模型的参数(权重)进行约束。通过给权重的调整施加一个惩罚项,使得模型在优化过程中倾向于选择较小的权重值。
这样做的好处主要有几点:一是可以防止模型过拟合,因为较小的权重通常意味着模型复杂度降低,不太容易过度拟合训练数据;二是有助于提高模型的泛化能力,使模型在新数据上有更好的表现;三是可以在一定程度上促进模型的稳定性和鲁棒性。
要设置
weight_decay
的参数值以达到最佳效果,可以考虑以下几点:
- 数据集和模型复杂度:一般来说,数据集越大、模型越复杂,
weight_decay
的值可以适当增大;反之,数据集较小、模型较简单时,weight_decay
的值应适当减小。- 实验和调参:由于不同的问题和模型结构可能对
weight_decay
的敏感度不同,因此需要进行实验来确定最佳值。可以尝试不同的weight_decay
值,并比较模型在验证集或测试集上的性能。- 正则化强度:
weight_decay
是一种正则化方法,用于控制模型的过拟合。较大的weight_decay
值会对模型的参数进行更强的正则化,可能导致模型欠拟合;而较小的weight_decay
值可能不足以防止过拟合。- 与其他超参数的交互:
weight_decay
的值可能与其他超参数(如学习率、优化器等)相互作用。在调整weight_decay
时,也需要考虑这些超参数的设置。- 模型的具体情况:某些模型或层可能对
weight_decay
更敏感或不敏感。例如,在卷积神经网络中,卷积层的偏置项通常不需要添加正则化,而全连接层的偏置项可能需要。一些常见的设置经验包括:
- 在深度学习框架中,通常可以在优化器中设置
weight_decay
参数。例如,在 PyTorch 中,可以在定义优化器时指定weight_decay
的值。- 对于大多数情况,可以先尝试一个较小的
weight_decay
值,如 0.001 或 0.01,并根据模型的性能进行调整。- 如果模型出现过拟合,可以适当增大
weight_decay
值;如果模型欠拟合,可以尝试减小weight_decay
值或尝试其他正则化方法。- 结合其他正则化技术,如Dropout、Batch Normalization 等,以进一步提高模型的泛化5能力。
5. decay_step
decay_step
是指学习率衰减的步长,它控制着学习率的衰减速度。在学习率衰减中,学习率会随着训练的进行而逐渐减小,以避免模型在训练后期出现过拟合现象。
例如,如果将 decay_step
设置为 1000,decay_rate
设置为 0.9,那么学习率将在每 1000 次迭代后乘以 0.9。如果将 staircase
参数设置为 True
,则学习率将在每 1000 次迭代后阶梯式地下降;如果将 staircase
参数设置为 False
,则学习率将在每次迭代后连续地下降。
因此,decay_step
的值越大,学习率的衰减速度就越慢;decay_step
的值越小,学习率的衰减速度就越快。在实际应用中,需要根据具体情况选择合适的 decay_step
值,以达到最佳的训练效果。
6. gamma 伽马分布
在深度学习中,gamma 通常指的是伽马分布(Gamma Distribution),它是统计学中的一种连续概率函数。伽马分布中有两个参数:形状参数(shape parameter)α和尺度参数(scale parameter)β。
伽马分布具有以下特点:
- 可加性:如果两个独立的随机变量 X 和 Y 都服从伽马分布,且它们的尺度参数相同,那么它们的和 Z=X+Y 也服从伽马分布,其形状参数为两个伽马分布的形状参数之和。
- 与指数分布的关系:当伽马分布的形状参数α为 1 时,它退化为指数分布。
- 在深度学习中的应用:伽马分布在深度学习中有多种应用,例如在生成对抗网络(Generative Adversarial Network,GAN)中,它可以用于生成数据;在强化学习中,它可以用于策略优化等。
7. 学习率预热
学习率预热(Learning Rate Warmup)是一种在深度学习训练过程中采用的策略。
意思是在训练初期,不是直接使用预设的学习率(通常相对较高)开始训练,而是先让学习率从一个较小的值开始逐渐上升,经过一定的训练步数或阶段后,再达到预设的正常学习率水平。
这样做的主要目的是:
- 提高训练稳定性:一开始模型对数据还不熟悉,较小的学习率可以让模型更平稳地适应数据,减少因学习率过大可能导致的不收敛或剧烈波动。
- 避免初期的异常:有助于避免在训练早期因学习率不合适而出现一些奇怪的训练行为。
8. bert_num_blocks、bert_num_heads
“bert_num_blocks” 通常指的是 BERT(Bidirectional Encoder Representations from Transformers)模型中块(block)的数量。 在 BERT 模型结构中,这些块通常包含了一系列的层和计算单元,对输入文本进行处理和特征提取。通过调整这个参数可以在一定程度上控制模型的复杂度和性能表现。
通过调整
bert_num_blocks
可以有以下一些影响和方式来控制复杂度与性能表现:对复杂度的影响:
增加
bert_num_blocks
会使模型的整体结构变得更复杂,计算量增大,需要更多的内存和计算资源。对性能表现的影响及调整方式:
- 增加数量:一般来说,增加块数可能会让模型有更强的语言理解和表示能力,从而在一些复杂任务中可能提升性能,比如对语义理解要求很高的任务。
- 减少数量:可以降低模型复杂度,可能在计算资源有限或任务相对简单时,减少过拟合风险,同时加快训练和推理速度,但可能会损失一定的性能上限。
“bert_num_heads” 指的是 BERT 模型中多头注意力机制(Multi-Head Attention)的头数。
调整这个参数对模型有以下影响:
对模型复杂度:头数增加会使模型更复杂,计算量也相应增加。
对性能表现:
- 增加头数:通常可以让模型捕捉到更丰富的语义信息和不同维度的特征表示,可能有助于提升模型在一些复杂任务中的表现,比如对文本的理解更细致准确。但过多头数也可能导致过拟合或训练难度增大。
- 减少头数:能一定程度上降低复杂度和计算开销,但可能损失一些模型的表示能力。
9. .pth文件
‘ .pth ’ 文件是 PyTorch 框架中用于保存模型参数或整个模型状态的文件格式。 它可以包含模型的权重、偏置等参数信息,以便在后续需要时可以通过加载该文件来快速恢复模型。
10. 学习率调度器
学习率调度器(Learning Rate Scheduler)是用于动态调整学习率的机制。
常见的学习率调度方式有以下几种:
1. 阶梯式下降:在特定的训练阶段或轮数后,将学习率降低为一个固定的比例。
2. 指数衰减:学习率按照指数形式逐渐减小。
3. 余弦退火:学习率按照余弦函数的形式进行周期性变化,通常会有一个学习率的初始值和最小值,在训练过程中学习率在这两个值之间周期性波动。
使用学习率调度器的好处是可以帮助模型更好地收敛,避免学习率一直保持较大导致模型不稳定或难以收敛,也可以防止学习率过早地降得过低而影响训练效果。不同的调度方式适用于不同的场景和任务,需要根据实际情况进行选择和调整。
if args.enable_lr_schedule:
if args.enable_lr_warmup:
# 创建带有热身的学习率调度器
self.lr_scheduler = self.get_linear_schedule_with_warmup(
self.optimizer, args.warmup_steps, len(train_loader) * self.num_epochs)
else:
# 创建 StepLR 学习率调度器
self.lr_scheduler = optim.lr_scheduler.StepLR(
self.optimizer, step_size=args.decay_step, gamma=args.gamma)
11. 开始前后每个epoch的验证操作
在训练模型时,开始前和每个epoch结束后进行验证操作是为了监控模型的性能。
开始前验证:在训练开始之前进行验证,可以提供一个基线,了解模型在未经训练时对数据集的初始表现。这有助于后续比较训练过程中模型的改善情况。
每个epoch后验证:在每个训练周期(epoch)结束后进行验证,可以实时检查模型在验证集上的性能。这有助于识别模型是否过拟合或欠拟合,以及何时应该停止训练。如果验证集上的性能不再提升甚至下降,可能表明模型已经学习到验证集的噪声,此时应停止训练以避免过拟合。
12. tqdm 创建进度条
超级简单的一个例子
from tqdm import tqdm
import time
# 模拟一个需要进度显示的任务,比如遍历一个列表
items = range(100)
# 使用 tqdm 创建进度条
with tqdm(total=len(items)) as pbar:
for item in items:
time.sleep(0.1) # 模拟任务执行时间
pbar.update(1) # 更新进度条
13. 交叉熵损失函数
交叉熵损失函数的作用是衡量模型预测的概率分布与真实的概率分布之间的差异。当模型的预测结果与真实结果越接近时,交叉熵损失函数的值就越小;反之,当模型的预测结果与真实结果相差较大时,交叉熵损失函数的值就越大。
torch
提供了两种形式来使用交叉熵函数:函数形式F.cross_entropy
和类形式nn.CrossEntropyLoss
。
以下是使用函数形式的示例代码:
import torch
import torch.nn.functional as F
# 预测结果
pred = torch.randn(3, 5)
# 真实标签
target = torch.tensor([2, 4, 3], dtype=torch.long)
# 计算交叉熵损失
loss = F.cross_entropy(pred, target)
print(loss)
类形式的使用方式如下:
import torch
import torch.nn as nn
# 预测结果
pred = torch.randn(3, 5)
# 真实标签
target = torch.tensor([2, 4, 3], dtype=torch.long)
# 创建交叉熵损失函数对象
loss_func = nn.CrossEntropyLoss()
# 计算交叉熵损失
loss = loss_func(pred, target)
print(loss)
- torch.randn():是 PyTorch 中的一个函数,用于生成指定形状的随机张量,其中每个元素的值都是从均值为 0,标准差为 1 的正态分布(即高斯分布)中随机采样得到的。
print(pred)
再举个例子:
import torch # 生成一个 2x3 的随机张量 x = torch.randn(2, 3) print(x) # 生成一个 2x3x4 的随机张量 y = torch.randn(2, 3, 4) print(y)
14. 张量切片
在PyTorch
中,张量切片操作可以通过索引来实现。切片操作可以提取张量的一部分,返回一个新的张量。
以下是一些常见的张量切片操作:
- 基本切片:可以使用类似
Python
列表的切片语法来进行基本切片。例如,a[start:end]
表示提取张量a
中从索引start
到索引end-1
的部分。- 跨步切片:可以指定切片的步长。例如,
a[start:end:step]
表示以步长step
提取张量a
中从索引start
到索引end-1
的部分。- 多维切片:对于多维张量,可以在每个维度上进行切片。例如,对于二维张量
a
,a[row_start:row_end, col_start:col_end]
表示提取a
中从行索引row_start
到行索引row_end-1
,列索引col_start
到列索引col_end-1
的部分。- 整行或整列切片:可以使用
:
来表示提取整行或整列。例如,a[:, col_index]
表示提取张量a
的第col_index
列,a[row_index, :]
表示提取张量a
的第row_index
行。- 条件切片:可以根据条件进行切片。例如,可以使用
a[a > 0]
来提取张量a
中大于0
的元素。
代码示例:
import torch
tensor1 = torch.rand(10)
# 1. 基本切片
sliced_tensor1 = tensor1[1:4]
# 2. 跨步切片
sliced_tensor2 = tensor1[0:8:2]
# 3. 多维切片(以二维张量为例)
tensor3 = torch.rand(3, 4)
sliced_tensor3 = tensor3[1:3, 1:3]
# 4. 整行或整列切片
row_sliced_tensor4_1 = tensor3[1, :]
col_sliced_tensor4_2 = tensor3[:, 2]
# 5. 条件切片
filtered_tensor5 = tensor1[tensor1 > 0.5]
print("原始张量:",tensor1)
print("-------------------")
print("原始张量:",tensor3)
print("-------------------")
print("基本切片:",sliced_tensor1)
print("跨步切片:",sliced_tensor2)
print("多维切片:",sliced_tensor3)
print("整行切片:",row_sliced_tensor4_1)
print("整列切片:",col_sliced_tensor4_2)
print("条件切片:",filtered_tensor5)
在这片论文代码中,scores = scores[:, -1, :]