介绍
执行CNN程序时,有很多部分取决于随机数,并且每次执行时输出结果都会改变。因此,对我而言,可能很难完全复制该论文(如果它在小数点后两位左右)。一个认真解决这个问题的故事。
单击此处以在gpu
上的
验证环境
macOS High Sierra 10.13.6
python 3.5.5
pytorch 0.4.0
火炬视觉0.2.1
验证
运行该程序3次,并比较结果(因为它很长,所以省略了)。
https://github.com/chatflip/qiita_code/blob/master/deterministic/not_deterministic1.py
终奌站
1 | ~/qiita_code/deterministic$ python not_deterministic1.py |
not_deterministic1.py
1 2 3 4 5 | 1回目 2回目 3回目 Train Epoch: 1 [0/60000 (0%)] Loss: 2.304123 Loss: 2.300169 Loss: 2.294914 Train Epoch: 1 [64/60000 (0%)] Loss: 2.306989 Loss: 2.302103 Loss: 2.290142 Train Epoch: 1 [128/60000 (0%)] Loss: 2.319033 Loss: 2.294176 Loss: 2.300677 Train Epoch: 1 [192/60000 (0%)] Loss: 2.305209 Loss: 2.313074 Loss: 2.310522 |
每次执行时,
损失都有不同的值。
- 加载的图像的变形(例如Transforms.RandomCrop)
-
数据集改组(例如DataLoader
shuffle=True ) - 初始网络权重(例如,Nn。Conv2d。权重)
捕获pytorch / torchvision库以修复这些随机数的种子。
加载的图像变形
在
torchvision.transforms中使用的随机数在python标准库中是随机的。
因此,使用
transforms.RandomCrop 的随机部分
https://github.com/pytorch/vision/blob/v0.2.1/torchvision/transforms/transforms.py#L399
transforms.RandomHorizo??ntalFlip的随机部分
https://github.com/pytorch/vision/blob/v0.2.1/torchvision/transforms/transforms.py#L447
python标准库随机
https://docs.python.jp/3.5/library/random.html
数据集洗牌
如果
DataLoader的shuffle参数设置为True,则将在函数中调用RandomSampler。
在RandomSampler内部,
可以使用torch.manual_seed()设置torch.randperm的随机种子。
随机抽样创建操作列在[随机抽样]和...
(https://pytorch.org/docs/0.4.0/torch.html#random-sampling)
https://pytorch.org/docs/0.4.0/torch.html?highlight=randperm#creation-ops
Dataloader shuffle = True
https://github.com/pytorch/pytorch/blob/v0.4.0/torch/utils/data/dataloader.py#L434
RandomSampler的随机数部分
https://github.com/pytorch/pytorch/blob/v0.4.0/torch/utils/data/sampler.py#L51
torch.manual_seed
https://pytorch.org/docs/0.4.0/torch.html?highlight=randperm#torch.manual_seed
网络的初始值
声明
nn.Conv2d时,nn.Parameter()存储在self.weight中,并使用torch.Tensor的uniform_(统一随机数)进行初始化。
也可以使用torch.manual_seed()进行设置。
nn.ConvNd重量设置
https://github.com/pytorch/pytorch/blob/v0.4.0/torch/nn/modules/conv.py#L31
https://github.com/pytorch/pytorch/blob/v0.4.0/torch/nn/modules/conv.py#L45
重新验证
根据上述内容执行程序(not_deterministic2.py)
终奌站
1 | ~/qiita_code/deterministic$ python not_deterministic2.py --num_workers=0 |
not_deterministic2.py
1 2 3 4 5 | 1回目 2回目 3回目 Train Epoch: 1 [0/60000 (0%)] Loss: 2.283671 Loss: 2.283671 Loss: 2.283671 Train Epoch: 1 [64/60000 (0%)] Loss: 2.313809 Loss: 2.313809 Loss: 2.313809 Train Epoch: 1 [128/60000 (0%)] Loss: 2.318310 Loss: 2.318310 Loss: 2.318310 Train Epoch: 1 [192/60000 (0%)] Loss: 2.315323 Loss: 2.315323 Loss: 2.315323 |
结果相同。但是num_worker