生生不息00 2025-03-22 22:48 采纳率: 0%
浏览 8

mini_batch批量训练问题

累积多个样本和大批量样本训练结果应该一致的,但是实际的累积的不能正常训练(loss不下降),大批量样本可以正常训练(正常收敛)。网络中已经注释掉了BatchNorm。是因为优化器的原因吗?

#累积600个样本
#batch_size=1
def Train_batch(self,epoch):
        self.net.train()
        
        loss_ = 0
        self.optim.zero_grad()

        for i,(data, label) in enumerate(self.train):
            data = data.cuda() if tr.cuda.is_available() else data
            label = label.cuda() if tr.cuda.is_available() else label
            
            _,prediction = self.net(data)
            loss = train.compute_loss(prediction, label)   

            loss.backward()   #计算梯度

            if (i+1)%600 == 0:
                for param in self.net.parameters():
                    if param.grad is not None:
                        param.grad /= 600  
                #更新参数
                self.optim.step()
                self.optim.zero_grad()
            loss_ +=  loss.item()
        
        return loss_ / len(self.train)  # 计算epoch内 loss 的均值

#batch_size=600
 def Train_batch(self,epoch):
        self.net.train()
        loss_ = 0
        batch_count = 0  # 记录批次数量
        for data, label in self.train:
            data = data.cuda() if tr.cuda.is_available() else data
            label = label.cuda() if tr.cuda.is_available() else label
            self.optim.zero_grad()
            
            _,prediction = self.net(data)
            
            loss = train.compute_loss(prediction, label)  
         
            loss.backward()   #计算梯度
            self.optim.step()  #更新参数

            loss_ = loss_ + loss.item()
            batch_count += 1  # 统计 batch 数量
        return loss_ / batch_count  # 计算 loss 的均值

  • 写回答

4条回答 默认 最新

  • 道友老李 JWE233286一种基于机器视觉的水表指针读数识别及修正的方法 专利发明者 2025-03-22 22:49
    关注
    让【道友老李】来帮你解答,本回答参考gpt编写,并整理提供,如果还有疑问可以点击头像关注私信或评论。
    如果答案让您满意,请采纳、关注,非常感谢!
    这个问题可能是由于在累积样本时未正确更新梯度造成的。在第一个代码段中,每累积600个样本就对参数进行一次梯度更新,但是在更新前并没有将累积的梯度除以累积的样本数量600。因此,导致每次对参数更新的梯度过大,无法正常训练。 你可以尝试在累积样本的代码段中将参数梯度除以累积的样本数量600,即在`self.optim.step()`前进行梯度的更新操作。 代码示例:
    if (i+1)%600 == 0:
        for param in self.net.parameters():
            if param.grad is not None:
                param.grad /= 600
        self.optim.step()
        self.optim.zero_grad()
    

    这样做可以保证每次梯度更新时梯度的大小合适,可能解决你遇到的问题。如果问题仍然存在,可以尝试调整学习率等优化器的超参数,以提高模型的训练效果。

    评论

报告相同问题?

问题事件

  • 创建了问题 3月22日