合并的GRU和CNN网络始终为所有输入返回相同的值

时间:2019-07-17 14:17:23

标签: python pytorch lstm recurrent-neural-network gated-recurrent-unit

我正尝试训练CNN和GRU / LSTM的组合,以找出一系列移动的图片中objetcs的数量以及不移动的对象数。因此,我正在使用CNN来处理我的图像,并因此使用GRU。 我的问题是GRU对于每个输入集总是返回相同的值。可能是什么原因?

我已经尝试使用不同的学习率,并在GRU之后添加线性层。

我的网络:

cases p1
1     1
2     NA
3     2
4     NA

这是我的训练:


    class GRU(nn.Module):
        def __init__(self, **kwargs):
            super(GRU, self).__init__()
            self.n_class = int(kwargs.get("n_class"))
            self.seq_length = int(kwargs.get("seq_length"))
            self.input_shape = int(kwargs.get("input_shape"))
            self.n_channels = int(kwargs.get("n_channels"))
            self.conv1 = nn.Conv2d(in_channels=1 * seq_length, out_channels=4 * seq_length, kernel_size=5)
            self.conv2 = nn.Conv2d(in_channels=4 * seq_length, out_channels=8 * seq_length, kernel_size=5)
            self.conv3 = nn.Conv2d(in_channels=8 * seq_length, out_channels=16 * seq_length, kernel_size=5)
            self.rnn = nn.GRU(
                input_size=self.seq_length,
                hidden_size=64,
                num_layers=1,
                batch_first=True)
            self.linear = nn.Linear(64, 2)

        def forward(self, t):
            t = self.conv1(t)
            t = F.relu(t) 
            t = F.max_pool2d(t, kernel_size=2, stride=2)
            # second conv layer
            t = self.conv2(t)
            t = F.relu(t)
            t = F.max_pool2d(t, kernel_size=4, stride=4)
            # third conv layer
            t = self.conv3(t)
            t = F.relu(t)
            t = F.max_pool2d(t, kernel_size=3, stride=3)
            t = t.reshape(-1 , self.seq_length, 16 * 20 ** 2)
            t = t.permute(0,2,1)
            t, (h_n) =self.rnn(t)
            t = self.linear(t[:,-1])
            return t

以下是输出的实际标签示例:

for epoch in range(number_epochs):
    for batch in get_batch_generator(batch_size, rootdir, seq_length=seq_length):
        current_batch = batch[0].cuda()
        current_labels = batch[1].cuda()
        pre = nw(current_batch)
        loss_func = torch.nn.MSELoss()
        loss = loss_func(pre, current_labels)
        loss.backward()
        optimizer = optim.Adam(nw.parameters(), lr=learning_rate)
        optimizer.step()

我的网络的预测:

tensor([[ 4.,  5.],
        [10.,  0.],
        [10.,  0.],
        [ 2.,  9.],
        [ 5.,  1.],
        [10.,  0.]], device='cuda:0')

因此,对于这两个类,两个类(移动的对象和不移动的对象)的输出都是相同的,

1 个答案:

答案 0 :(得分:0)

最后,我发现有必要将每批的梯度设置为零。由于某些原因,这在我训练没有LSTM的正常CNN时不会造成问题。 在反向传播之前,需要在每个训练循环中添加以下命令:

optimizer.zero_grad()

nw.zero_grad()