【深度学习】计算机视觉(CV)-图像生成-风格迁移(Style Transfer)

风格迁移(Style Transfer)

风格迁移 是一种计算机视觉技术,可以将一张图像的内容 和另一张图像的风格融合在一起,生成一张既保留原始内容,又带有目标风格的全新图像!这种方法常用于艺术创作、图像增强、甚至视频处理。

最经典的风格迁移方法基于 卷积神经网络(CNN) ,由 Gatys 等人 在 2015 年提出,他们证明了 CNN 的不同层能够分别捕捉图像的内容特征风格特征

让我带你一步步了解!


1. 核心思想

风格迁移的目标是将:

  • 内容图像 C:保留其主要结构和对象信息
  • 风格图像 S:提取其纹理、色彩、笔触等艺术风格

生成一个混合图像 G,使其:

  • 内容接近 C
  • 风格接近 S

这个过程的核心是优化一个目标图像,使其最小化以下损失函数


2. 损失函数

(1) 内容损失

  • 使用 预训练的 VGG 网络,在特定层提取内容特征。
  • 目标:让生成图像的特征图接近内容图的特征图

内容损失通常使用均方误差(MSE):

  • :生成图像在第 l 层特征图的激活值
  • :内容图像在第 l 层特征图的激活值

(2) 风格损失

  • Gram 矩阵(特征图的自相关矩阵)表示风格特征。
  • Gram 矩阵编码了特征图通道之间的相关性,反映了纹理信息

风格损失也是 MSE,但基于 Gram 矩阵:

  • :生成图像第 l 层的 Gram 矩阵
  • :风格图像第 l 层的 Gram 矩阵
  • :特征图的通道数和空间维度
  • :不同层的风格损失权重

(3) 总损失

  • α:控制内容保留程度
  • β:控制风格强度

调整 α 和 β 的比值,可以在写实艺术感之间找到平衡!


3. 训练过程

  1. 初始化生成图像(通常是随机噪声或内容图像本身)。
  2. 前向传播:计算生成图像的内容和风格特征。
  3. 计算损失:根据内容图和风格图计算损失。
  4. 反向传播 :用 梯度下降优化生成图像,使损失逐步减小。
  5. 迭代更新生成图像,直到风格迁移成功!

4. 代码实现(PyTorch)

让我们用 PyTorch 快速实现一个简单的风格迁移!

python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.models as models
import torchvision.transforms as transforms
from PIL import Image

# 图像加载和预处理
def load_image(image_path, max_size=512):
    image = Image.open(image_path).convert('RGB')
    size = min(max_size, max(image.size))
    transform = transforms.Compose([
        transforms.Resize(size),
        transforms.ToTensor(),
        transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
    ])
    image = transform(image).unsqueeze(0)
    return image

# Gram 矩阵计算
def gram_matrix(tensor):
    _, c, h, w = tensor.size()
    features = tensor.view(c, h * w)
    gram = torch.mm(features, features.t())
    return gram / (c * h * w)

# 风格迁移模型
class StyleTransferModel(nn.Module):
    def __init__(self):
        super(StyleTransferModel, self).__init__()
        vgg = models.vgg19(pretrained=True).features.eval()
        self.content_layers = ['conv4_2']
        self.style_layers = ['conv1_1', 'conv2_1', 'conv3_1', 'conv4_1', 'conv5_1']
        self.model = nn.Sequential()

        i = 0
        for layer in vgg:
            if isinstance(layer, nn.Conv2d):
                i += 1
                name = f'conv{i}'
            elif isinstance(layer, nn.ReLU):
                name = f'relu{i}'
                layer = nn.ReLU(inplace=False)
            elif isinstance(layer, nn.MaxPool2d):
                name = f'pool{i}'
            elif isinstance(layer, nn.BatchNorm2d):
                name = f'bn{i}'
            self.model.add_module(name, layer)

            if name in self.content_layers or name in self.style_layers:
                pass

# 训练过程
def train(content_img, style_img, model, num_steps=500, alpha=1e5, beta=1e10):
    target = content_img.clone().requires_grad_(True)
    optimizer = optim.Adam([target], lr=0.003)

    for step in range(num_steps):
        target_features = model(target)
        content_features = model(content_img)
        style_features = model(style_img)

        content_loss = torch.mean((target_features['conv4_2'] - content_features['conv4_2']) ** 2)

        style_loss = 0
        for layer in model.style_layers:
            target_gram = gram_matrix(target_features[layer])
            style_gram = gram_matrix(style_features[layer])
            layer_loss = torch.mean((target_gram - style_gram) ** 2)
            style_loss += layer_loss

        loss = alpha * content_loss + beta * style_loss

        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if step % 50 == 0:
            print(f"Step {step}, Loss: {loss.item()}")

    return target

下面是一个简单的风格迁移实现,使用 VGG-19 作为特征提取器:

python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.transforms as transforms
import torchvision.models as models
from PIL import Image
import matplotlib.pyplot as plt

# 图像加载和预处理
def load_image(image_path, size=None):
    image = Image.open(image_path)
    if size:
        image = image.resize((size, size))
    transform = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
    ])
    return transform(image).unsqueeze(0)

# 加载内容和风格图像
content_img = load_image("content.jpg", size=512)
style_img = load_image("style.jpg", size=512)

# 使用预训练的 VGG19
vgg = models.vgg19(pretrained=True).features.eval()

# 内容和风格特征层
content_layers = ['conv4_2']
style_layers = ['conv1_1', 'conv2_1', 'conv3_1', 'conv4_1', 'conv5_1']

# Gram 矩阵计算
def gram_matrix(tensor):
    B, C, H, W = tensor.size()
    tensor = tensor.view(C, H * W)
    return torch.mm(tensor, tensor.t())

# 提取内容和风格特征
def get_features(image, model):
    features = {}
    x = image
    for name, layer in model._modules.items():
        x = layer(x)
        if 'conv' in name:
            features[f'conv{name}'] = x
    return features

# 计算损失
def calculate_loss(generated, content_features, style_features):
    gen_features = get_features(generated, vgg)
    content_loss = torch.mean((gen_features['conv4_2'] - content_features['conv4_2'])**2)

    style_loss = 0
    for layer in style_layers:
        gen_gram = gram_matrix(gen_features[layer])
        style_gram = gram_matrix(style_features[layer])
        style_loss += torch.mean((gen_gram - style_gram) ** 2)

    return content_loss * 1 + style_loss * 1e6

# 初始化生成图像
generated_img = content_img.clone().requires_grad_(True)

# 提取内容和风格特征
content_features = get_features(content_img, vgg)
style_features = get_features(style_img, vgg)

# 优化器
optimizer = optim.Adam([generated_img], lr=0.01)

# 训练风格迁移
for step in range(500):
    optimizer.zero_grad()
    loss = calculate_loss(generated_img, content_features, style_features)
    loss.backward()
    optimizer.step()
    if step % 50 == 0:
        print(f"Step [{step}/500] Loss: {loss.item():.4f}")

# 保存生成图像
generated_img = generated_img.detach().squeeze().clamp(0, 1).permute(1, 2, 0).numpy()
plt.imshow(generated_img)
plt.axis('off')
plt.show()

5. 应用场景

  • 艺术创作 :将普通照片转换成名画风格(如梵高、莫奈)。
  • 图像增强:增强图像的色彩和纹理,使其更具表现力。
  • AR/VR:实时风格迁移用于增强虚拟现实体验。
  • 视频处理:将整个视频帧逐帧风格迁移,打造动画片效果!

6. 进化版本

  • Fast Style Transfer :用 卷积自编码器替代优化过程,极大加快推理速度。
  • Neural Style Field (NSF):基于神经隐式场,实现更高分辨率、更稳定的风格迁移。
  • Stable Diffusion + Style Transfer:结合扩散模型生成更精细的风格图像。

7. 总结

风格迁移 是深度学习和艺术的完美结合!

通过内容损失 保持结构,风格损失 捕捉艺术特征,我们可以轻松生成独特的艺术作品。

无论是照片转油画、视频转动漫,还是增强现实体验,风格迁移都展现了AI 创意的无限可能

相关推荐
王牌狮AIen1 分钟前
AI营销智能体实战:OPC如何重构自主获客闭环?
大数据·人工智能·重构·数据挖掘·geo·ai营销
代码有点萌2 分钟前
ComfyUI 新手实战记录:一次跑通 AI 绘图工作流
人工智能
元启数宇3 分钟前
机电设计AI不只是消防:给排水、暖通、强弱电如何进入自动化?
运维·人工智能·自动化
我登哥MVP5 分钟前
VS Code 安装 Claude Code 并接入 DeepSeek V4 Model
人工智能·python·node.js·agent·codex·deepseek·claude code
unique6 分钟前
AI Native 调研报告
人工智能
云烟成雨TD6 分钟前
Spring AI Alibaba 1.x 系列【73】两步 RAG
java·人工智能·spring
ai产品老杨8 分钟前
解耦视频高并发与边缘计算AI布控:基于Docker的高性能安防平台,破局GB28181/RTSP协议兼容与源码交付痛点
人工智能·音视频·边缘计算
CHrisFC9 分钟前
LIMS 系统 AI 建设路径:从自动化到智能化的演进之路
运维·人工智能·自动化
饼干哥哥10 分钟前
一口气搭了300个AI Agents并发处理跨境运营的dirty work
人工智能
AI行业学习10 分钟前
CC‑Switch v3.16.1-下载、配置、安装(2026‑06‑01 最新官方版)
开发语言·人工智能·windows·python