如何在多次运行中重现RNN结果?

时间:2019-05-17 16:26:49

标签: pytorch recurrent-neural-network

我连续两次在相同的输入上调用相同的模型,但没有得到相同的结果,该模型具有nn.GRU层,因此我怀疑它具有一些内部状态,应在第二次运行之前释放该状态?

如何重置RNN隐藏状态以使其与最初加载模型时相同?

更新:

某些上下文:

我正在尝试从此处运行模型:

https://github.com/erogol/WaveRNN/blob/master/models/wavernn.py#L93

我正在致电generate

https://github.com/erogol/WaveRNN/blob/master/models/wavernn.py#L148

实际上在pytorch中使用随机生成器有一些代码:

https://github.com/erogol/WaveRNN/blob/master/models/wavernn.py#L200

https://github.com/erogol/WaveRNN/blob/master/utils/distribution.py#L110

https://github.com/erogol/WaveRNN/blob/master/utils/distribution.py#L129

我已放置(我正在CPU上运行代码):

torch.manual_seed(0)
torch.cuda.manual_seed_all(0)
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
np.random.seed(0)

https://github.com/erogol/WaveRNN/blob/master/utils/distribution.py

所有进口之后。

我检查了两次运行之间的GRU权重,它们是相同的:

https://github.com/erogol/WaveRNN/blob/master/models/wavernn.py#L153

我还检查了运行之间的logitssamplelogits是否相同,但sample不相同,所以@Andrew Naguib似乎对随机种子是正确的,但是我不确定应该将用于修复随机种子的代码放在哪里?

https://github.com/erogol/WaveRNN/blob/master/models/wavernn.py#L200

更新2:

我已将种子初始化放入generate内,现在结果是一致的:

https://github.com/erogol/WaveRNN/blob/master/models/wavernn.py#L148

2 个答案:

答案 0 :(得分:3)

我认为这可能与Random Seeding高度相关。为了确保可重复的结果(as stated by them),您必须像这样播种torch

import torch
torch.manual_seed(0)

还有CuDNN模块。

torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False

如果您使用的是numpy,也可以这样做:

import numpy as np
np.random.seed(0)

但是,他们警告您:

  

确定性模式可能会对性能产生影响,具体取决于您的模型。


我经常使用的建议脚本可以很好地再现结果,

# imports
import numpy as np
import random
import torch
# ...
""" Set Random Seed """
if args.random_seed is not None:
    """Following seeding lines of code are to ensure reproducible results 
       Seeding the two pseudorandom number generators involved in PyTorch"""
    random.seed(args.random_seed)
    np.random.seed(args.random_seed)
    torch.manual_seed(args.random_seed)
    # https://pytorch.org/docs/master/notes/randomness.html#cudnn
    if not args.cpu_only:
        torch.cuda.manual_seed(args.random_seed)
        cudnn.deterministic = True
        cudnn.benchmark = False

答案 1 :(得分:0)

您可以使用model.init_hidden()重置RNN隐藏状态。

def init_hidden(self):
     # Initialize hidden and cell states
     return Variable(torch.zeros(num_layers, batch_size, hidden_size))

因此,下一次在相同数据上调用相同模型之前,可以调用model.init_hidden()将隐藏状态和单元格状态重置为初始值。

这将清除历史记录,以顺序的方式显示首次运行数据后所学习的模型的权重。