本博客用于记录在学习pytorch时遇到的零碎问题,持续更新(但愿)
参考:
https://blog.csdn.net/u013548568/article/details/81368019
https://pytorch-cn.readthedocs.io/zh/latest/package_references/torch-cuda/
torch.cuda.synchronize() # 等待当前设备上所有流中的所有核心完成。
start = time.time()
result = model(input)
torch.cuda.synchronize()
end = time.time()
来源:https://pytorch.org/docs/stable/data.html#torch.utils.data.DataLoader
pin_memory的作用:如果CPU tensor原来没有在固定内存中,则将tensor复制到固定内存中,这样可以使主机到GPU的复制速度更快。
注意:默认的内存固定逻辑(memory pinning logic)只能够识别Tensors、maps和iterable containing Tesnors,所以,如果batch是自定义的(比如用 collate_fn
来返回一个自定义的batch类型),或者batch中的每个元素都是自定义的,则不会被识别,也就是说此时pinning logic返回的是没有固定内存的batch。为了能够让自定义的batch或数据类型实现内存固定,需要在自定义类型中定义pin_memory
方法。比如:
class SimpleCustomBatch:
def __init__(self, data):
transposed_data = list(zip(*data))
self.inp = torch.stack(transposed_data[0], 0)
self.tgt = torch.stack(transposed_data[1], 0)
# custom memory pinning method on custom type
def pin_memory(self):
self.inp = self.inp.pin_memory() # 单独定义pin_memory()
self.tgt = self.tgt.pin_memory()
return self
def collate_wrapper(batch):
return SimpleCustomBatch(batch)
inps = torch.arange(10 * 5, dtype=torch.float32).view(10, 5)
tgts = torch.arange(10 * 5, dtype=torch.float32).view(10, 5)
dataset = TensorDataset(inps, tgts)
loader = DataLoader(dataset, batch_size=2, collate_fn=collate_wrapper,
pin_memory=True)
for batch_ndx, sample in enumerate(loader):
print(sample.inp.is_pinned())
print(sample.tgt.is_pinned())
2021-3-27
问题:batch size不能被整除。
一共有19130个训练数据,我设置的batch size=4,训练到最后一个iter的时候显示如下错误:
ValueError: Expected input batch_size(4) to match target batch_size(2)
解决办法:
参考:https://blog.csdn.net/qazwsxrx/article/details/108119029
在torch.utils.data.DataLoader
中设置drop_last=True
,丢弃最后不够的batch。
2021-3-27
来源:https://blog.csdn.net/u013289254/article/details/98785869
偏置的大小控制着激活神经元的难易程度。如果卷积后面接着BN,由于BN有去均值的作用,所以可以不加偏置,也就是设置bias=Flase
。默认bias=True
。
【tag:timeit、conv1d、linear】
import torch
import timeit
linear = torch.nn.Linear(256, 512).cuda()
conv = torch.nn.Conv1d(256,512,1).cuda()
input = torch.randn((128, 4096, 256)).cuda()
print(timeit.timeit("_ = linear(input)", number=3, setup="from __main__ import input, linear"))
input = input.permute(0,2,1)
print(timeit.timeit("_ = conv(input)", number=3, setup="from __main__ import conv, input"))
改变输入的size大小时,linear所需时间基本不变,但conv1d的时间会随着输入size的增大而增大。当输入的size比较小的时候,conv1d(k=1)比linear的计算速度更快,但当输入的size很大时,conv1d的速度就比linear慢不少。
存疑:conv1d(k=1)和linear的区别。
2021-3-28
来源:https://zhuanlan.zhihu.com/p/61725100
BN和Dropout单独使用都能减少过拟合并加速训练速度,但如果一起使用的话并不会产生1+1>2的效果,相反可能会得到比单独使用更差的效果。相关的研究参考论文:Understanding the Disharmony between Dropout and Batch Normalization by Variance Shift。本论文作者发现理解 Dropout 与 BN 之间冲突的关键是网络状态切换过程中存在神经方差的(neural variance)不一致行为。试想若有图一中的神经响应 X,当网络从训练转为测试时,Dropout 可以通过其随机失活保留率(即 p)来缩放响应,并在学习中改变神经元的方差,而 BN 仍然维持 X 的统计滑动方差。这种方差不匹配可能导致数值不稳定。而随着网络越来越深,最终预测的数值偏差可能会累计,从而降低系统的性能。简单起见,作者们将这一现象命名为「
方差偏移
」。事实上,如果没有 Dropout,那么实际前馈中的神经元方差将与 BN 所累计的滑动方差非常接近,这也保证了其较高的测试准确率。
代码:
parser = argparse.ArgumentParser()
parser.add_argument('configs', nargs='+', default='configs/c1.py')
args, opts = parser.parse_known_args()
直接右键运行,报错:
usage: train.py [-h] [--devices DEVICES] [--evaluate] configs [configs ...]
train.py: error: the following arguments are required: configs
原因:
python args parse_args() 报错 xxx.py: error: the following arguments are required: xxx
args分为可选参数和必选参数。–指定可选参数,不加–指定的是必选参数,必选参数必须手动指定参数,此时即使通过default设置默认参数,也还是会报错
。
修改:
parser = argparse.ArgumentParser()
parser.add_argument('--configs', nargs='+', default='configs/c1.py')
args, opts = parser.parse_known_args()