Вес и результаты PyTorch не меняются - PullRequest
0 голосов
/ 19 марта 2019

Мне действительно нравится использовать PyTorch для классификации и регрессии.У меня есть новая интересная проблема, которую я хочу решить, и я не могу найти решение, я чувствую, что я действительно близко.

Моя проблема: я создал сеть с тремя выходами, назовем их x, y и z У меня есть функция F (x, y, z), которая возвращает значение в диапазоне от 0,0 до 100,0, где 100 лучше. Моя собственная потеря, таким образом, составляет 100-F (x, y, z) на каждом шаге. Цель состоит в том, чтобывыяснить наилучшую комбинацию выходов для задачи F (...) (я знаю, что генетический алгоритм превзойдет это, это мой проект прямо сейчас, чтобы доказать это на множестве проблем)

Для реализации вышеизложенного,Я заставляю сеть иметь 1 часть входных данных и размер пакета 1, а затем в потере мы просто полностью игнорируем «истинные» и «прогнозируемые» значения и заменяем потерю 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 голосов
/ 20 марта 2019

Во-первых, применение двух 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, который не является Тензорным и не может записывать операции backprop, так что по сути вы рассчитываете свой убыток на detached тензор

Я думаю, я знаю, чего вы пытаетесь достичь.в этой строке:

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

вы, вероятно, хотите detach второй вывод, он аналогичен stop_grad() TF.

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