【深度学习】用Pytorch给你的母校做一个样式迁移吧!
前言
先看下效果,我實在沒有拍過學校的照片,隨便谷歌了一張,學校是哈爾濱理工大學榮成校區。
Github代碼我已經開源在文末,環境我使用的是Colab pro,下載直接運行。(別忘了Star~)大家可以用好看的照片哦!
輸出圖像:
輸入圖像:
樣式遷移
如果你是一位攝影愛好者,你也許接觸過濾鏡。它能改變照片的顏色樣式,從而使風景照更加銳利或者令人像更加美白。但一個濾鏡通常只能改變照片的某個方面。如果要照片達到理想中的樣式,你可能需要嘗試大量不同的組合。這個過程的復雜程度不亞于模型調參。
這里我們需要兩張輸入圖像:一張是內容圖像,另一張是樣式圖像。
我們將使用神經網絡修改內容圖像,使其在樣式上接近樣式圖像。
例如,圖像為本書作者在西雅圖郊區的雷尼爾山國家公園拍攝的風景照,而樣式圖像則是一幅主題為秋天橡樹的油畫。
最終輸出的合成圖像應用了樣式圖像的油畫筆觸讓整體顏色更加鮮艷,同時保留了內容圖像中物體主體的形狀。
▌2.1 方法
簡單的例子闡述了基于卷積神經網絡的樣式遷移方法。
首先,我們初始化合成圖像,例如將其初始化為內容圖像。該合成圖像是樣式遷移過程中唯一需要更新的變量,即樣式遷移所需迭代的模型參數。然后,我們選擇一個預訓練的卷積神經網絡來抽取圖像的特征,其中的模型參數在訓練中無須更新。
這個深度卷積神經網絡憑借多個層逐級抽取圖像的特征,我們可以選擇其中某些層的輸出作為內容特征或樣式特征。
接下來,我們通過正向傳播(實線箭頭方向)計算樣式遷移的損失函數,并通過反向傳播(虛線箭頭方向)迭代模型參數,即不斷更新合成圖像。
樣式遷移常用的損失函數由3部分組成:
內容損失使合成圖像與內容圖像在內容特征上接近;
樣式損失使合成圖像與樣式圖像在樣式特征上接近;
總變差損失則有助于減少合成圖像中的噪點。
最后,當模型訓練結束時,我們輸出樣式遷移的模型參數,即得到最終的合成圖像。
這里選取的預訓練的神經網絡含有3個卷積層,其中第二層輸出內容特征,第一層和第三層輸出樣式特征。
和無監督學習不是一個道理哈。
這句話很重要哦。
▌2.2 數據處理和網絡實現
第一步,統一圖像尺寸。
下面,定義圖像的預處理函數和后處理函數。預處理函數preprocess對輸入圖像在RGB三個通道分別做標準化,并將結果變換成卷積神經網絡接受的輸入格式。后處理函數postprocess則將輸出圖像中的像素值還原回標準化之前的值。由于圖像打印函數要求每個像素的浮點數值在0到1之間,我們對小于0和大于1的值分別取0和1。
rgb_mean = torch.tensor([0.485, 0.456, 0.406]) rgb_std = torch.tensor([0.229, 0.224, 0.225])def preprocess(img, image_shape):transforms = torchvision.transforms.Compose([torchvision.transforms.Resize(image_shape),torchvision.transforms.ToTensor(),torchvision.transforms.Normalize(mean=rgb_mean, std=rgb_std)])return transforms(img).unsqueeze(0)def postprocess(img):img = img[0].to(rgb_std.dnet = nn.Sequential(*[pretrained_net.features[i] for i inrange(max(content_layers + style_layers) + 1)])evice)img = torch.clamp(img.permute(1, 2, 0) * rgb_std + rgb_mean, 0, 1)return torchvision.transforms.ToPILImage()(img.permute(2, 0, 1))基于ImageNet數據集預訓練的VGG-19模型來抽取圖像特征
pretrained_net = torchvision.models.vgg19(pretrained=True)使用VGG層抽取特征時,我們只需要用到從輸入層到最靠近輸出層的內容層或樣式層之間的所有層。下面構建一個新的網絡net,它只保留需要用到的VGG的所有層。
net = nn.Sequential(*[pretrained_net.features[i] for i inrange(max(content_layers + style_layers) + 1)])下面定義兩個函數:get_contents函數對內容圖像抽取內容特征;get_styles函數對樣式圖像抽取樣式特征。因為在訓練時無須改變預訓練的VGG的模型參數,所以我們可以在訓練開始之前就提取出內容特征和樣式特征。由于合成圖像是樣式遷移所需迭代的模型參數,我們只能在訓練過程中通過調用extract_features函數來抽取合成圖像的內容特征和樣式特征。
def get_contents(image_shape, device):content_X = preprocess(content_img, image_shape).to(device)contents_Y, _ = extract_features(content_X, content_layers, style_layers)return content_X, contents_Ydef get_styles(image_shape, device):style_X = preprocess(style_img, image_shape).to(device)_, styles_Y = extract_features(style_X, content_layers, style_layers)return style_X, styles_Y▌2.3 訓練
在訓練模型進行樣式遷移時,我們不斷抽取合成圖像的內容特征和樣式特征,然后計算損失函數。下面定義了訓練循環。
現在我們訓練模型:首先將內容圖像和樣式圖像的高和寬分別調整為300和450像素,用內容圖像來初始化合成圖像。
device, image_shape = d2l.try_gpu(), (300, 450) net = net.to(device) content_X, contents_Y = get_contents(image_shape, device) _, styles_Y = get_styles(image_shape, device) output = train(content_X, contents_Y, styles_Y, device, 0.3, 500, 50)device, image_shape = d2l.try_gpu(), (300, 450)net = net.to(device)content_X, contents_Y = get_contents(image_shape, device)_, styles_Y = get_styles(image_shape, device)output = train(content_X, contents_Y, styles_Y, device, 0.3, 500, 50)
樣式遷移常用的損失函數由3部分組成:(i) 內容損失使合成圖像與內容圖像在內容特征上接近;(ii) 樣式損失令合成圖像與樣式圖像在樣式特征上接近;(iii) 總變差損失則有助于減少合成圖像中的噪點。
我們可以通過預訓練的卷積神經網絡來抽取圖像的特征,并通過最小化損失函數來不斷更新合成圖像來作為模型參數。
我們使用格拉姆矩陣表達樣式層輸出的樣式。
開源代碼
代碼地址:https://github.com/lixiang007666/Style-Transfer-pytorch
運行style-pytorch.ipynb:
訓練300個epoch結果:
epoch ?10, content loss 25.22, style loss 3014.07, TV loss 1.16, 0.01 sec epoch ?20, content loss 29.34, style loss 740.11, TV loss 1.31, 0.00 sec epoch ?30, content loss 30.87, style loss 383.17, TV loss 1.36, 0.00 sec epoch ?40, content loss 31.51, style loss 250.63, TV loss 1.40, 0.01 sec epoch ?50, content loss 31.39, style loss 190.49, TV loss 1.45, 0.01 sec epoch ?60, content loss 30.82, style loss 152.23, TV loss 1.46, 0.01 sec epoch ?70, content loss 29.83, style loss 124.40, TV loss 1.49, 0.01 sec epoch ?80, content loss 29.00, style loss 108.24, TV loss 1.50, 0.01 sec epoch ?90, content loss 28.27, style loss 92.64, TV loss 1.52, 0.01 sec epoch 100, content loss 27.65, style loss 82.47, TV loss 1.53, 0.00 sec epoch 110, content loss 27.15, style loss 73.10, TV loss 1.54, 0.01 sec epoch 120, content loss 26.44, style loss 65.02, TV loss 1.56, 0.01 sec epoch 130, content loss 25.90, style loss 58.60, TV loss 1.57, 0.01 sec epoch 140, content loss 25.44, style loss 53.61, TV loss 1.58, 0.01 sec epoch 150, content loss 24.98, style loss 49.11, TV loss 1.59, 0.00 sec epoch 160, content loss 24.60, style loss 45.28, TV loss 1.60, 0.01 sec epoch 170, content loss 24.11, style loss 42.02, TV loss 1.61, 0.01 sec epoch 180, content loss 23.78, style loss 39.58, TV loss 1.61, 0.01 sec epoch 190, content loss 23.41, style loss 37.26, TV loss 1.62, 0.01 sec epoch 200, content loss 23.05, style loss 35.32, TV loss 1.62, 0.00 sec epoch 210, content loss 22.81, style loss 33.80, TV loss 1.62, 0.00 sec epoch 220, content loss 22.49, style loss 32.43, TV loss 1.62, 0.00 sec epoch 230, content loss 22.19, style loss 31.25, TV loss 1.62, 0.01 sec epoch 240, content loss 21.94, style loss 29.98, TV loss 1.62, 0.00 sec epoch 250, content loss 21.65, style loss 28.75, TV loss 1.62, 0.00 sec epoch 260, content loss 21.44, style loss 27.63, TV loss 1.62, 0.01 sec epoch 270, content loss 21.19, style loss 26.77, TV loss 1.62, 0.01 sec epoch 280, content loss 20.97, style loss 25.81, TV loss 1.62, 0.01 sec epoch 290, content loss 20.81, style loss 24.97, TV loss 1.62, 0.01 sec epoch 300, content loss 20.57, style loss 24.25, TV loss 1.62, 0.01 sec參考
[1].https://zh-v2.d2l.ai/index.html
注:本文僅代表作者個人觀點。如有不同看法,歡迎留言反饋/討論。
???????作者:李響Superb,CSDN百萬訪問量博主,普普通通男大學生,深度學習算法、醫學圖像處理專攻,偶爾也搞全棧開發,沒事就寫文章。
博客地址:lixiang.blog.csdn.net
???????—End—
往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習筆記專輯《統計學習方法》的代碼復現專輯 AI基礎下載機器學習的數學基礎專輯黃海廣老師《機器學習課程》視頻課 本站qq群851320808,加入微信群請掃碼:總結
以上是生活随笔為你收集整理的【深度学习】用Pytorch给你的母校做一个样式迁移吧!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GitHub标星14k:超详细的人工智能
- 下一篇: 基于智慧教室|无纸化会议的新选择:RTM