文章目錄
- 一、風格遷移模型🎨
- 1、發展時間線
- 2、分類與優缺點
- 3、選擇建議
- 4、HuggingFace Demo(instruct-pix2pix) —— 在線測試
- 二、論文簡讀
- (1)FastStyleTransfer(快速風格遷移,Johnson et al., 2016)
- 1、原理概述
- 2、特點與優勢
- 3、 局限性
- (2)AdaIN(自適應實例規范化,Huang & Belongie, 2017)
- 1、原理概述
- 2、特點與優勢
- 3、局限性
- (3)CycleGAN:基于循環一致性的無配對圖像風格遷移方法(Zhu et al., 2017)
- 1、原理概述
- 2、特點與優勢
- 3、局限性
- 4、適用與非適用場景
- 5、實戰建議
- 三、CycleGAN:項目實戰
- 1、環境配置
- 2、使用CPU模式而非GPU(默認強制使用,有GPU跳過該步驟)
- 3、文件配置
- (1)數據集下載
- (2)模型下載
- 4、代碼測試(Test a CycleGAN model)
- 備注1:CycleGAN 本質上無法保證 " 主體不變、僅變風格 "
- 備注2:白 / 黑背景將使得模型失去遷移方向
一、風格遷移模型🎨
1、發展時間線
年份 | 模型/方法 | 發布者/會議 | 技術關鍵詞 | 關鍵貢獻或備注 |
---|---|---|---|---|
2015 | NeuralStyleTransfer | Gatys等(CVPR) | Gram矩陣、VGG特征、優化迭代 | 開創性風格遷移方法,掀起研究熱潮 |
2016 | FastStyleTransfer | Johnson等(ECCV) | 感知損失、快速前向網絡 | 實現實時風格遷移,提升實用性 |
2017 | AdaIN | Huang等(NeurIPS) | 自適應實例歸一化 | 任意風格遷移新范式,靈活性強 |
2017 | WCT | Li等(CVPR) | 白化與著色變換(WCT) | 無需訓練,基于特征統計 |
2017 | Pix2Pix | Isola等(CVPR) | 條件GAN、成對圖像翻譯 | 開創成對圖像翻譯標準方法 |
2017 | CycleGAN | Zhu等(ICCV) | 循環一致性、無監督圖像翻譯 | 打破成對限制,支持任意風格遷移 |
2018 | MUNIT | Huang等(ECCV) | 多模態風格遷移、潛變量解耦 | 實現多風格切換 |
2019 | UGATIT | Kim等(ICLR) | 注意力機制、可控無監督遷移 | 強化結構保持,適用于面部、插畫等 |
2020 | CUT | Park等(ECCV) | 對比學習、PatchNCE損失 | 改進CycleGAN,提升圖像結構保持能力 |
2022 | StableDiffusion | CompVis等 | 文圖擴散模型、文本控制 | 圖文創作與藝術風格遷移 |
2023 | DALL·E2 | OpenAI | CLIP引導圖文生成、多模態優化 | 多樣化風格圖生成利器,適合設計類應用 |
MUNIT:多模態無監督圖像到圖像翻譯 —— https://github.com/nvlabs/MUNIT
2、分類與優缺點
類別 | 代表模型 | 特點描述 | 優點 | 局限性 |
---|---|---|---|---|
統計特征匹配類 | NeuralStyleTransfer、AdaIN、WCT | 特征層統計參數(均值/方差)匹配 | 快速、無需訓練、可實時應用 | 風格粒度不可控,結構保持差 |
成對監督類 | Pix2Pix | 條件GAN訓練,有明確輸入輸出成對 | 精確控制、結構保持好 | 需成對樣本,任務限制大 |
無監督圖像翻譯類 | CycleGAN、DualGAN、CUT | 循環一致性、對比學習等實現非配對遷移 | 無需配對,適用于多風格切換 | 訓練穩定性差,細節模糊,存在模式崩潰風險 |
結構保持增強類 | UGATIT、MUNIT、DRIT | 引入注意力或語義模塊,增強結構和可控性 | 支持局部顯著風格、結構更完整 | 推理慢,訓練復雜,對參數敏感 |
跨模態生成類 | StableDiffusion、DALL·E、ControlNet | 文本控制圖像風格,生成類大模型 | 控制力強、創意表達能力強 | 結構不可控、不適用于精確圖像風格遷移 |
3、選擇建議
使用需求 | 推薦模型 | 是否需訓練 | 推理速度 | 結構保持 | 風格質量 | 適用建議 |
---|---|---|---|---|---|---|
快速預覽風格效果 | AdaIN、WCT | 否 | ★★★★★ | ★★ | ★★★★ | 適合濾鏡類APP、快速嘗試多種風格 |
批量生成某一固定風格 | FastStyleTransfer | 是 | ★★★★ | ★★★★ | ★★★★ | 一次訓練后多圖高效渲染 |
精確圖?圖風格轉換 | Pix2Pix | 是 | ★★★ | ★★★★★ | ★★★★ | 數據成對充分時優選 |
任意圖像風格遷移 | CycleGAN、CUT | 是 | ★★★ | ★★★★ | ★★★★ | 適合插畫?實拍等風格轉換 |
多風格自由切換 | MUNIT、DRIT、StyleGAN | 是 | ★★ | ★★★★ | ★★★★ | 風格交互應用場景,如頭像生成、社交內容等 |
文本描述控制圖像風格 | StableDiffusion、DALL·E | 否 | ★★ | ★★ | ★★★★★ | 創意類內容創作,如封面設計、藝術生成等 |
4、HuggingFace Demo(instruct-pix2pix) —— 在線測試
https://huggingface.co/spaces/timbrooks/instruct-pix2pix
- 輸入:任意照片 + 文字指令(如 “Turn it into a cyberpunk style”)
- 特點:無需風格圖,直接通過文本描述控制風格。
- 超參數:
- Text CFG:7.5(默認)
- Image CFG:1.5(默認)
- 備注:權重越大,越傾向于哪一方!
- 輸入圖像的一般要求
- 格式:常見的圖片格式(如 .jpg, .png, .webp)。
- 分辨率:建議 512x512 ~ 1024x1024 像素(太高可能被自動壓縮)。
- 內容清晰:避免過度模糊、噪點或強壓縮偽影。
- 主體明確:風格遷移對主體(如人像、建筑、風景)效果更好。
二、論文簡讀
(1)FastStyleTransfer(快速風格遷移,Johnson et al., 2016)
快速神經風格:將一張圖片的內容與另一張圖片的風格進行混合
- https://github.com/pytorch/examples/tree/main/fast_neural_style
- https://github.com/jcjohnson/fast-neural-style
1、原理概述
FastStyleTransfer 是一種利用感知損失(Perceptual Loss)實現的快速圖像風格遷移方法。其基本結構為一個前饋神經網絡,在訓練階段學習將任意圖像轉換為特定風格的圖像。訓練完成后,該網絡在推理階段可實現毫秒級圖像風格轉換。
網絡結構
- 輸入:內容圖像(如渲染圖);
- 輸出:風格化圖像;
- 損失函數基于 VGG 特征提取器:
- 內容損失:保持原始圖像的語義結構;
- 風格損失:匹配目標風格圖的Gram矩陣特征;
- 總變差損失(TV loss):增強圖像平滑性。
2、特點與優勢
優勢點 | 說明 |
---|---|
? 推理速度快 | 一次前向傳播即可完成風格遷移,0.05~0.2秒/張,適合實時應用。 |
? 不改變圖像結構 | 網絡學習內容保留與風格分離,結果結構清晰。 |
? 工程部署簡單 | 可導出為TorchScript或ONNX,部署于邊緣設備或網頁端。 |
3、 局限性
局限點 | 描述 |
---|---|
? 每種風格需單獨訓練一個模型 | 若需支持多種風格,需為每種風格圖單獨訓練一次,增加存儲與訓練成本。 |
? 風格靈活性較低 | 風格結果相對固定,無法在推理階段動態調整風格程度或更換風格圖像。 |
(2)AdaIN(自適應實例規范化,Huang & Belongie, 2017)
AdaIN:通過自適應實例規范化,實現實時任意風格轉換
- https://github.com/naoto0804/pytorch-AdaIN
- https://github.com/xunhuang1995/AdaIN-style
1、原理概述
AdaIN 是一種任意風格圖像遷移方法,通過在推理階段動態注入風格圖像特征統計信息,實現任意風格的實時轉換。核心思想是:將內容圖像的特征歸一化后,重新賦予目標風格圖的均值與方差,從而在不改變內容結構的前提下完成風格映射。
關鍵模塊:Adaptive Instance Normalization
設內容特征為 fc,風格特征為 fs,則:
AdaIN ( f c , f s ) = σ ( f s ) ? ( f c ? μ ( f c ) σ ( f c ) ) + μ ( f s ) \text{AdaIN}(f_c, f_s) = \sigma(f_s) \cdot \left( \frac{f_c - \mu(f_c)}{\sigma(f_c)} \right) + \mu(f_s) AdaIN(fc?,fs?)=σ(fs?)?(σ(fc?)fc??μ(fc?)?)+μ(fs?)
其中:
μ:均值
σ:標準差
2、特點與優勢
局限點 | 描述 |
---|---|
? 風格僅體現顏色與紋理分布 | 不適合高度結構化或抽象風格(如某些插畫或2.5D卡通),表現不如GAN類方法。 |
? 對抗性質量不及GAN | 相比CycleGAN等對抗訓練方法,輸出真實感稍弱,細節較平滑。 |
3、局限性
局限點 | 描述 |
---|---|
? 風格僅體現顏色與紋理分布 | 不適合高度結構化或抽象風格(如某些插畫或2.5D卡通),表現不如GAN類方法。 |
? 對抗性質量不及GAN | 相比CycleGAN等對抗訓練方法,輸出真實感稍弱,細節較平滑。 |
(3)CycleGAN:基于循環一致性的無配對圖像風格遷移方法(Zhu et al., 2017)
- 論文地址:https://junyanz.github.io/CycleGAN/
- 開源地址:https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix
1、原理概述
CycleGAN是一種用于圖像到圖像轉換(Image-to-Image Translation)任務的生成對抗網絡(GAN)框架,具有無需成對訓練樣本,學習兩個域之間的映射關系,實現跨領域圖像轉換。其核心思想是通過循環一致性損失(Cycle Consistency Loss) 約束風格遷移的可逆性,從而在保留圖像結構的同時實現風格映射。
基本架構:CycleGAN包括兩個生成器(GA→B 和 GB→A)與兩個判別器(DA 和 DB)
其中:
- GA→B:將A域圖像(如照片)轉換為B域圖像(如油畫);例如:照片 → 油畫、夏天 → 冬天、馬 → 斑馬
- GB→A:實現B→A的反向轉換;例如:照片 → 油畫、夏天 → 冬天、馬 → 斑馬(反著)
- DA 與 DB:分別判別生成圖像是否屬于對應域的真實樣本。
循環一致性損失(Cycle Loss):
- A → B → A ≈ A
- B → A → B ≈ B
這種結構使得即使兩個領域之間沒有一一對應的圖像對,模型也能學到結構穩定的風格映射。
2、特點與優勢
優勢點 | 說明 |
---|---|
? 無需配對訓練樣本 | 相較于Pix2Pix等方法,CycleGAN僅依賴兩個領域的非配對圖像,降低了數據準備難度。 |
? 結構保持能力強 | 通過循環損失保持圖像內容結構不變,適合結構穩定但風格差異大的任務(如風景?油畫)。 |
? 具備雙向映射能力 | 同時學習A→B和B→A轉換路徑,提升模型魯棒性與泛化能力。 |
? 可生成較高質量圖像 | 相比簡單風格遷移模型,CycleGAN在圖像真實感、邊緣保留等方面表現更優。 |
3、局限性
局限點 | 描述 |
---|---|
? 需大量非配對數據 | 雖不要求成對圖像,但仍需大量覆蓋多樣風格的兩域圖像(例如上千張A域圖像+上千張B域圖像)才能訓練有效模型。 |
? 單圖像訓練效果差 | 如果僅提供一張風格圖像,模型難以提取穩定風格特征,易過擬合或風格失真。 |
? 推理依賴訓練域 | 測試時輸入圖像必須來自訓練時分布相近的領域,否則模型輸出不可控、泛化能力弱。 |
? 訓練耗時且資源密集 | 通常需數小時至數天GPU訓練時間,不適合快速測試或小樣本部署。 |
4、適用與非適用場景
? 適用場景
- 領域之間存在明顯風格差異,但結構內容一致(如:實拍照片?渲染圖、風景?油畫)。
- 具備大規模非配對訓練數據,可以覆蓋目標領域的主要特征分布。
- 需要高質量風格映射效果,用于研究、藝術生成等精度要求較高任務。
? 非適用場景
- 僅有1~5張風格參考圖像,無法支撐有效訓練。
- 風格域差異較抽象或領域跨度過大(如素描?動漫、照片?2.5D手繪)時,CycleGAN輸出容易失控。
- 對訓練時長、部署資源有限制,如實時應用、比賽時間緊張等場合。
5、實戰建議
在如 “ 渲染圖?2.5D插畫風格 ” 的圖像風格互換場景中,若僅有少量參考圖或時間限制較大,建議優先采用無需訓練的通用風格遷移方法(如AdaIN或FastStyleTransfer)。而CycleGAN更適用于訓練資源充足、可離線生成高質量雙向風格映射的情況。
三、CycleGAN:項目實戰
1、環境配置
conda create -n CycleGAN38 python=3.8 -y
conda activate CycleGAN38
pip install requirements.txt
2、使用CPU模式而非GPU(默認強制使用,有GPU跳過該步驟)
(模型強制使用GPU)如果你沒有 GPU 或者 CUDA 配置不正確,可以修改代碼以強制使用 CPU:
(1)在 base_options.py 文件中
torch.cuda.set_device(opt.gpu_ids[0])
######################################################
(1)將其修改為:
######################################################
# 如果沒有 GPU,可直接強制使用 CPU
if torch.cuda.is_available() and len(opt.gpu_ids) > 0:torch.cuda.set_device(opt.gpu_ids[0])
else:device = torch.device("cpu") # 強制使用 CPUprint("No GPU detected, using CPU instead.")# state_dict = torch.load(load_path, map_location=str(self.device))
######################################################
(2)將其修改為:
######################################################
if self.device.type == 'cpu':state_dict = torch.load(load_path, map_location=lambda storage, loc: storage)
else:state_dict = torch.load(load_path, map_location=self.device)
(2)在 base_options.py 文件中
self.device = torch.device('cuda:{}'.format(self.gpu_ids[0])) if self.gpu_ids else torch.device('cpu') # get device name: CPU or GPU
######################################################
將其修改為:
######################################################
# self.device = torch.device('cuda:{}'.format(self.gpu_ids[0])) if self.gpu_ids and self.gpu_ids[0] != -1 else torch.device('cpu')
if self.gpu_ids and self.gpu_ids[0] != -1 and torch.cuda.is_available(): # 增加了 torch.cuda.is_available() 的檢查self.device = torch.device('cuda:{}'.format(self.gpu_ids[0]))
else: # 如果沒有指定有效 GPU 或 CUDA 不可用,則強制使用 CPUself.device = torch.device('cpu')
(3)在 networks.py 文件中
def init_net(net, init_type='normal', init_gain=0.02, gpu_ids=[]):# if len(gpu_ids) > 0:# assert(torch.cuda.is_available())# net.to(gpu_ids[0])# net = torch.nn.DataParallel(net, gpu_ids) # multi-GPUs# init_weights(net, init_type, init_gain=init_gain)# return net######################################################將其修改為:####################################################### Determine the deviceif len(gpu_ids) > 0 and gpu_ids[0] != -1 and torch.cuda.is_available(): # 修改了這里的條件判斷device = torch.device('cuda:{}'.format(gpu_ids[0]))net.to(device)if len(gpu_ids) > 1: # Only use DataParallel if multiple GPUs are specifiednet = torch.nn.DataParallel(net, gpu_ids) # multi-GPUselse: # 增加了 else 分支來處理 CPU 情況device = torch.device('cpu')net.to(device)init_weights(net, init_type, init_gain=init_gain)return net
3、文件配置
地址:Index of /cyclegan
github中提供的下載教程:
bash是linux命令;
(1)在windows系統中,使用記事本打開文件pytorch-CycleGAN-and-pix2pix/datasets/download_pix2pix_dataset.sh;
(2)定位URL,打開http://efrosgans.eecs.berkeley.edu/cyclegan/datasets/;
(3)下載數據集ae_photos.zip,并解壓到pytorch-CycleGAN-and-pix2pix/datasets文件夾下;
(1)數據集下載
cyclegan地址:http://efrosgans.eecs.berkeley.edu/cyclegan/datasets/
(2)模型下載
cyclegan地址:http://efrosgans.eecs.berkeley.edu/cyclegan/pretrained_models/
4、代碼測試(Test a CycleGAN model)
以下是兩條test.py命令的參數逐項詳細解析(詳細請看test.py說明),用于在復現CycleGAN模型時正確理解和自定義測試流程:
? 命令1:雙向測試 CycleGAN(A→B和B→A)
python test.py --dataroot ./datasets/maps --name maps_cyclegan --model cycle_gan參數 含義--dataroot ./datasets/maps 指定數據集根目錄,CycleGAN會自動尋找testA/和testB/兩個子目錄,分別代表兩個方向的測試數據--name maps_cyclegan 模型名稱,對應于checkpoints/maps_cyclegan路徑下保存的訓練模型參數(G_A、G_B等)--model cycle_gan 指定模型類型為cycle_gan,表示使用CycleGAN的生成器G_A(A→B)和G_B(B→A)做雙向翻譯測試? 命令2:僅單向測試(如horse→zebra)
python test.py --dataroot datasets/horse2zebra/testA --name horse2zebra_pretrained --model test --no_dropout參數 含義--dataroot datasets/horse2zebra/testA 測試集只提供testA/(源域圖像),不需要testB/,只做單向A→B映射--name horse2zebra_pretrained 指定模型名為horse2zebra_pretrained,將從checkpoints/horse2zebra_pretrained中加載訓練好的G_A模型--model test 指定測試模式為單向測試,默認只使用G_A(源域→目標域),不會進行Cycle Consistency或B→A映射--no_dropout 禁用Dropout(測試階段通常不使用Dropout,結果更加穩定)📁 輸出文件默認保存路徑:./results/horse2zebra_pretrained/test_latest/images/
備注1:CycleGAN 本質上無法保證 " 主體不變、僅變風格 "
CycleGAN 所使用的是無監督圖像到圖像轉換框架,其本質是:在不使用成對圖像監督的前提下,學習兩個域之間的整體映射關系,而不是單獨控制前景或背景。
備注2:白 / 黑背景將使得模型失去遷移方向
原因如下:
- CycleGAN不具備語義理解能力
它依靠像素分布的統計特征進行映射;
全白/黑背景的統計特征過于簡單,模型難以提取有用信息;
如果背景占圖像面積過大,模型會將背景視作主體的一部分。- 背景過于“干凈”,擾亂遷移邏輯
模型的遷移邏輯通常依賴局部紋理;
純背景導致輸入特征“太干凈”,而輸出風格域中的背景往往存在紋理或漸變,模型會“強行添加內容”;- 目標結構稀疏,易丟失原圖語義
CycleGAN 的生成器為全卷積結構,弱語義感知;
當前景小、背景大時,模型會偏向“遷移背景”,導致主題模糊。
對于CycleGAN:
- 白/黑背景不是“無內容”,而是“全是背景內容”;
- 如果風格圖中的背景有豐富紋理或顏色變化,模型會認為“純白純黑背景是待轉換的區域”;
- 最終結果:模型在嘗試改變背景的過程中,犧牲了前景穩定性,遷移效果不佳。