GAN里面什么时候用detach的说明

在生成对抗网络(GAN)中,生成器(G)和判别器(D)通常是两个独立的神经网络,它们之间会有梯度传播的互动。下面是一个简单的GAN的PyTorch实现,用于生成一维数据,以展示何时应该使用detach()。

复制代码
import torch
import torch.nn as nn
import torch.optim as optim

# 生成器
class Generator(nn.Module):
    def __init__(self):
        super(Generator, self).__init__()
        self.model = nn.Sequential(
            nn.Linear(10, 50),
            nn.ReLU(),
            nn.Linear(50, 1)
        )
    
    def forward(self, x):
        return self.model(x)

# 判别器
class Discriminator(nn.Module):
    def __init__(self):
        super(Discriminator, self).__init__()
        self.model = nn.Sequential(
            nn.Linear(1, 50),
            nn.ReLU(),
            nn.Linear(50, 1),
            nn.Sigmoid()
        )
    
    def forward(self, x):
        return self.model(x)

# 实例化生成器和判别器
G = Generator()
D = Discriminator()

# 定义优化器和损失函数
optimizer_G = optim.Adam(G.parameters(), lr=0.001)
optimizer_D = optim.Adam(D.parameters(), lr=0.001)
loss_func = nn.BCELoss()

# 训练循环
for epoch in range(1000):
    # 训练判别器
    D.zero_grad()
    real_data = torch.randn(100, 1)  # 真实数据
    real_labels = torch.ones(100, 1) # 真实标签
    fake_data = G(torch.randn(100, 10)).detach() # 使用detach(), 因为我们不想在这一步更新生成器
    fake_labels = torch.zeros(100, 1) # 假的标签

    real_loss = loss_func(D(real_data), real_labels)
	# real_loss = loss_func(D(real_data.detach), real_labels)
    fake_loss = loss_func(D(fake_data), fake_labels)
    d_loss = real_loss + fake_loss
    d_loss.backward()
    optimizer_D.step()

    # 训练生成器
    G.zero_grad()
    noise_data = torch.randn(100, 10) # 噪声数据
    fake_data = G(noise_data) # 没有使用detach(), 因为我们想在这一步更新生成器
    g_loss = loss_func(D(fake_data), torch.ones(100, 1))
    g_loss.backward()
    optimizer_G.step()

在这个例子中:

  1. 当训练判别器(D)时,我们使用了detach()来中断梯度传播到生成器(G)。这是因为在这一步中,我们仅关心优化判别器,而不希望更新生成器的参数。
  2. 当训练生成器(G)时,我们没有使用detach(),因为我们需要通过反向传播的梯度来更新生成器的参数。

注意:在训练判别器时,不使用real_loss = loss_func(D(real_data.detach), real_labels), 也就是这里不需要对real_data进行detach操作。

而且即使对real_data进行.detach()操作实际上应该不会有明显影响,原因在于real_data并不是通过模型参数生成的,也不是一个需要优化的变量。.detach()方法主要用于将一个张量从当前计算图中分离出来,阻止反向传播过程中对其计算梯度。但在本例中,real_data本身就没有与需要优化的模型参数有直接关系,也不是由其他需要优化的变量通过一些运算得到的。

注意: 在训练判别器时,使用fake_data = G(torch.randn(100, 10)).detach(), 注意是因为这个fake_data是由生成器G生成的, 为了保证分开训练判别器和生成器,即在训练判别器的时候,不对生成器的参数进行更新,这里就要把G生成的数据进行detach操作

在训练生成器时, 也用到了判别器,用判别器去判别生成器生成的内容,希望判别器能把G生成的内容当做真的,这样就说明G的生成的内容可以以假乱真

复制代码
fake_data = G(noise_data) # 没有使用detach(), 因为我们想在这一步更新生成器
g_loss = loss_func(D(fake_data), torch.ones(100, 1))
g_loss.backward()
optimizer_G.step()

上面没有对传进D的fake_data进行detach,是因为下面的代码只有g_loss_backward(),也就是只对G进行参数更新,当然这里也不能对fake_data进行detach,如果detach了,就无法更新G的参数了

相关推荐
邵宇然1 分钟前
轻量级推理引擎开发:从模型加载到推理执行的 Rust 实战
人工智能
装不满的克莱因瓶2 分钟前
掌握语义分割经典模型 FCN——从像素分类到端到端分割的奠基之作
人工智能·python·深度学习·算法·机器学习·分类·数据挖掘
ACP广源盛139246256733 分钟前
GSV5600@ACP#多接口协议转换芯片,物理 AI 便携终端的互联核心
大数据·人工智能·分布式·嵌入式硬件·spark
لا معنى له3 分钟前
NeoVerse: Enhancing 4D World Model with in-the-wild Monocular Videos
人工智能·笔记·机器学习·语言模型
147API4 分钟前
Fable 5访问暂停后,模型接入层不能再只写死一个模型名
大数据·人工智能·api·claude
KaMeidebaby6 分钟前
卡梅德生物技术快报 | 噬菌体展示 12 肽文库在蛋白表位定位中的应用与实验数据
大数据·人工智能·架构·spark·新浪微博
JIAXIN_culture12 分钟前
甘肃景观工程定制服务FAQ:企业如何选对合作方?
大数据·人工智能
青绿蓝LCA低碳研究院13 分钟前
环保的本质:从“末端修补”到“系统重构”的生存范式转移 - 蓝色星球
大数据·人工智能·经验分享·重构
xwz小王子13 分钟前
ICRA 2026深度观察:全栈闭环成标配,中国具身智能势力显著崛起
大数据·人工智能·算法
逻辑探险家14 分钟前
2026 中国 GEO 服务商综合实力评测
大数据·人工智能·产品运营