#python #machine-learning #deep-learning #pytorch #recurrent-neural-network
#python #машинное обучение #глубокое обучение #pytorch #рекуррентная нейронная сеть
Вопрос:
Попытка использовать пользовательскую функцию потерь и получение ошибки ‘RuntimeError: элемент 0 тензоров не требует grad и не имеет grad_fn’. Ошибка возникает во время loss.backward()
Я знаю, что все вычисления должны выполняться в тензорах с ‘require_grad = True’ . У меня возникли проблемы с реализацией этого, поскольку мой код требует вложенного цикла for . Я полагаю, что это может быть цикл for. Есть ли способ создать пустой тензор и добавить его? Ниже приведен мой код.
def Gaussian_Kernal(x, mu, sigma):
p = (1./(math.sqrt(2. * math.pi * (sigma**2)))) * torch.exp((-1.) * (((Variable(x)**2) - mu)/(2. * (sigma**2))))
return p
class MEE(torch.nn.Module):
def __init__(self):
super(MEE,self).__init__()
def forward(self,output, target, mu, variance):
error = torch.subtract(Variable(output),Variable(target))
error_diff = []
for i in range(0, error.size(0)):
for j in range(0, error.size(0)):
error_diff.append(error[i] - error[j])
error_diff = torch.cat(error_diff)
torch.tensor(error_diff,requires_grad=True)
loss = (1./(target.size(0)**2)) * torch.sum(Gaussian_Kernal(Variable(error_diff), mu, variance*(2**0.5)))
loss = Variable(loss)
return loss
Ответ №1:
Пока вы работаете с тензорами и применяете функции PyTorch и базовые операторы, это должно работать. Поэтому нет необходимости переносить ваши переменные с torch.tensor
помощью или Variable
. Последнее устарело (я полагаю, начиная с версии 0.4).
API переменных устарел: переменные больше не нужны для использования autograd с тензорами. Autograd автоматически поддерживает тензоры с require_grad, установленным в True. Документы PyTorch
Я предполагаю output
, что и target
являются тензорами, а mu
и variance
являются реалами, а не тензорами? Тогда первым измерением output
и target
будет пакет.
def Gaussian_Kernel(x, mu, sigma):
p = (1./(math.sqrt(2. * math.pi * (sigma**2)))) * torch.exp((-1.) * (((x**2) - mu)/(2. * (sigma**2))))
return p
class MEE(torch.nn.Module):
def __init__(self):
super(MEE, self).__init__()
def forward(self, output, target, mu, variance):
error = output - target
error_diff = []
for i in range(0, error.size(0)):
for j in range(0, error.size(0)):
error_diff.append(error[i] - error[j]) # Assuming that's the desired operation
error_diff = torch.cat(error_diff)
kernel = Gaussian_Kernel(error_diff, mu, variance*(2**0.5))
loss = (1./(target.size(0)**2))*torch.sum(kernel)
return loss
Комментарии:
1. ваши предположения верны. mu и дисперсия являются действительными. Первое измерение тензоров — это размер пакета. Я думаю, что проблема в списке error_diff. Я вычисляю разницу в ошибках для каждой точки пакета. Я думаю, что копирование из списка в тензор приводит к ошибке, но я не уверен. Есть ли способ выполнить эту операцию только с тензорами? Я не думаю, что это ошибка в моей сети, потому что простой MSELoss() работает хорошо.
2. Это должно быть
error[i] - error[j]
тогда. Я не думаю, что создание нового спискаerror_diff
является проблемой, если вы создаете стек или впоследствии объединяете их в тензор. Он все еще не работает?3. Он по-прежнему выдает ту же ошибку. Я сохранил ошибку [i] — ошибка [j] . torch.cat создает копию списка в виде тензора.
4. Я также могу поделиться им через colab, если это поможет
5. У меня это работает, обязательно удалите
Variable
обертываниеx
в вашейGaussian_Kernel
функции, я думаю, вы забыли его удалить.