потеря.назад() нет градации в pytorch NN

#machine-learning #neural-network #pytorch

Вопрос:

Код выдает ошибку в потере.обратная() Ошибка: ошибка времени: элемент 0 тензоров не требует градации и не имеет grad_fn

 for epoch in range(N_EPOCHS):  model.train()  for i,(im1, im2, labels) in enumerate(train_dl):  i1 = torch.flatten(im1,1)  i2 = torch.flatten(im2,1)  inp = torch.cat([i1,i2],1)    b_x = Variable(inp) # batch x  b_y = Variable(labels) # batch y  y_ = model(b_x).squeeze()  y_ = (y_gt;0.5).float()    print(y_)  print(l)  loss = criterion(y_,b_y)  print(loss.item())  loss.backward()  optimizer.step()  

Комментарии:

1. y_ gt; 0.5 lt;- ты не можешь этого сделать, преобразование создает разрыв в графике. Какова именно цель этого ? Не могли бы вы уточнить ?

2. На самом деле, я даю 2 сплющенных изображения, соединенных на входе и выходе, независимо от того, принадлежат ли они одному и тому же человеку или нет.

3. Вот почему я занимаюсь пороговым значением.

4. в чем же дело .shape y_ ? И что criterion это такое ?

5. y_-это тензор [100,1], а метки-тензор размера [100], из-за которого я сжал y_, я удалил y_ = (y_gt;0,5), и ошибка удалена. Но мои данные не подходят для первой партии

Ответ №1:

 y_ = (y_gt;0.5).float()  

имеет нулевой градиент, интуитивно, потому что «крошечные изменения в аргументе не приводят к абсолютно никакому изменению значения (представьте, что y_ изменения на крошечный эпсилон, это не влияет на значение y_ .

Комментарии:

1. Я не понял, что вы подразумеваете под «не приведет ни к каким изменениям»??

2. Модель возвращает вероятность, поэтому мы установили пороговое значение, чтобы сделать его равным нулю или единице.

3. Подумайте о любом y_, близком к 0,7. Будет ли y_ отличаться, если вы измените его на крошечный эпсилон? Нет, это будет 1 постоянно. Это «абсолютно никаких изменений», интуитивный способ понять, почему градиент будет равен 0 (и даже не реализован). Вы не можете использовать пороговое значение и (по крайней мере, наивное) обучение на основе градиентов вместе. Вы можете использовать пороговое значение при вычислении показателя оценки, но не потери, которые вы хотите дифференцировать. Вот почему мы минимизируем перекрестную энтропию, а не максимизируем точность и т. Д.

4. Я имел в виду, что «будет ли *результат y_», конечно, другим.

Ответ №2:

С дополнительной информацией, предоставленной OP в комментарии, правильный подход здесь-просто удалить строку

 y_ = (y_gt;0.5).float()