[GAN学习系列3]采用深度学习和 TensorFlow 实现图片修复(下)
這是本文的最后一部分內容了,前兩部分內容的文章:
以及原文的地址:
http://bamos.github.io/2016/08/09/deep-completion/
最后一部分的目錄如下:
- 第三步:為圖像修復尋找最佳的假圖片
- 利用 DCGANs 實現圖像修復
- [ML-Heavy] 損失函數
- [ML-Heavy] TensorFlow 實現 DCGANs 模型來實現圖像修復
- 修復你的圖片
第三步:為圖像修復尋找最佳的假圖片
利用 DCGANs 實現圖像修復
在第二步中,我們定義并訓練了判別器D(x)和生成器G(z),那接下來就是如何利用DCGAN網絡模型來完成圖片的修復工作了。
在這部分,作者會參考論文"Semantic Image Inpainting with Perceptual and Contextual Losses" 提出的方法。
對于部分圖片y,對于缺失的像素部分采用最大化D(y)這種看起來合理的做法并不成功,它會導致生成一些既不屬于真實數據分布,也屬于生成數據分布的像素值。如下圖所示,我們需要一種合理的將y映射到生成數據分布上。
[ML-Heavy] 損失函數
首先我們先定義幾個符號來用于圖像修復。用M表示一個二值的掩碼(Mask),即只有 0 或者是 1 的數值。其中 1 數值表示圖片中要保留的部分,而 0 表示圖片中需要修復的區域。定義好這個 Mask 后,接下來就是定義如何通過給定一個 Mask 來修復一張圖片y,具體的方法就是讓y和M的像素對應相乘,這種兩個矩陣對應像素的方法叫做哈大馬乘積,并且表示為 M ⊙ y ,它們的乘積結果會得到圖片中原始部分,如下圖所示:
接下來,假設我們從生成器G的生成結果找到一張圖片,如下圖公式所示,第二項表示的是DCGAN生成的修復部分:
根據上述公式,我們知道最重要的就是第二項生成部分,也就是需要實現很好修復圖片缺失區域的做法。為了實現這個目的,這就需要回顧在第一步提出的兩個重要的信息,上下文和感知信息。而這兩個信息的獲取主要是通過損失函數來實現。損失函數越小,表示生成的G(z)越適合待修復的區域。
Contextual Loss
為了保證輸入圖片相同的上下文信息,需要讓輸入圖片y(可以理解為標簽)中已知的像素和對應在G(z)中的像素盡可能相似,因此需要對產生不相似像素的G(z)做出懲罰。該損失函數如下所示,采用的是 L1 正則化方法:
這里還可以選擇采用 L2 正則化方法,但論文中通過實驗證明了 L1 正則化的效果更好。
理想的情況是y和G(z)的所有像素值都是相同的,也就是說它們是完全相同的圖片,這也就讓上述損失函數值為0
Perceptual Loss
為了讓修復后的圖片看起來非常逼真,我們需要讓判別器D具備正確分辨出真實圖片的能力。對應的損失函數如下所示:
因此,最終的損失函數如下所示:
這里 λ 是一個超參數,用于控制兩個函數的各自重要性。
另外,論文還采用泊松混合(poisson blending) 方法來平滑重構后的圖片。
[ML-Heavy] TensorFlow 實現 DCGANs 模型來實現圖像修復
代碼實現的項目地址如下:
https://github.com/bamos/dcgan-completion.tensorflow
首先需要新添加的變量是表示用于修復的 mask,如下所示,其大小和輸入圖片一樣
self.mask = tf.placeholder(tf.float32, [None] + self.image_shape, name='mask')對于最小化損失函數的方法是采用常用的梯度下降方法,而在 TensorFlow 中已經實現了自動微分的方法,因此只需要添加待實現的損失函數代碼即可。添加的代碼如下所示:
self.contextual_loss = tf.reduce_sum(tf.contrib.layers.flatten(tf.abs(tf.mul(self.mask, self.G) - tf.mul(self.mask, self.images))), 1) self.perceptual_loss = self.g_loss self.complete_loss = self.contextual_loss + self.lam*self.perceptual_loss self.grad_complete_loss = tf.gradients(self.complete_loss, self.z)接著,就是定義一個 mask。這里作者實現的是位置在圖片中心部分的 mask,可以根據需求來添加需要的任意隨機位置的 mask,實際上代碼中實現了多種 mask
if config.maskType == 'center':scale = 0.25assert(scale <= 0.5)mask = np.ones(self.image_shape)l = int(self.image_size*scale)u = int(self.image_size*(1.0-scale))mask[l:u, l:u, :] = 0.0因為采用梯度下降,所以采用一個 mini-batch 的帶有動量的映射梯度下降方法,將z映射到[-1,1]的范圍。代碼如下:
for idx in xrange(0, batch_idxs):batch_images = ...batch_mask = np.resize(mask, [self.batch_size] + self.image_shape)zhats = np.random.uniform(-1, 1, size=(self.batch_size, self.z_dim))v = 0for i in xrange(config.nIter):fd = {self.z: zhats,self.mask: batch_mask,self.images: batch_images,}run = [self.complete_loss, self.grad_complete_loss, self.G]loss, g, G_imgs = self.sess.run(run, feed_dict=fd)# 映射梯度下降方法v_prev = np.copy(v)v = config.momentum*v - config.lr*g[0]zhats += -config.momentum * v_prev + (1+config.momentum)*vzhats = np.clip(zhats, -1, 1)修復你的圖片
選擇需要進行修復的圖片,并放在文件夾dcgan-completion.tensorflow/your-test-data/raw下面,然后根據之前第二步的做法來對人臉圖片進行對齊操作,然后將操作后的圖片放到文件夾dcgan-completion.tensorflow/your-test-data/aligned。作者隨機從數據集LFW中挑選圖片進行測試,并且保證其DCGAN模型的訓練集沒有包含LFW中的人臉圖片。
接著可以運行下列命令來進行修復工作了:
./complete.py ./data/your-test-data/aligned/* --outDir outputImages上面的代碼會將修復圖片結果保存在--outDir參數設置的輸出文件夾下,接著可以采用ImageMagick工具來生成動圖。這里因為動圖太大,就只展示修復后的結果圖片:
而原始的輸入待修復圖片如下:
小結
最后,再給出前兩步的文章鏈接:
當然這個圖片修復方法由于也是2016年提出的方法了,所以效果不算特別好,這兩年其實已經新出了好多篇新的圖片修復方法的論文,比如:
2016CVPR Context encoders: Feature learning by inpainting
Deepfill 2018–Generative Image Inpainting with Contextual Attention
Deepfillv2–Free-Form Image Inpainting with Gated Convolution
2017CVPR–High-resolution image inpainting using multi-scale neural patch synthesis
2018年的 NIPrus收錄論文–Image Inpainting via Generative Multi-column Convolutional Neural Networks
歡迎關注我的微信公眾號–機器學習與計算機視覺,或者掃描下方的二維碼,在后臺留言,和我分享你的建議和看法,指正文章中可能存在的錯誤,大家一起交流,學習和進步!
我的個人博客:
http://ccc013.github.io/
往期精彩推薦
1.機器學習入門系列(1)–機器學習概覽(上)
2.機器學習入門系列(2)–機器學習概覽(下)
3.[GAN學習系列] 初識GAN
4.[GAN學習系列2] GAN的起源
5.[GAN學習系列3]采用深度學習和 TensorFlow 實現圖片修復(上)
6.[GAN學習系列3]采用深度學習和 TensorFlow 實現圖片修復(中)
總結
以上是生活随笔為你收集整理的[GAN学习系列3]采用深度学习和 TensorFlow 实现图片修复(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常用视频格式简述(RMVB\RM\WMV
- 下一篇: 实用软件工程(张海藩)课后答案