Style Transfer-PyTorch

Content Loss

content loss用来计算原图片和生成的图片之间像素的差距,这里用的是卷积层获取的 feature map 之间的差距

通过卷积层,有多少个卷积核就会生成多少个 feature_map(也就是一个卷积核的输出结果)

公式为:Lc=wc×∑i,j(Fijℓ−Pijℓ)2L_c = w_c \times \sum_{i,j} (F_{ij}^{\ell} - P_{ij}^{\ell})^2Lc​=wc​×∑i,j​(Fijℓ​−Pijℓ​)2

  • wcw_cwc​ 是当前层两张照片之间的差距的权重
  • FlF^lFl 是当前图片的 feature_map
  • PlP^lPl 是内容来源图片的 feature_map

def content_loss(content_weight, content_current, content_original):"""Compute the content loss for style transfer.Inputs:- content_weight: Scalar giving the weighting for the content loss.- content_current: features of the current image; this is a PyTorch Tensor of shape(1, C_l, H_l, W_l).- content_target: features of the content image, Tensor with shape (1, C_l, H_l, W_l).Returns:- scalar content loss"""# *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****N,C,H,W = content_current.shapeFc = content_current.view(C,H*W) # view 相当于 reshapePc = content_original.view(C,H*W)Lc = content_weight * (Fc - Pc).pow(2).sum()return Lc# *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****

Style Loss

这里我们使用格拉姆矩阵(Gram matrix G)来表示feature map每个通道(channel)之间的联系(也就是风格)。

  • Gram matrix G :Gijℓ=∑kFikℓFjkℓG_{ij}^\ell = \sum_k F^{\ell}_{ik} F^{\ell}_{jk}Gijℓ​=∑k​Fikℓ​Fjkℓ​

    • FlF^lFl 是当前图片的 feature_map

  • Gram matrix 的核心就是以上两个矩阵进行矩阵乘法

    def gram_matrix(features, normalize=True):"""Compute the Gram matrix from features.Inputs:- features: PyTorch Tensor of shape (N, C, H, W) giving features fora batch of N images.- normalize: optional, whether to normalize the Gram matrixIf True, divide the Gram matrix by the number of neurons (H * W * C)Returns:- gram: PyTorch Tensor of shape (N, C, C) giving the(optionally normalized) Gram matrices for the N input images."""# *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****N,C,H,W = features.shapeF = features.view(N , C , H * W) # N * C * MF_t = F.permute(0 , 2 , 1)  # N * M * C    permute的作用是交换维度gram = torch.matmul(F , F_t) # N * C * Cif normalize:gram = gram / (C * H * W)return gram# *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****
    
  • 第 l 层的 Loss:Lsℓ=wℓ∑i,j(Gijℓ−Aijℓ)2L_s^\ell = w_\ell \sum_{i, j} \left(G^\ell_{ij} - A^\ell_{ij}\right)^2Lsℓ​=wℓ​∑i,j​(Gijℓ​−Aijℓ​)2

    • AlA^lAl 是特征来源图片的 Gram matrix
    • 和 GlG^lGl 的计算方法相同 , 只是换了输入
  • Loss function:Ls=∑ℓ∈LLsℓL_s = \sum_{\ell \in \mathcal{L}} L_s^\ellLs​=∑ℓ∈L​Lsℓ​

    • 所有层的 loss 相加
  • torch.matmul

    • torch.matmul 是tensor的乘法,输入可以是高维的。(超过两维的时候前面的都当做 batch , 最后两维进行矩阵乘法)
    • 当输入是都是二维时,就是普通的矩阵乘法,和 tensor.mm 函数用法相同
a = torch.ones(3 , 4)
b = torch.ones(4 , 2)
c = torch.matmul(a , b)
c.shape
>> torch.Szie([3 , 2])
a = torch.ones(5 , 3 , 4)
b = torch.ones(4 , 2)
c = torch.matmul(a , b)
c.shape
>> torch.Size([5 , 3 , 2])
a = torch.ones(2 , 5 , 3)
b = torch.ones(1 , 3 , 4)
c = torch.matmul(a , b)
c.shape
>> torch.Size([2 , 5 , 4])
  • 计算 Style Loss

    # Now put it together in the style_loss function...
    def style_loss(feats, style_layers, style_targets, style_weights):"""Computes the style loss at a set of layers.Inputs:- feats: list of the features at every layer of the current image, as produced bythe extract_features function.- style_layers: List of layer indices into feats giving the layers to include in thestyle loss.- style_targets: List of the same length as style_layers, where style_targets[i] isa PyTorch Tensor giving the Gram matrix of the source style image computed atlayer style_layers[i].- style_weights: List of the same length as style_layers, where style_weights[i]is a scalar giving the weight for the style loss at layer style_layers[i].Returns:- style_loss: A PyTorch Tensor holding a scalar giving the style loss."""# Hint: you can do this with one for loop over the style layers, and should# not be very much code (~5 lines). You will need to use your gram_matrix function.# *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****style_current = []#style_loss = torch.zeros([1],dtype=float)style_loss = 0for i,idx in enumerate(style_layers):style_current.append(gram_matrix(feats[idx].clone()))style_loss += (style_current[i] - style_targets[i]).pow(2).sum() * style_weights[i]return style_loss# *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****

Total-variation regularization

total variation loss可以使图像变得平滑 ,变得更加平滑被证明是有帮助的

具有过多和可能是虚假细节的信号具有高的总变化,即,信号的绝对梯度的积分是高的。根据该原理,减小信号的总变化,使其与原始信号紧密匹配,去除不需要的细节,同时保留诸如边缘的重要细节

  • Total Variation(TV)的方程是这样的:RVβ(f)=∫Ω((∂f∂u(u,v))2+(∂f∂v(u,v))2)β2dudv\mathcal{R}_{V^{\beta}}(f)=\int_{\Omega}\left(\left(\frac{\partial f}{\partial u}(u, v)\right)^{2}+\left(\frac{\partial f}{\partial v}(u, v)\right)^{2}\right)^{\frac{\beta}{2}} d u d vRVβ​(f)=∫Ω​((∂u∂f​(u,v))2+(∂v∂f​(u,v))2)2β​dudv
  • 在图像中,连续域的积分就变成了像素离散域中求和,所以可以这么算:RVβ(x)=∑i,j((xi,j+1−xij)2+(xi+1,j−xij)2)β2\mathcal{R}_{V^{\beta}}(\mathbf{x})=\sum_{i, j}\left(\left(x_{i, j+1}-x_{i j}\right)^{2}+\left(x_{i+1, j}-x_{i j}\right)^{2}\right)^{\frac{\beta}{2}}RVβ​(x)=∑i,j​((xi,j+1​−xij​)2+(xi+1,j​−xij​)2)2β​
  • 也就是说,求每一个像素和横向下一个像素的差的平方,加上纵向下一个像素的差的平方。然后开β/2次根

在本次实验中,我们的 Total Variation(TV) 公式为:

​ Ltv=wt×(∑c=13∑i=1H−1∑j=1W(xi+1,j,c−xi,j,c)2+∑c=13∑i=1H∑j=1W−1(xi,j+1,c−xi,j,c)2)L_{tv} = w_t \times \left(\sum_{c=1}^3\sum_{i=1}^{H-1}\sum_{j=1}^{W} (x_{i+1,j,c} - x_{i,j,c})^2 + \sum_{c=1}^3\sum_{i=1}^{H}\sum_{j=1}^{W - 1} (x_{i,j+1,c} - x_{i,j,c})^2\right)Ltv​=wt​×(∑c=13​∑i=1H−1​∑j=1W​(xi+1,j,c​−xi,j,c​)2+∑c=13​∑i=1H​∑j=1W−1​(xi,j+1,c​−xi,j,c​)2)

  • 可以看出,和上面的式子一样,只是计算了三通道像素,并且乘以权重 wtw_twt​
def tv_loss(img, tv_weight):"""Compute total variation loss.Inputs:- img: PyTorch Variable of shape (1, 3, H, W) holding an input image.- tv_weight: Scalar giving the weight w_t to use for the TV loss.Returns:- loss: PyTorch Variable holding a scalar giving the total variation lossfor img weighted by tv_weight."""# Your implementation should be vectorized and not require any loops!# *****START OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****N,C,H,W = img.shapex1 = img[: , : , 0:H-1 , :]x2 = img[: , : , 1:H , :] # x1的所有元素的后一个的组合y1 = img[: , : , : , 0:W-1]y2 = img[: , : , : , 1:W] # y1的所有元素的后一个的组合loss = ((x2-x1).pow(2).sum() + (y2-y1).pow(2).sum()) * tv_weightreturn loss# *****END OF YOUR CODE (DO NOT DELETE/MODIFY THIS LINE)*****

Generate some pretty pictures

  • Example 1

  • Example 2

  • Example 3

结论分析与体会

本次实验主要学习了利用 PyTorch 进行风格迁移训练(将一张图片的内容与另一张图片的风格相结合)

  • 计算 content loss

    • 将当前图片的 features map 与 content 原图片的 features map进行比较
    • 每一层的 loss 公式为:Lc=wc×∑i,j(Fijℓ−Pijℓ)2L_c = w_c \times \sum_{i,j} (F_{ij}^{\ell} - P_{ij}^{\ell})^2Lc​=wc​×∑i,j​(Fijℓ​−Pijℓ​)2
  • 计算 style loss
    • 计算当前图片的 features map 对应的 Gram matrix

      • Gram matrix G :Gijℓ=∑kFikℓFjkℓG_{ij}^\ell = \sum_k F^{\ell}_{ik} F^{\ell}_{jk}Gijℓ​=∑k​Fikℓ​Fjkℓ​
    • 计算 style 原图片的 features map 对应的 Gram matrix
      • Gram matrix A :Aijℓ=∑kPikℓPjkℓA_{ij}^\ell = \sum_k P^{\ell}_{ik} P^{\ell}_{jk}Aijℓ​=∑k​Pikℓ​Pjkℓ​
    • 利用当前图片的 Gram matrix 和 style 原图片的 Gram matrix 计算 loss
      • 第 l 层的 Loss:Lsℓ=wℓ∑i,j(Gijℓ−Aijℓ)2L_s^\ell = w_\ell \sum_{i, j} \left(G^\ell_{ij} - A^\ell_{ij}\right)^2Lsℓ​=wℓ​∑i,j​(Gijℓ​−Aijℓ​)2
      • Loss function:Ls=∑ℓ∈LLsℓL_s = \sum_{\ell \in \mathcal{L}} L_s^\ellLs​=∑ℓ∈L​Lsℓ​
  • 计算 Total-variation loss
    • ​ Ltv=wt×(∑c=13∑i=1H−1∑j=1W(xi+1,j,c−xi,j,c)2+∑c=13∑i=1H∑j=1W−1(xi,j+1,c−xi,j,c)2)L_{tv} = w_t \times \left(\sum_{c=1}^3\sum_{i=1}^{H-1}\sum_{j=1}^{W} (x_{i+1,j,c} - x_{i,j,c})^2 + \sum_{c=1}^3\sum_{i=1}^{H}\sum_{j=1}^{W - 1} (x_{i,j+1,c} - x_{i,j,c})^2\right)Ltv​=wt​×(∑c=13​∑i=1H−1​∑j=1W​(xi+1,j,c​−xi,j,c​)2+∑c=13​∑i=1H​∑j=1W−1​(xi,j+1,c​−xi,j,c​)2)
  • 总的 Loss
    • loss=contentLoss+styleLoss+tvLossloss = contentLoss + styleLoss + tvLossloss=contentLoss+styleLoss+tvLoss
  • 使用梯度下降的方法缩小 loss 对模型进行优化

Style Transfer(PyTorch)相关推荐

  1. 谈谈图像的style transfer(二)

    总说 主要从几个方面来进行说明吧  - 加快transfer的速度  - 让transfer的效果看起来更加visual-pleasing  - 其他的一些方面  - 用GAN来做 加快style s ...

  2. 深度学习(三十五)——Style Transfer(2), YOLOv3, Tiny-YOLO, One-stage vs. Two-stage

    Style Transfer Texture Networks: Feed-forward Synthesis of Textures and Stylized Images 这篇论文属于fast s ...

  3. 谈谈图像的Style Transfer(一)

    总说 最近更新:17-5-9 增加Neural style使用Gram矩阵的前提工作 其实这个方向火起来是从2015年Gatys发表的一篇文章 A Neural Algorithm of Artist ...

  4. Deep Learning Art: Neural Style Transfer(吴恩达课程)

    Deep Learning & Art: Neural Style Transfer(吴恩达课程) # UNQ_C1 # GRADED FUNCTION: compute_content_co ...

  5. 深度学习准「研究僧」预习资料:图灵奖得主Yann LeCun《深度学习(Pytorch)》春季课程...

    视学算法报道 编辑:蛋酱 转载自公众号:机器之心 开学进入倒计时,深度学习方向的准「研究僧」们,你们准备好了吗? 转眼 2020 年已经过半,又一届深度学习方向的准研究生即将踏上「炼丹」之路.对于这一 ...

  6. 基于yolo4和yolo3(pytorch)的口罩识别的对比

    这是yolov4的(pytorch)目录结构 这个是基于keras yolo3的 目前测试来看pytorch的快 keras速度慢 这两个项目的地址 这里有模型直接就可以使用,感兴趣可以体验一下 py ...

  7. 【深度学习】Dropout、正反向传播、计算图等的介绍和实现(Pytorch)

    [深度学习]Dropout.正反向传播.计算图等的介绍和实现(Pytorch) 文章目录 1 Dropout概述 2 实践中的dropout2.1 从零开始实现2.2 定义模型参数2.3 定义模型2. ...

  8. 图解一维卷积层(PyTorch)

    图解一维卷积层(PyTorch) 在NLP中,我们需要对文本做embedding表示,那么embedding之后的文本做一维卷积运算的过程到底是什么样子的呢?我们给出下图加以说明

  9. 动手学习深度学习——2.7 文档(Pytorch)

    2.7 文档(Pytorch)   由于本书篇幅的限制,我们不可能介绍每一个单独的[PyTorch]函数和类.API文档,其他教程和示例提供了许多本书之外的文档.在本节中,我们将为您提供一些探索[Py ...

最新文章

  1. Python基础入门:分支及循环
  2. 免费当天澳洲运营商全天下载量达1841TB
  3. 使用代码将指定的product加入新建的transaction
  4. python self 值自动改变,在python中对self的理解
  5. 友善串口工具接收数据随机换行_使用Python3+PyQT5+Pyserial 实现简单的串口工具方法...
  6. Scala类型系统的目的——Martin Odersky访谈(三)
  7. 60K!刚面完Python!这个被Oracle裁掉的程序员求职刷爆全网!
  8. 消息称华为计划推出自有品牌电动汽车 官方重申不造车
  9. 双11小米手机、AIoT销售成绩公布,雷军笑了
  10. 倍福服务器维修,Beckhoff TwinCAT
  11. iOS开发:几种静态扫描工具的使用与对比
  12. SMB协议端口号,Windows文件共享协议
  13. Yolov2 训练时anchor是如何使用的?build_target
  14. Tensorflow学习笔记-第二节程序结构
  15. java renderer_Java TableCellRenderer显示奇怪的行为
  16. 直播源列表转换php,电视直播源列表制作、转换工具Telelist(可以DPL、M3U、TXT等互转)...
  17. 大学生网页制作之美食篇html+css静态网页设计
  18. LaTex - 插入公式 (从MathType公式编辑器导入到LaTex中)
  19. 万字深度好文!VL最强总结!
  20. 学计算机的什么是镜像,一、什么是windows镜像?什么是Ghost?它们有什么优缺点?...

热门文章

  1. 社交营销还是要走到线下
  2. bpnn——matlab工具箱-归一化函数 premnmx、tramnmx、postmnmx、mapminmax
  3. 3D医学图像CT dcm格式转换为png
  4. IM在线客服系统_开源在线客服系统附源码
  5. MyCat教程【分库分表】
  6. kafka源码分析之producer
  7. v06.03 鸿蒙内核源码分析(调度队列) | 内核调度也需要排队 | 百篇博客分析HarmonyOS源码
  8. JS实现简单农场小游戏
  9. Conflux 树图区块链 “数字藏品 合约标准和编写规范
  10. org.apache.tomcat.util.descriptor.web.WebXml.setVersion Unknown version stri