昇思25天学习打卡营第08天 | 模型训练
文章目录
- 昇思25天学习打卡营第08天 | 模型训练
- 超参数
- 损失函数
- 优化器
- 优化过程
- 训练与评估
- 总结
- 打卡
模型训练一般遵循四个步骤:
- 构建数据集
- 定义神经网络模型
- 定义超参数、损失函数和优化器
- 输入数据集进行训练和评估
构建数据集和网络模型在之前的内容在已经涉及,不再赘述。
超参数
超参数(Hyperparameters)是可以调整的参数,可以控制模型训练的过程。
深度学习模型多采用随机梯度下降算法SGD进行优化:
w
t
+
1
=
w
t
−
η
1
n
∑
x
∈
B
∇
l
(
x
,
w
t
)
w_{t+1}=w_t- \eta\frac1n\sum_{x\in B}\nabla l(x,w_t)
wt+1=wt−ηn1x∈B∑∇l(x,wt)
其中,
η
\eta
η是学习率,
n
n
n是batch大小,都是超参数,这两个参数是直接影响模型性能收敛的重要参数。
一般会定义三个超参数:
- epoch:遍历数据集的次数
- batch size:每个批次数据的大小。size 过小导致花费时间多,梯度震荡严重,不利于收敛;size 过大容易陷入局部极小值。
- learning rate:学习率国小会导致收敛速度变慢;过大则可能会导致训练不收敛。
损失函数
损失函数用于评估模型预测值和目标值之间的误差。
常见的损失函数包括:
nn.MSELoss
:均方误差,用于回归nn.NLLLoss
:负对数似然,用于分类nn.CrossEntropyLoss
:结合了nn.LogSoftmax
和nn.NLLLoss
,可以对logits进行归一化并计算预测误差
loss_fn = nn.CrossEntropyLoss()
优化器
优化器内部定义了模型参数的优化过程,所有的优化逻辑都封装在优化器对象中。
optimizer = nn.SGD(model.trainable_params(), learning_rate=learning_rate)
优化过程
通过自动微分获得的微分函数,计算参数对应的梯度,并传入优化器中,即可实现参数优化。
grads = grad_fn(inputs)
optimizer(grads)
训练与评估
遍历一次数据集被称为一轮(epoch),每轮执行训练时包含两个步骤:
- 训练:迭代训练数据集,并尝试收敛到最佳参数。
- 验证/测试:迭代测试数据集,检查模型性能是否提升。
# Define forward function
def forward_fn(data, label):
logits = model(data)
loss = loss_fn(logits, label)
return loss, logits
# Get gradient function
grad_fn = mindspore.value_and_grad(forward_fn, None, optimizer.parameters, has_aux=True)
# Define function of one-step training
def train_step(data, label):
(loss, _), grads = grad_fn(data, label)
optimizer(grads)
return loss
def train_loop(model, dataset):
size = dataset.get_dataset_size()
model.set_train()
for batch, (data, label) in enumerate(dataset.create_tuple_iterator()):
loss = train_step(data, label)
if batch % 100 == 0:
loss, current = loss.asnumpy(), batch
print(f"loss: {loss:>7f} [{current:>3d}/{size:>3d}]")
def test_loop(model, dataset, loss_fn):
num_batches = dataset.get_dataset_size()
model.set_train(False)
total, test_loss, correct = 0, 0, 0
for data, label in dataset.create_tuple_iterator():
pred = model(data)
total += len(data)
test_loss += loss_fn(pred, label).asnumpy()
correct += (pred.argmax(1) == label).asnumpy().sum()
test_loss /= num_batches
correct /= total
print(f"Test: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")
训练过程一般为:
loss_fn = nn.CrossEntropyLoss()
optimizer = nn.SGD(model.trainable_params(), learning_rate=learning_rate)
for t in range(epochs):
print(f"Epoch {t+1}\n-------------------------------")
train_loop(model, train_dataset)
test_loop(model, test_dataset, loss_fn)
总结
这一节的内容对深度学习模型训练的一般过程进行了详细的介绍,从数据集构建到模型定义,接着定义超参数并选择合适的值,创建损失函数和优化器对象完成训练前的准备。通过封装一个模型调用和loss计算的前向计算函数并自动微分,在每个epoch中计算loss并优化参数,从而完成模型的训练。