Почему в этом примере необходимо вызвать команду detach для переменной?
Я проходил через этот пример - https://github.com/pytorch/examples/blob/master/dcgan/main.py и у меня есть основной вопрос.
fake = netG(noisev)
labelv = Variable(label.fill_(fake_label))
output = netD(fake.detach()) # detach to avoid training G on these labels
errD_fake = criterion(output, labelv)
errD_fake.backward()
D_G_z1 = output.data.mean()
errD = errD_real + errD_fake
optimizerD.step()
Я понимаю, почему мы вызываем detach()
переменную fake
, чтобы не вычислялись градиенты для параметров генератора. Мой вопрос в том, имеет ли это значение, так как optimizerD.step()
собирается обновить параметры, связанные только с дискриминатором?
Кроме того, на следующем шаге, когда мы будем обновлять параметры для генератора, перед этим мы будем вызов netG.zero_grad()
, который в конечном итоге удаляет все ранее вычисленные градиенты. Более того, когда мы обновляем параметры для сети G, мы делаем это - output = netD(fake)
. Здесь мы не используем detach. Почему?
Итак, почему в приведенном выше коде необходимо отсоединить переменную (строка 3)?
2 ответа:
Вы правы,
optimizerD
только обновляетnetD
и градиенты наnetG
не используются до вызоваnetG.zero_grad()
, поэтому отсоединение не нужно, это просто экономит время, потому что вы не вычисляете градиенты для генератора.Вы в основном также отвечаете на свой другой вопрос самостоятельно, вы не отсоединяете
fake
во втором блоке, потому что вы специально хотите вычислить градиенты наnetG
, чтобы иметь возможность обновить его параметры.Обратите внимание, как во втором блоке
real_label
используется в качестве соответствующая метка дляfake
, так что если дискриминатор находит поддельный вход реальным, конечная потеря невелика, и наоборот, что именно то, что вы хотите для генератора. Не уверен, что это то, что смутило вас, но это действительно единственная разница по сравнению с обучением дискриминатора на поддельных входах.
Потому что поддельная переменная теперь является частью графа генератора [1], но ты этого не хочешь. Поэтому вы должны "отделить" его от него, прежде чем поместить его в дискриминатор.