Python 回归损失函数不正确

Python 回归损失函数不正确,python,machine-learning,deep-learning,pytorch,Python,Machine Learning,Deep Learning,Pytorch,我正在尝试一个基本的平均示例,但是如果我增加训练时间,验证和损失不匹配,网络无法收敛。我正在训练一个包含2个隐藏层的网络,每个层的宽度为500个单位,范围为[0,9],学习率为1e-1,Adam,批量大小为1,退出3000次迭代,每100次迭代验证一次。如果标签和假设之间的绝对差值小于阈值,在这里,我将阈值设置为1,我认为是正确的。有人能告诉我这是否是损失函数选择的问题,Pytorch有什么问题,或者我正在做什么。以下是一些图表: val_diff = 1 acc_diff = torch.Fl

我正在尝试一个基本的平均示例,但是如果我增加训练时间,验证和损失不匹配,网络无法收敛。我正在训练一个包含2个隐藏层的网络,每个层的宽度为500个单位,范围为[0,9],学习率为1e-1,Adam,批量大小为1,退出3000次迭代,每100次迭代验证一次。如果标签和假设之间的绝对差值小于阈值,在这里,我将阈值设置为1,我认为是正确的。有人能告诉我这是否是损失函数选择的问题,Pytorch有什么问题,或者我正在做什么。以下是一些图表:

val_diff = 1
acc_diff = torch.FloatTensor([val_diff]).expand(self.batch_size)
在验证过程中循环100次至:

num_correct += torch.sum(torch.abs(val_h - val_y) < acc_diff)
以下是一些假设和标签的示例:

[...(-0.7043088674545288, 6.0), (-0.15691305696964264, 2.6666667461395264),
 (0.2827358841896057, 3.3333332538604736)]
我尝试了API中通常用于回归的六个损失函数:

torch.nn.L1LOSSIZE_平均值=假

火炬

torch.nn.mselossize_average=False

火炬

torch.nn.SmoothL1Losssize_平均值=False

火炬

谢谢

网络代码:

class Feedforward(nn.Module):
    def __init__(self, topology):
        super(Feedforward, self).__init__()
        self.input_dim     = topology['features']
        self.num_hidden    = topology['hidden_layers']
        self.hidden_dim    = topology['hidden_dim']
        self.output_dim    = topology['output_dim']
        self.input_layer   = nn.Linear(self.input_dim, self.hidden_dim)
        self.hidden_layer  = nn.Linear(self.hidden_dim, self.hidden_dim)
        self.output_layer  = nn.Linear(self.hidden_dim, self.output_dim)
        self.dropout_layer = nn.Dropout(p=0.2)


    def forward(self, x):
        batch_size = x.size()[0]
        feat_size  = x.size()[1]
        input_size = batch_size * feat_size

        self.input_layer = nn.Linear(input_size, self.hidden_dim).cuda()
        hidden = self.input_layer(x.view(1, input_size)).clamp(min=0)

        for _ in range(self.num_hidden):
            hidden = self.dropout_layer(F.relu(self.hidden_layer(hidden)))

        output_size = batch_size * self.output_dim
        self.output_layer = nn.Linear(self.hidden_dim, output_size).cuda()
        return self.output_layer(hidden).view(output_size)
培训代码:

def train(self):
    if self.cuda:
        self.network.cuda()

    dh        = DataHandler(self.data)
    # loss_fn = nn.L1Loss(size_average=False)
    # loss_fn = nn.L1Loss()
    # loss_fn = nn.SmoothL1Loss(size_average=False)
    # loss_fn = nn.SmoothL1Loss()
    # loss_fn = nn.MSELoss(size_average=False)
    loss_fn   = torch.nn.MSELoss()
    losses    = []
    validate  = []
    hypos     = []
    labels    = []
    val_size  = 100
    val_diff  = 1
    total_val = float(val_size * self.batch_size)

    for i in range(self.iterations):
        x, y = dh.get_batch(self.batch_size)
        x = self.tensor_to_Variable(x)
        y = self.tensor_to_Variable(y)

        self.optimizer.zero_grad()
        loss = loss_fn(self.network(x), y)
        loss.backward()
        self.optimizer.step()

看起来您误解了pytorch中的层是如何工作的,以下是一些提示:

在你前进时,当你做nn。线性。。。您正在定义新层,而不是使用您在网络中预先定义的层。因此,它无法学到任何东西,因为权重不断地重新调整

你不需要打电话。cuda内网。转发。。。因为您已经通过调用self.network.cuda在列车的gpu上复制了网络

理想情况下,网前。。。输入应该直接具有第一层的形状,这样您就不必修改它。这里应该有x.size Linear->Batch\u size,特性

你的前锋应该密切关注这一点:

def forward(self, x):
    x = F.relu(self.input_layer(x))
    x = F.dropout(F.relu(self.hidden_layer(x)),training=self.training)
    x = self.output_layer(x)
    return x

在更新权重后是否将渐变归零?这是一个常见的错误。此外,您的学习率似乎很高。@mexmex我不是应该在每次迭代中清除局部梯度吗?这不是优化器的目的吗?零梯度?是的,只是检查你是否真的这么做了!抱歉,如果我的语言模棱两可。你能给我们看一下神经网络代码吗?@Cedias我刚刚用代码更新了我的帖子,所以每次迭代我都初始化了新的层以适应动态输入。pytorch是否能自动为您处理动态输入和动态批处理?@Soubriquet动态输入和动态批处理是什么意思?但是,在每个输入上使用新的权重是不起作用的。是的,你如何动态地处理批处理批处理大小在批处理之间的变化,因为层不需要固定的批处理输入。所以pytorch会自动处理这个问题?
def forward(self, x):
    x = F.relu(self.input_layer(x))
    x = F.dropout(F.relu(self.hidden_layer(x)),training=self.training)
    x = self.output_layer(x)
    return x