• 风格迁移常用代码


    损失

    nn.MSELoss均方损失函数

    LPIPS感知损失

    学习感知图像块相似度(Learned Perceptual Image Patch Similarity, LPIPS)也称为“感知损失”(perceptual loss),用于度量两张图像之间的差别,来源于论文《The Unreasonable Effectiveness of Deep Features as a Perceptual Metric》。

    论文地址:

    https://arxiv.org/pdf/1801.03924.pdf

    代码地址:

    pytorch:https://github.com/richzhang/PerceptualSimilarity

    计算相似度需逐层计算网络输出的对应channel的Cos Distance,然后对得到的distance进行平均(所有层,空间维度),LPIPS主要是把两个Cos Distance作为网络的输入,然后用Cross Entropy Loss训练网络学习2AFC。

    计算x与x0 之间的距离d0:给定不同的BaseNet F,首先计算深度嵌入,规格化通道维度中的激活,用向量w缩放每个通道,取L2距离,然后对空间维度和所有层次求平均。 

    l层提取特征堆并在通道维度中进行单元标准化。通过w_{l }缩放激活通道维并计算 L_{2 }距离

    ,在空间上取平均,在层上求和。

    1. # pytorch 求LPIPS
    2. import torch
    3. import lpips
    4. import os
    5. use_gpu = False # Whether to use GPU
    6. spatial = True # 返回感知距离的空间图
    7. # 线性校准模型 Linearly calibrated models (LPIPS)
    8. loss_fn = lpips.LPIPS(net='alex', spatial=spatial) # Can also set net = 'squeeze' or 'vgg'
    9. # loss_fn = lpips.LPIPS(net='alex', spatial=spatial, lpips=False) # Can also set net = 'squeeze' or 'vgg'
    10. if (use_gpu):
    11. loss_fn.cuda()
    12. # 使用伪张量的实例 Example usage with dummy tensors
    13. rood_path = r'D:\Project\results\faces'
    14. img0_path_list = []
    15. img1_path_list = []
    16. ## path in net is already exist
    17. '''
    18. for root, _, fnames in sorted(os.walk(rood_path, followlinks=True)):
    19. for fname in fnames:
    20. path = os.path.join(root, fname)
    21. if '_generated' in fname:
    22. im0_path_list.append(path)
    23. elif '_real' in fname:
    24. im1_path_list.append(path)
    25. '''
    26. dist_ = []
    27. for i in range(len(img0_path_list)):
    28. dummy_img0 = lpips.im2tensor(lpips.load_image(img0_path_list[i]))
    29. dummy_img1 = lpips.im2tensor(lpips.load_image(img1_path_list[i]))
    30. if (use_gpu):
    31. dummy_img0 = dummy_img0.cuda()
    32. dummy_img1 = dummy_img1.cuda()
    33. dist = loss_fn.forward(dummy_img0, dummy_img1)
    34. dist_.append(dist.mean().item())
    35. print('Avarage Distances: %.3f' % (sum(dist_) / len(img0_path_list)))

    GAN

    1. netG = StyleBankNet(len(dataset_list))
    2. netD = Discriminator()
    3. loss_network = LossNetwork()
    4. bce_loss = nn.BCELoss()
    5. use_gpu = torch.cuda.is_available()
    6. if use_gpu:
    7. netG = netG.cuda()
    8. netD = netD.cuda()
    9. loss_network = loss_network.cuda()
    10. LR = 1e-2
    11. optimizerG = Adam(netG.parameters(), LR)
    12. optimizerD = Adam(netD.parameters(), LR)
    13. scheduler = StepLR(optimizerG, step_size=30, gamma=0.2)
    14. netG.train()
    15. netD.train()
    16. print('networks done')
    17. # batch_id--批次索引 (style_id, content_image, stylized_image)--风格索引 内容图 风格图
    18. for batch_id, (style_id, content_image, stylized_image) in enumerate(dataloader):
    19. optimizerG.zero_grad()
    20. optimizerD.zero_grad()
    21. batch_size = len(style_id)
    22. count += batch_size # 总训练的图片数量
    23. epoch_count += batch_size # 本轮次训练的图片数量
    24. # 创建了一个名为label的张量(tensor),类型为torch.FloatTensor,它的大小与batch_size相同。
    25. # fill_()函数用指定的值填充整个张量。在这里,fill_(1)表示将label张量的所有元素都设置为1
    26. label = torch.FloatTensor(batch_size).fill_(1)
    27. # Variable函数的作用是将输入的张量(例如图像)封装成一个可以进行自动求导操作的变量
    28. content_image = Variable(content_image)
    29. stylized_image = Variable(stylized_image)
    30. if use_gpu:
    31. content_image = content_image.cuda()
    32. stylized_image = stylized_image.cuda()
    33. label = label.cuda()
    34. labelv = Variable(label)
    35. output_image = netG(content_image, style_id)
    36. output_features = loss_network(output_image)
    37. #############################################################
    38. # (1) 更新鉴别器网络: 最大化 log(D(x)) + log(1 - D(G(z)))
    39. # Update D network: maximize log(D(x)) + log(1 - D(G(z)))
    40. # the Discriminator training part is referenced from
    41. # https://github.com/pytorch/examples/blob/master/dcgan/main.py
    42. # at 2018/3/6
    43. #############################################################
    44. # train with real
    45. p_real = netD(stylized_image)
    46. # 使用二值交叉熵损失函数 bce_loss 比较输出 p_real 和标签 labelv,计算真实图像的判别器损失 errD_real
    47. # p_real 是一个预测值,表示模型对真实数据的预测结果。labelv 是真实标签,其中包含了对应于每个预测值的期望输出
    48. errD_real = bce_loss(p_real, labelv)
    49. errD_real.backward()
    50. D_x = D_x + p_real.data.mean()
    51. # train with fake
    52. labelv = Variable(label.fill_(0))
    53. p_fake = netD(output_image.detach())
    54. errD_fake = bce_loss(p_fake, labelv)
    55. errD_fake.backward()
    56. D_G_z1 = D_G_z1 + p_fake.data.mean()
    57. Loss_D = Loss_D + errD_fake.data.mean() + errD_real.data.mean()
    58. optimizerD.step()

    nn.BCELoss()

    `bce_loss(p_real, labelv)` 是二分类任务中的二元交叉熵损失函数。它的原理如下:

    首先,`p_real` 是一个预测值,表示模型对真实数据的预测结果。`labelv` 是真实标签,其中包含了对应于每个预测值的期望输出。

    二元交叉熵损失函数的计算公式如下:
    ```
    loss = -[labelv * log(p_real) + (1 - labelv) * log(1 - p_real)]
    ```

    其中 `log` 表示自然对数。这个损失函数通过比较预测值 `p_real` 和真实标签 `labelv` 之间的差异来度量模型的预测效果。

    当 `labelv` 为 1 时,损失函数的第一项起作用,即 `loss = -log(p_real)`。这时,我们希望模型能够将真实数据正确分类为正样本,即 `p_real` 趋近于 1。如果 `p_real` 越接近 0(即模型错误地将真实数据分类为负样本),那么损失函数的值就会越大,反之亦然。

    当 `labelv` 为 0 时,损失函数的第二项起作用,即 `loss = -log(1 - p_real)`。这时,我们希望模型能够将真实数据正确分类为负样本,即 `p_real` 趋近于 0。如果 `p_real` 越接近 1(即模型错误地将真实数据分类为正样本),那么损失函数的值就会越大,反之亦然。

    通过最小化二元交叉熵损失函数,我们可以使模型学习到正确分类样本的权重和偏差,从而提高模型的准确性和泛化能力。

  • 相关阅读:
    ORA-01558故障恢复----惜分飞
    mac录屏快捷键 - mac截图截屏快捷键 - 自带录屏软件QuickTime Player如何使用
    DAO:“动态仲裁”能否解决投票冷漠问题?
    CMake教程-第 9 步:打包安装程序
    经典快速制作套打证书模板(xls)大全
    简单3步轻松搭建个人博客
    Python xlwings打开excel表格进行最大化
    第七章 规范化:Eslint + Prettier + Husky
    springboot日志切面记录请求日志
    AI数字人:最强声音驱动面部表情模型VideoReTalking
  • 原文地址:https://blog.csdn.net/qq_44527508/article/details/134074075