文章目录
- 深度学习损失计算
- 1.如何计算当前epoch的损失?
- 2.为什么要计算样本平均损失,而不是计算批次平均损失?
深度学习损失计算
1.如何计算当前epoch的损失?
深度学习中的损失计算,通常为数据集的平均损失,即每个样本的平均损失值。计算步骤如下:
-
计算单个批次的损失。每次迭代中,用当前模型预测值和真实值计算损失。假设
_loss
是这次迭代中计算得到的损失。 -
转换为标量。利用
item()
方法将其转换为标量值。_loss.item()
- 乘以批次大小。乘以批次大小的原因是,希望总损失是所有数据点的损失总和,而不是批次平均损失。
-
累加损失。
loss += _loss.item() * batch_size
将当前批次的总损失累加到变量loss
中。这样所有批次遍历结束后,就得到一个epoch的总损失。 -
计算当前epoch的样本平均损失。通过总损失除以总的数据样本数,来得到平均损失。
average_loss = loss/len(dataloader.dataset)
【注意:除的是总的数据样本数(len(dataloader.dataset)
)!不是总的批次数(len(dataloader)
)!】
示例代码如下:
for epoch in total_epoch: # epoch迭代
total_loss = 0.0 # 初始化总损失
for inputs, targets in dataloader: # batch迭代
outputs = model(inputs) # 获取预测值
_loss = criterion(outputs, targets) # 计算当前批次损失,为批次平均损失
batch_size = inputs.size(0) # 获取批次大小
total_loss += _loss.item() * batch_size # 计算当前批次的总损失
# 计算当前epoch的平均损失
average_loss = total_loss / len(dataloader.dataset)
2.为什么要计算样本平均损失,而不是计算批次平均损失?
由于每个批次的大小可能不一样,特别是在数据集的大小不是批次大小的整数倍时,所以使用
len(dataloader)
会导致错误的平均损失计算。
下面用一个简单的例子,解释这两种计算方式的不同:
假设数据集有 105 个样本,每个批次大小为 10,这样会有 11 个批次,其中最后一个批次只有 5 个样本。结合上面的伪代码,假设损失值 _loss.item()
是 1,对于 10 个批次的损失是 10,最后一个批次的损失是 5。那么:
- t o t a l _ l o s s = ( 1 ∗ 10 ) ∗ 10 + ( 1 ∗ 5 ) ∗ 1 = 105 total\_loss = (1 * 10) * 10 + (1 * 5) * 1 = 105 total_loss=(1∗10)∗10+(1∗5)∗1=105
- l e n ( d a t a l o a d e r . d a t a s e t ) = 105 len(dataloader.dataset) = 105 len(dataloader.dataset)=105
- l e n ( d a t a l o a d e r ) = 11 len(dataloader) = 11 len(dataloader)=11
计算结果:
- 样本平均损失计算:
average_loss = total_loss / len(dataloader.dataset)
即 105 / 105 = 1 105/105 = 1 105/105=1。 - 批次平均损失计算:
average_loss = total_loss / len(dataloader)
即 105 / 11 ≈ 9.545 105/11 \approx 9.545 105/11≈9.545。
显然,第一种方式是正确的,反映了每个样本的真实平均损失。
????????????