PyTorch的权重和输出未更改

时间:2019-03-19 19:44:29

标签: python machine-learning deep-learning pytorch backpropagation

我真的很喜欢使用PyTorch进行分类和回归。我有一个有趣的新问题要解决,但我想不出解决方案,我觉得我真的很接近。

我的问题: 我创建了一个具有三个输出的网络,我们称它们为x,y和z 我有一个函数F(x,y,z)返回一个介于0.0和100.0之间的值,其中100更好 因此,我的自定义损失在每一步都是100-F(x,y,z) 目的是找出问题F(...)的最佳输出组合 (我知道遗传算法的性能会比这好,这是我目前在一系列问题上证明它的项目)

为实现上述目的,我强制网络具有1个输入数据且批处理大小为1,然后在损失中,我们完全忽略了“ true”和“ predicted”值,并用100代替损失-F(x,y,z)。基本上,我们的权重和输出将在每个时期导致一个解决方案,并且该解决方案的适应性与给出损失的最大可能适应性成反比(即,适应性100将导致损失0、100-100)。

由于F(...)要求将输出舍入为整数。为避免这成为问题,我有很大的动力和学习速度。

我遇到的问题是,尽管损失函数正在运行,并且我的第一个[x,y,z]正在评估中,但值永远不会改变。网络无法从产生的结果中学习。

我的代码如下: 注意testnetwork()太长,无法粘贴,但是它是上面提到的F(x,y,z)-任何虚拟函数都可以替换它,例如。 'return x + z y / 2'等以最小化此功能(100-x + z y / 2)

import torch
import torch.nn as nn

from testnetwork import *


n_in, n_h, n_out, batch_size = 10, 5, 3, 5

x = torch.randn(batch_size, n_in)
y = torch.tensor([[1.0], [1.0], [1.0], [1.0], [1.0], [1.0], [1.0], [0.0], [1.0], [1.0]])

model = nn.Sequential(nn.Linear(n_in, n_h),
                     nn.ReLU(),
                     nn.ReLU()
                     )

def fitness(string):
    print(string)
    list = string.split(",")
    list[0] = (int(round(float(list[0]))))
    list[1] = (int(round(float(list[1]))))
    list[2] = (int(round(float(list[2]))))
    print(list)
    loss = 100 - testnetwork(list[0], list[1], list[2])
    return loss


def my_loss(output, target):
    table = str.maketrans(dict.fromkeys('tensor()'))
    ftn = fitness(str(output.data[0][0]).translate(table) + ", " + str(output.data[0][1]).translate(table) + ", " + str(output.data[0][2]).translate(table))


    loss = torch.mean((output - output)+ftn)

    return loss



#optimizer = torch.optim.SGD(model.parameters(), lr=1, momentum=2)
optimizer = torch.optim.Adam(model.parameters(), lr=1, momentum=2)

for epoch in range(10):
    # Forward Propagation
    y_pred = model(x)
    # Compute and print loss
    loss = my_loss(y_pred, y)
    print('epoch: ', epoch,' loss: ', loss.item())
    # Zero the gradients
    optimizer.zero_grad()

    # perform a backward pass (backpropagation)
    loss.backward(retain_graph=True)

    # Update the parameters
    optimizer.step()

非常感谢您阅读我的帖子!

epoch:  0  loss:  50.339725494384766
0., 0.0200, 0.6790
[0, 0, 1]
testing: [0, 0, 1]
epoch:  1  loss:  50.339725494384766
0., 0.0200, 0.6790
[0, 0, 1]
testing: [0, 0, 1]
epoch:  2  loss:  50.339725494384766
0., 0.0200, 0.6790
[0, 0, 1]
testing: [0, 0, 1]
epoch:  3  loss:  50.339725494384766
0., 0.0200, 0.6790
[0, 0, 1]
testing: [0, 0, 1]
epoch:  4  loss:  50.339725494384766
0., 0.0200, 0.6790
[0, 0, 1]

..依此类推,似乎从一个纪元到另一个纪元都没有改变。

1 个答案:

答案 0 :(得分:0)

首先,相继应用两个ReLU是没有用的,而应用一个就足够了。

第二次,您的问题出在这行

ftn = fitness(str(output.data[0][0]).translate(table) + ", " + str(output.data[0][1]).translate(table) + ", " + str(output.data[0][2]).translate(table))

您正在调用.data,它不是张量并且无法记录反向传播操作,因此从本质上来说,您是在detached张量上计算损失

我想,我知道您想要实现的目标。在这一行:

loss = torch.mean((output - output)+ftn)

您可能想要detach的第二个输出,它类似于TF的stop_grad()

loss = torch.mean((output - output.detach())+ftn)