• 关于训练时,最后一轮batch_size=1的报错


    问题再现

    Traceback (most recent call last):
      File "./codes/ign_train.py", line 235, in <module>
        run_a_train_epoch(DTIModel, loss_fn, train_dataloader, optimizer, device)
      File "./codes/ign_train.py", line 46, in run_a_train_epoch
        outputs = model(bg, bg3)
      File ".../miniconda3/envs/IGN/lib/python3.6/site-packages/torch/nn/modules/module.py", line 532, in __call__
        result = self.forward(*input, **kwargs)
      File ".codes/model.py", line 380, in forward
        return self.FC(readouts)
      File ".../miniconda3/envs/IGN/lib/python3.6/site-packages/torch/nn/modules/module.py", line 532, in __call__
        result = self.forward(*input, **kwargs)
      File "./codes/model.py", line 40, in forward
        h = layer(h)
      File ".../miniconda3/envs/IGN/lib/python3.6/site-packages/torch/nn/modules/module.py", line 532, in __call__
        result = self.forward(*input, **kwargs)
      File "/home/haida_liuhao/software/miniconda3/envs/IGN/lib/python3.6/site-packages/torch/nn/modules/batchnorm.py", line 107, in forward
        exponential_average_factor, self.eps)
      File ".../miniconda3/envs/IGN/lib/python3.6/site-packages/torch/nn/functional.py", line 1666, in batch_norm
        raise ValueError('Expected more than 1 value per channel when training, got input size {}'.format(size))
    ValueError: Expected more than 1 value per channel when training, got input size torch.Size([1, 200])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    问题描述:

    其实这个问题就是他本身的机制问题:

      当Batch Normalization设为训练模式时(通过训练样本学习均值和方差),拒绝任何batch-size为1的情况。至于原因,简单地说就是BN归一化是依靠当前mini-batch的均值和方差进行归一化的,如果batch-size太小,显然所谓的均值和方差并不能代表不同sample之间的差距,各个mini-batch归一化结果的差异会非常大,归一化就没有意义了。另外,当batch-size设为1时,BN的结果近似于IN。

    问题分析

      归结一句话就是:不能以任何形式,或者每一轮都不能有batch_size==1的情况出现。基本上现在不会直接设置batch_size==1,还有一种情况就是,在最后一轮的时候batch_size==1
      不好理解的话,举个例子:
      比如我的数据集为17,我设置batch_size==16。那么16个数据集一轮,最后一轮就只剩下了1个数据集,这也就是出现了:batch_size==1的情况。

    解决方法

    1. 解决方法一:
        将dataloader的一个丢弃参数设置为true。即训练数据在加载的时候遇到batch=1的情况,可以设定DataLoader中的drop_last=True解决。
      这个方法是参考别人的,我没有怎么用过,其实方法就是自动把多的这个刨除掉吧!
    2. 解决方法二:
      如果避无可避,期望在测试阶段,仍然需要BN保持训练模式(即所谓的用测试数据的方差和均值来归一化测试数据,而不是通过训练样本得到的方差和均值进行归一化测试数据)这种非正常的情况,并且还需要batch-size为1时,那么就只能修改源码了:
      nn.functional文件(文件在报错的提示中出现了)中,把刚刚的那两行判断batch-size为1就报错的代码注释掉,如下图所示:
      File ".../miniconda3/envs/IGN/lib/python3.6/site-packages/torch/nn/functional.py", line 1666,
      在这里插入图片描述
      这个方法测试了一下,还是报错,我也不知道为什么。
    3. 解决方法三:
      这个问题就是因为数据集会剩余1个,所以我就从根本上解决问题。
      我直接删掉多出来的数据集,随机删掉一个即可。
      或者是在增加一个数据集即可。

    参考链接

    1. https://www.freesion.com/article/1452676290/
    2. https://blog.csdn.net/weixin_43732473/article/details/125661920
    3. https://blog.csdn.net/qq_37278761/article/details/117250865
  • 相关阅读:
    模电和爱情一样,都很难懂!
    #循循渐进学51单片机#函数进阶与按键#not.7
    通讯录多版本代码归纳
    一文了解Spring框架
    Docker 相关操作,及其一键安装Docker脚本
    [网络工程师]-路由配置-HSRP配置
    elementui组件兼容移动端
    数据结构之LinkedList与链表(上)
    Mongodb索引类型简介
    Python 光速入门课程
  • 原文地址:https://blog.csdn.net/pfl_327/article/details/127135543