【问题标题】:Implementing a many-to-many regression task实现多对多回归任务
【发布时间】:2019-05-09 01:59:54
【问题描述】:

对不起,如果我没有清楚地表达我的问题,英语不是我的第一语言

问题

简短说明:

我想训练一个模型,它将输入x(形状为[n_sample, timestamp, feature])映射到输出y(形状完全相同)。这就像映射 2 个空间

加长版:

我有 2 个形状为 [n_sample, timestamp, feature] 的浮点 ndarrays,代表 n_sample 音频文件的 MFCC 特征。这2个ndarray是同一语料库的2个说话者的语音,由DTW对齐。让我们将这两个数组命名为 xy。我想训练一个模型,在给定x[k] 的情况下预测y[k]。这就像从空间x 到空间y 的映射,并且输出必须与输入的形状完全相同

我尝试过的

这是时间序列问题,所以我决定使用RNN 方法。这是我在 PyTorch 中的代码(我在代码中添加了注释。为简单起见,我删除了平均损失的计算)。请注意,我已经尝试了许多学习率选项,但行为仍然相同

类定义

class Net(nn.Module):
    def __init__(self, in_size, hidden_size, out_size, nb_lstm_layers):
        super().__init__()
        self.in_size = in_size
        self.hidden_size = hidden_size
        self.out_size = out_size
        self.nb_lstm_layers = nb_lstm_layers

        # self.fc1 = nn.Linear()
        self.lstm = nn.LSTM(input_size=self.in_size, hidden_size=self.hidden_size, num_layers=self.nb_lstm_layers, batch_first=True, bias=True)
        # self.fc = nn.Linear(self.hidden_size, self.out_size)
        self.fc1 = nn.Linear(self.hidden_size, 128)
        self.fc2 = nn.Linear(128, 128)
        self.fc3 = nn.Linear(128, self.out_size)

    def forward(self, x, h_state):
        out, h_state = self.lstm(x, h_state)
        output_fc = []

        for frame in out:
            output_fc.append(self.fc3(torch.tanh(self.fc1(frame)))) # I added fully connected layer to each frame, to make an output with same shape as input

        return torch.stack(output_fc), h_state

    def hidden_init(self):
        if use_cuda:
            h_state = torch.stack([torch.zeros(nb_lstm_layers, batch_size, 20) for _ in range(2)]).cuda()
        else:
            h_state = torch.stack([torch.zeros(nb_lstm_layers, batch_size, 20) for _ in range(2)])

        return h_state

训练步骤:

net = Net(20, 20, 20, nb_lstm_layers)
optimizer = optim.Adam(net.parameters(), lr=0.0001, weight_decay=0.0001)
criterion = nn.MSELoss()

for epoch in range(nb_epoch):
    count = 0
    loss_sum = 0

    batch_x = None
    for i in (range(len(data))): 
    # data is my entire data, which contain A and B i specify above.
        temp_x = torch.tensor(data[i][0])
        temp_y = torch.tensor(data[i][1])

        for ii in range(0, data[i][0].shape[0] - nb_frame_in_batch*2 + 1): # Create batches 
            batch_x, batch_y = get_batches(temp_x, temp_y, ii, batch_size, nb_frame_in_batch)  
            # this will return 2 tensor of shape (batch_size, nb_frame_in_batch, 20), 
            # with `batch_size` is the number of sample each time I feed to the net, 
            # nb_frame_in_batch is the number of frame in each sample
            optimizer.zero_grad()

            h_state = net.hidden_init()

            prediction, h_state = net(batch_x.float(), h_state)
            loss = criterion(prediction.float(), batch_y.float())

            h_state = (h_state[0].detach(), h_state[1].detach())

            loss.backward()
            optimizer.step()

问题是,损失似乎没有减少而是波动很大,没有明确的行为

请帮助我。任何建议将不胜感激。如果有人可以检查我的代码并提供一些评论,那就太好了。
提前致谢!

【问题讨论】:

  • 如果您的算法使用梯度下降,这种意外行为可能是由于学习率太高。如果你采取的步骤太大,你可能会远离损失函数的局部最小值,而不是接近它。简而言之:尝试降低你的学习率。
  • 感谢您的建议。我已经为 lr 尝试了很多选择。这似乎不是lr的错。我认为不良行为来自架构。我将编辑我的帖子以降低学习率,因为这个 0.01 无论如何都太高了
  • 无论如何,您的问题可能更适合datascience.stackexchange.comstats.stackexchange.com,因为它不是编程问题。
  • 我已经考虑过了。但就我而言,除了寻求一般问题的建议外,我还希望有人检查我的代码并告诉我我做错了什么。所以 SO 比 DS/stat 更适合

标签: python deep-learning lstm pytorch


【解决方案1】:

似乎网络从您的数据中没有学到任何东西,因此损失波动(因为权重仅取决于随机初始化)。您可以尝试以下方法:

  • 尝试规范化数据(这个建议很宽泛,但由于我没有你的数据,所以我不能给你更多细节,但是把它规范化到一个特定的范围,比如 [0, 1],或者均值和标准值值得一试)
  • pytorch 中 LSTM 的一个非常典型的问题是它的输入维度与其他类型的神经网络完全不同。您必须向网络输入一个形状为 (seq_len、batch、input_size) 的张量。你应该去here,LSTM 部分了解更多详情
  • 还有一件事:尝试调整您的超参数。与 FC 或 CNN 相比,LSTM 更难训练(根据我的经验)。

如果您有改进,请告诉我。调试神经网络总是很困难并​​且充满潜在的编码错误

【讨论】:

  • 第二个正是我所需要的。我输入的形状不正确。损失正在稳定下降。谢谢
【解决方案2】:

对于大多数机器学习算法,如果不查看数据就很难进行诊断。根据您的损失结果的不一致,这可能是您的数据预处理的问题。您是否尝试过先规范化数据?通常情况下,结果波动很大,您的输入神经元值之一可能会扭曲您的损失函数,使其无法找到好的方向。 How to normalize a NumPy array to within a certain range? 这是音频标准化的示例,但我也会尝试调整学习率,因为它看起来很高,并可能移除隐藏层。

【讨论】:

  • 抱歉回复晚了。我的数据是音频 MFCC 特征,我尝试使用非规范、特征维度的规范、时间戳维度的规范来训练网络(通过使用规范,我的意思是多种规范,01 -11 ...)没有帮助。我认为问题出在架构上
【解决方案3】:

可能问题出在损失的计算上。尝试对序列中每个时间步的损失求和,然后取该批次的平均值。希望对你有帮助

【讨论】:

    猜你喜欢
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多