DAST精简代码

先训练G:

先不计算D的梯度:                                           判别器输入类型为(源域,0)或者(目标域,1),输出图片为真实图片(源域)的概率值
for param in model_D.parameters():    # model_D = nn.ModuleList([FCDiscriminator...]) 判别器是一个全卷积网络,其实就是一个二分类,输出一个条件概率,即输入样本属于源域或者目标域的概率
param.requires_grad = False 判别损失 Ld 是一个二分类交叉熵损失,判断输入属于源域还是目标域
                                                      怎么才算训练好判别器:判别器能对真图打高分,对假图打低分
                                                       
输入图片:
images.size: torch.Size([1, 3, 512, 1024])
labels.size: torch.Size([1, 512, 1024])
源域图片S 的输出分割特征图:
feat_source: ([1, 2048, 65, 129])
pred_source: ([1, 19, 65, 129])
输出特征图接一个上采样后 pred_source 大小变成: ([1, 19, 512, 1024])
计算交叉熵损失:
loss_seg = seg_loss(pred_source, labels)
计算梯度值,并反传梯度值: (只是计算,不更新)
loss_seg.backward()

目标域图片T的大小、特征图大小 和上面的源域S一样,不同的是,经过分割网络时,得到一个加权的特征图(注:加权后的特征图大小不变)
和S一样,得到特征图后,接一个上采样:
pred_target = interp_target(pred_target)
先损失清零
loss_adv = 0
然后计算判别损失值,即对倒数第二层的T域特征图打分

D_out = model_D[0](feat_target) (判别器D[0]输入通道为2048,输出通道为1)
再用上面的判别损失值来计算对抗损失即用bce_loss(均方差MSELoss())来计算D_out和source_label的分布差
loss_adv += bce_loss(D_out, torch.FloatTensor(D_out.data.size()).fill_(source_label).to(device))
# source_label=0

先对最后一层的T域特征图打分:特征图先变成概率图(用softmax()),然后对概率图打分
D_out = model_D[1](F.softmax(pred_target, dim=1)) 判别器D[1]输入19,输出1)
然后计算对抗损失:
loss_adv += bce_loss(D_out, torch.FloatTensor(D_out.data.size()).fill_(source_label).to(device))

loss_adv = loss_adv * 0.01
计算梯度值,并将梯度反传
loss_adv.backward()
更新模型参数:
optimizer.step()
再训练D:


 
posted @ 2022-08-06 17:18  ethan178  Views(93)  Comments(0Edit  收藏  举报