天天看點

三步教你搭建給黑白照片上色的神經網絡 !(附代碼)

三步教你搭建給黑白照片上色的神經網絡 !(附代碼)

深度學習雲平台FloydHub最近在官方部落格上發了一篇通過搭建神經網絡,來給黑白照片上色的教程,在Twitter和Reddit論壇上都廣受好評。

FloydHub是個YC孵化的創業公司,号稱要做深度學習領域的Heroku。它在GPU系統上預裝了TensorFlow和很多其他的機器學習工具,使用者可以按時長租用,訓練自己的機器學習模型。免費版支援1個項目、每月20小時GPU時長、10G存儲空間,用上色項目練個手足夠了。

進入正題~

以下内容編譯自FloydHub官方部落格:

我将分三個步驟展示如何打造你自己的着色神經網絡。

第一部分介紹核心邏輯。我們将用40行代碼來建構一個簡單的神經網絡,叫做“Alpha”版本着色機器人。這個代碼裡沒有太多技巧,但是有助于熟悉文法。

下一步是建立一個具備泛化能力的神經網絡,叫做“Beta”版本,它能夠對以前沒見過的圖像進行着色。

最後,将神經網絡與分類器相結合,得到最終版本。Inception Resnet V2是訓練120萬張圖像後得到的神經網絡,我們使用了該模型。為了使着色效果更加吸引人,我們使用了來自素材網站Unsplash的人像集,來訓練這個神經網絡。

Alpha版本機器人的Jupyter Notebook代碼、上述三個版本實作代碼的FloydHub和GitHub位址,以及在FloydHub的GPU雲上運作的所有實驗代碼,都在文末。

核心邏輯

在本節中,我将概述如何渲染圖像、數字顔色的基礎知識以及神經網絡的主要邏輯。

黑白圖像可以在像素網格中表示。每個像素有對應于其亮度的值,取值範圍為0 - 255,從黑色到白色。

三步教你搭建給黑白照片上色的神經網絡 !(附代碼)

彩色圖像可以分為三層,分别是紅色層、綠色層和藍色層。直覺上,你可能會認為植物隻存在于綠色層,但事實可能與你的直覺相反。想象一下,将白色背景上的綠葉分成三個圖層。

如下圖所示,葉子在三個圖層中都存在。這些層不僅可以确定顔色,還确定了亮度。

三步教你搭建給黑白照片上色的神經網絡 !(附代碼)

例如,為了得到白色這個顔色,你需要将所有顔色均勻分布。添加等量紅色和藍色後,綠色會變得更亮。是以,彩色圖像使用三個通道來編碼顔色和對比度:

三步教你搭建給黑白照片上色的神經網絡 !(附代碼)

就像黑白圖像一樣,彩色圖像中每個圖層值的範圍也是0 – 255,值為0意味着該圖層中沒有顔色。如果在所有顔色圖層中該值都為0,則該圖像像素為黑色。

神經網絡能建立輸入和輸出之間的關系。更準确地說,着色任務就是讓網絡找到連接配接灰階圖像與彩色圖像的特征。

是以,着色神經網絡,就是要尋找将灰階值網格連接配接到三色網格的特征。

三步教你搭建給黑白照片上色的神經網絡 !(附代碼)

Alpha版本

我們從簡單版本開始,建立一個能給女性臉部着色的神經網絡。這樣,當添加新特征時,你可以熟悉已有模型的核心文法。

隻需要40行代碼,就能實作下圖所示的轉換。中間圖像是用神經網絡完成的,右邊圖像是原始的彩色照片。這個網絡使用了相同圖像做訓練和測試,在beta版本中還會再講這一點。

三步教你搭建給黑白照片上色的神經網絡 !(附代碼)

1、顔色空間

首先,使用一種能改變顔色通道的算法,從RGB到Lab。其中,L表示亮度,a和b分别表示顔色光譜,綠-紅和藍-黃。

如下所示,Lab編碼的圖像具有一個灰階層,并将三個顔色層壓成兩層,這意味着在最終預測中可以使用原始灰階圖像。此外,我們隻需預測兩個通道。

三步教你搭建給黑白照片上色的神經網絡 !(附代碼)

科學研究表明,人類眼睛中有94%細胞确定着亮度,隻有6%細胞是用來感受顔色的。如上圖所示,灰階圖像比彩色層更加清晰。這是我們在最終預測中保留灰階圖像的另一個原因。

2、從黑白到彩色

最終預測應該是這樣的:向網絡輸入灰階層(L),然後預測Lab中的兩個顔色層ab。要建立最終輸出的彩色圖像,我們需要把輸入的灰階(L)圖像和輸出的a、b層加在一起,建立一個Lab圖像。

三步教你搭建給黑白照片上色的神經網絡 !(附代碼)

我們使用卷積過濾器将一層變成兩層,可以把它們看作3D眼鏡中的藍色和紅色濾鏡。每個過濾器确定能從圖檔中看到的内容,可以突出或移除某些東西,來從圖檔中提取資訊。這個網絡可以從過濾器中建立新圖像,也可以組合多個過濾器形成新圖像。

卷積神經網絡能自動調整每個濾波器,以達到預期結果。我們将從堆疊數百個濾波器開始,然後将它們縮小成兩層,即a層和b層。

在詳細介紹其工作原理之前,先介紹代碼。

4、Alpha版本

安裝好FloydHub後,執行以下指令:

打開檔案夾并啟動FloydHub。

FloydHub Web控制台将在浏覽器中打開,系統會提示你建立一個名為colornet的FloydHub新項目。完成後,傳回終端并執行相同的初始化指令。

接下來執行本項目任務。

對于這個任務的一些簡單說明:

我們在FloydHub的資料集目錄(—data emilwallner / datasets / colornet / 2:data)中載入了一個公開資料集,你在FloydHub上檢視并使用此資料集和許多其他公開資料集;

啟用了Tensorboard (—tensorboard);

在Jupyter Notebook下運作代碼 (—mode jupyter);

如果能使用GPU,你還可以将GPU (—gpu)添加到指令中,這樣運作速度能提高50倍。

在FloydHub網站上的選項“Jobs”下,點選Jupyter Notebook可連結到以下檔案:floydhub / Alpha version / working_floyd_pink_light_full.ipynb,打開它并摁下shift+enter。

逐漸增大epoch值,體會神經網絡是如何學習的。

開始時把epoch設定為1,逐漸增加到10、100、5500、1000和3000。epoch值表示神經網絡從圖像中學習的次數。在訓練神經網絡的過程中,你可以在主檔案夾中找到這個圖像img_result.png。

用FloydHub指令來運作網絡:

5、技術說明

與其他視覺網絡不同,它的主要差別在于像素位置的重要性。在着色網絡中,圖像的分辨率或比例在整個網絡中保持不變。而在其他網絡中,越靠近最後一層,圖像變得越扭曲。

分類網絡中的最大池化層增加了資訊密度,但也可能導緻圖像失真。它隻對資訊進行估值,而未考慮到圖像布局。在着色網絡中,我們将步幅改為2,每次運算使寬度和高度減半。這樣,不但增加了資訊密度,也不會使圖像扭曲。

三步教你搭建給黑白照片上色的神經網絡 !(附代碼)

兩者差異在于上采樣層和圖像比例保持方面。而分類網絡隻關心最終的分類正确率,是以随着網絡深入,它會不斷減小圖像的分辨率和品質。

但是,着色網絡的圖像比例保持不變。這是通過添加空白填充來實作的,否則每個卷積層将削減圖像,實作代碼為:padding =’same’。

這個for循環首先計算了目錄中的所有檔案名,然後周遊圖像目錄,并将圖像轉換為像素數組,最後将其組合成一個大型矢量。

在ImageDataGenerator中,我們還修改了圖像生成器的參數。這樣,圖像永遠不會相同,以改善學習效果。參數shear_range是指圖像向左或向右的傾斜程度,其他參數不需要加以說明。

我們使用了檔案夾Xtrain中的圖像,根據之前設定來生成圖像。然後我們提取X_batch中的黑白層和兩個顔色層的兩種顔色。

擁有越高性能的GPU,則可以設定越大的batch_size值。根據現有硬體,我們設定了每批次輸入50-100張圖像。參數steps_per_epoch是通過把訓練圖像的數量除以批次大小得出的。例如,有100張圖像且批次大小為50,則steps_per_epoch值為2。參數epoch決定網絡中所有圖像的訓練次數。在Tesla K80 GPU上,大約需要11小時才能完成對1萬張圖像的21次訓練。

6、訓練心得

先進行多次小批次實驗,再嘗試大批次實驗。即使經過20-30次實驗,我仍然發現很多錯誤。程式能運作并不意味着它能工作。神經網絡中的問題通常比傳統程式設計遇到的Bug更為麻煩。

多樣化的資料集會使着色效果呈現棕色。如果資料集中圖像比較相似,不需要設計很複雜的架構,就可以得到一個良好效果,但是其泛化能力十分糟糕。

重視圖像形狀的統一性。每張圖像的分辨率必須是準确的,且在整個網絡中保持成比例。開始時,所使用的圖像分辨率為300,将它減半三次後分别得到150、75和35.5。是以,就丢失了半個像素,這導緻了很多問題,後來才意識到應該使用4、8、16、32、64、256等這種能被2整除的數。

建立資料集。請禁用.DS_Store檔案,不然會産生很多麻煩;大膽創新,最後我用Chrome控制台腳本和擴充程式來下載下傳檔案;備份原始檔案并建構清理腳本。

最終版本

三步教你搭建給黑白照片上色的神經網絡 !(附代碼)

這個網絡通過将分類器的學習效果遷移到着色網絡上,可更好了解圖檔中的内容。是以,這樣使得網絡能夠把目标表征與着色方案相比對。

以下是在一些驗證圖像上的着色效果,僅使用20張圖像來訓練網絡。

三步教你搭建給黑白照片上色的神經網絡 !(附代碼)
三步教你搭建給黑白照片上色的神經網絡 !(附代碼)

注意:在下面代碼中,我把Keras的序列模型變換成相應的函數調用。

用FloydHub指令來運作最終版本神經網絡:

技術說明

當你要實作模型連接配接或模型融合時,Keras的函數調用功能是最佳選擇。

三步教你搭建給黑白照片上色的神經網絡 !(附代碼)

首先,要下載下傳inception resnet v2網絡并加載權重。由于要并行使用兩個模型,是以必須指定目前要使用哪個模型。這個可通過Keras的後端Tensorflow來完成。

批處理方法中使用了調整後的圖像,把它們變成黑白圖像,并在inception resnet模型上運作。

首先,要調整圖像分辨率以适應inception模型;然後根據模型,使用預處理程式來規範化像素和顔色值;最後,在inception網絡上運作并提取模型最後一層的權重。

再講下生成器。對于每個批次,我們按照下列格式生成20張圖像,在Tesla K80 GPU上大約要運作一個小時。基于該模型,每批次最多可輸入50張圖像,且不産生記憶體溢出。

代碼23

這與本項目中着色模型的格式相比對。

fusion_output = RepeatVector(32 * 32)(embed_input)

fusion_output = Reshape(([32, 32, 1000]))(fusion_output)

fusion_output = concatenate([fusion_output, encoder_output], axis=3)

fusion_output = Conv2D(256, (1, 1), activation='relu')(fusion_output)

1.Alpha版本機器人的Jupyter Notebook代碼:

<a href="https://www.floydhub.com/emilwallner/projects/color/43/code/Alpha-version/alpha_version.ipynb">https://www.floydhub.com/emilwallner/projects/color/43/code/Alpha-version/alpha_version.ipynb</a>

2.三個版本實作代碼 - Floydhub傳送門:

<a href="https://www.floydhub.com/emilwallner/projects/color/43/code">https://www.floydhub.com/emilwallner/projects/color/43/code</a>

3.三個版本實作代碼 - Github傳送門:

<a href="https://github.com/emilwallner/Coloring-greyscale-images-in-Keras">https://github.com/emilwallner/Coloring-greyscale-images-in-Keras</a>

4.所有實驗代碼:

<a href="https://www.floydhub.com/emilwallner/projects/color/jobs">https://www.floydhub.com/emilwallner/projects/color/jobs</a>

5.作者Twitter:emilwallner

<a href="https://twitter.com/EmilWallner">https://twitter.com/EmilWallner</a>

6.教程原文:

<a href="https://blog.floydhub.com/colorizing-b&amp;w-photos-with-neural-networks/">https://blog.floydhub.com/colorizing-b&amp;w-photos-with-neural-networks/</a>

繼續閱讀