【论文阅读】Universal Style Transfer via Feature Transforms

本文介绍了图像风格迁移中的白化和色彩变换技术,通过VGG网络提取特征并进行风格迁移。Whitening Transform移除风格特征,保留内容结构,而Coloring Transform结合内容特征与风格特征进行重建。使用WCT相比于直方图匹配能获得更好的效果,并可通过多层特征匹配实现更精细的风格转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关于图像白化和色彩变换的基本内容可以参考:

图像标准化、图像白化、色彩变换_S L N的博客-CSDN博客        

        这是一篇关于图像风格迁移的论文,主要提出了whitening and coloring transforms(WCTs)来进行风格的迁移。

        首先采用VGG网络对图像重建来训练网络,将训练好的VGG的encoder和decoder都fixed,用于图像特征提取和重建,损失函数如式(2.1)所示,Φ是通过encoder提取feature map。

 

 图4 图像重建

        Encoder和decoder训练好后,如图 5所示,将content image和style image通过encoder提取feature map,对feature map进行WCT进行特征迁移,WCT将content feature的统计特征和style feature的统计特征匹配,再将得到的feature map通过decoder重建。

 5 WCT

        Whitening transform的公式如式(2.2)所示,从图 6可以看出whitening保留了图像的全局内容结构,移除了图像本身的风格特征。

6 whitening transform

        Coloring transform的公式如式所示,从图 7中可以看出WCT的效果会比直方图匹配(HM)的效果好很多,这应该是WCT考虑了不同特征的相似度的原因,HM是在每个通道上做的。

7 WCT和HM对比

        通过式(2.4)中的α来控制风格化的程度,

        文中把single-level扩展到了multi-level,将前一层的输出作为后一层的content image输入,这样可以在不同的level进行统计特征匹配。 

图 8 multi-layer

        如图 9所示,lower level可以捕捉更低级的信息比如颜色,higher level可以捕捉到更复杂的局部结构。

在神经网络的训练过程中,通常需要进行以下五个步骤:准备数据、定义模型、定义损失函数、定义优化器、开始训练。下面是一份使用PyTorch实现style transfer的代码,其中与这五个步骤相对应的代码部分已经用注释标出。 ```python import torch import torch.nn as nn import torchvision.transforms as transforms import torchvision.models as models from PIL import Image # 准备数据 transform = transforms.Compose([ transforms.Resize(512), # 调整图像大小 transforms.ToTensor(), # 将图像转换为Tensor transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) # 标准化图像 ]) # 定义模型 class VGG(nn.Module): def __init__(self): super(VGG, self).__init__() self.features = models.vgg19(pretrained=True).features[:35] # 选择VGG19模型的前35层作为特征提取器 def forward(self, x): return self.features(x) # 定义损失函数 class StyleLoss(nn.Module): def __init__(self, target_feature): super(StyleLoss, self).__init__() self.target = self.gram_matrix(target_feature).detach() def forward(self, input): G = self.gram_matrix(input) self.loss = nn.functional.mse_loss(G, self.target) return input def gram_matrix(self, input): a, b, c, d = input.size() features = input.view(a * b, c * d) G = torch.mm(features, features.t()) return G.div(a * b * c * d) # 定义优化器 def get_input_optimizer(input_img): optimizer = torch.optim.Adam([input_img.requires_grad_()]) return optimizer # 开始训练 def run_style_transfer(content_img, style_img, num_steps=300, style_weight=1000000, content_weight=1): device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # 转换图像并将其放到设备上 content = transform(Image.open(content_img)).unsqueeze(0).to(device) style = transform(Image.open(style_img)).unsqueeze(0).to(device) input_img = content.clone().to(device).requires_grad_() # 定义模型和损失函数 model = VGG().to(device).eval() content_loss = nn.functional.mse_loss style_loss = StyleLoss(model(style).to(device)) # 定义优化器 optimizer = get_input_optimizer(input_img) # 迭代训练 for i in range(num_steps): input_img.data.clamp_(0, 1) optimizer.zero_grad() content_feature = model(content).detach() style_feature = model(input_img) content_loss = content_weight * content_loss(style_feature, content_feature) style_loss = 0 for ft, w in zip(style_feature, style_weight): style_loss += w * style_loss(ft, style_loss) loss = content_loss + style_loss loss.backward() optimizer.step() return input_img ``` 其中, - 准备数据:使用transforms定义了一组图像预处理方法,包括调整图像大小、将图像转换为Tensor、标准化图像。 - 定义模型:定义了一个VGG类,选择VGG19模型的前35层作为特征提取器。 - 定义损失函数:定义了一个StyleLoss类,用于计算风格损失。 - 定义优化器:定义了一个get_input_optimizer函数,用于获取一个Adam优化器。 - 开始训练:使用run_style_transfer函数开始训练,其中包括将图像转换到设备上、定义模型和损失函数、定义优化器、迭代训练过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值