首页 > 解决方案 > PyTorch CNN 永远不会收敛(怀疑是实现问题)

问题描述

我无法让这个网络按需要工作。我已经尝试了这个模型的多次迭代,但无法得到合理的错误(它永远不适合,甚至不能让它过拟合)。

我哪里出错了?任何帮助将不胜感激

作为参考,有 12 个形状为 49,9 的输入“图像”(它们实际上是河口 9 个站点的水面高程)和 12 个形状为 1,9 的标签。

完整的数据示例可以在https://gitlab.com/jb4earth/effonn/找到

  net = []
  class Net(torch.nn.Module):
      def __init__(self, kernel_size):
          super(Net, self).__init__()
          mid_size = (49*49*9)
          self.predict = torch.nn.Sequential(
              nn.Conv2d(
                          in_channels=1,
                          out_channels=mid_size,
                          kernel_size=kernel_size,
                          stride=1,
                          padding=(0, 0)
                      ),
              nn.ReLU(),
              nn.MaxPool2d(1),
              nn.ReLU(),
              nn.Conv2d(
                          in_channels=mid_size,
                          out_channels=1,
                          kernel_size=kernel_size,
                          stride=1,
                          padding=(0, 0)
                      ),
              nn.ReLU()
          )


      def forward(self, x):
          x = self.predict(x)
          return x

  def train_network(x,y,optimizer,loss_func):
      prediction = net(x)    
      loss = loss_func(prediction, y.squeeze())     
      optimizer.zero_grad()  
      loss.backward()     
      optimizer.step()    
      return prediction, loss


  net = Net((1,1))
  optimizer = torch.optim.Adam(net.parameters(), lr=0.01)
  loss_func = torch.nn.MSELoss()
  cnt = 0
  t = True
  while t == True:
      # get_xy in place of DataLoader
      (x,y) = get_xy(input_data,output_data,cnt)
      # x.shape is 1,1,49,9
      # y.shape is 1,1,1,9

      # train and predict
      (prediction,loss) = train_network(x,y,optimizer,loss_func)

      # prediction shape different than desired so averaging all results
      prediction_ = torch.mean(prediction)

      # only 12 IO's so loop through 
      cnt += 1
      if cnt > 11:
          cnt = 0

标签: pytorch

解决方案


看看这里,这看起来很可疑。您正在计算损失,然后使梯度为零。在计算损失之前应该调用零梯度。所以你需要将 optimizer.zero_grad() 切换到顶部,我认为它会起作用。我无法重现您的示例,这就是为什么我猜这是您的错误。

  loss = loss_func(prediction, y.squeeze())     
  optimizer.zero_grad()   # switch this to the top  
  loss.backward()     
  optimizer.step() 

推荐阅读