Matting(摳圖)--用深度學習自動去除照片背景

轉自:https://zhuanlan.zhihu.com/p/38031181算法

https://zhuanlan.zhihu.com/p/151212267瀏覽器

如今又有一個 AI 能幹 Photoshop 的活了——自動摳圖,一鍵去除照片背景。服務器

這款 AI 摳圖產品已經成型,叫作 GreenScreen。網絡

 

集智體驗了一下,效果還不錯。好比,咱們讓 AI 爲象徵自由的男人——香蕉君摳個圖吧。架構

熟悉的原圖:機器學習

 

 

而後咱們把香蕉君的照片拖到網站上,讓 AI 去除背景,說時遲那時快只聽嗖的一聲:ide

 

嗯效果還不錯工具

 

 

可能有人會說香蕉君這張照片背景是純黑色的,也太好摳了。行吧那咱們換個複雜點的,讓 AI 把滅霸君從這張經典比心心圖上摳下來:性能

 

 

一樣,咱們把照片拖入網站,讓 AI 去除背景,結果出來了:學習

 

 

除了旁邊物體沒有去完整外,總體效果仍是不錯的吧?

 

並且摳好的圖能夠右鍵保存爲 PNG 格式,隨時都能使用。

 

若是你想體驗一下,網站傳送門:

https://greenscreen-ai.boorgle.com/

 

那麼這款 AI 摳圖大師是怎麼煉成的?咱們來看看做者 Gidi Shperber 分享背後的故事。


過去幾年,我(做者Gidi Shperber ——譯者注)一直想完成一個真正的機器學習項目。

幾個月前學習了深度學習的課程後,我看到了實現這個夙願的機會:深度學習技術的迅速進步,能讓咱們完成不少之前沒法作到的事情。

 

本文就分享一下我是如何讓深度學習完成以往咱們用修圖軟件所作的工做——移除照片背景。

 

總的來講,若是使用一些工具好比 Photoshop、PowerPoint,移除照片背景不管是經過手工仍是半手工,仍是比較容易完成的工做。然而,據我所知,目前徹底自動實現照片背景移除,仍然是一項很是有難度的任務,雖然有很多這方面的嘗試,但尚無一款產品能在背景移除任務中取得使人滿意的效果。

 

咱們要移除什麼背景?這就變成了一個很重要的問題,由於一個深度學習模型越具體(好比對物體、角度有詳細的要求),圖像分割的質量就越高。在剛開始這項任務時,我從宏觀上下了個定義:一個通用的圖像背景移除 AI,應該能自動識別出任何類型照片的前景和背景。

不過在訓練完第一個模型後,我逐漸明白若是重點關注具體類型的照片,效果會更好。所以,我決定重點移除自拍照和人物肖像照片。

 

 

自拍照有一些比價顯著的特色:首先前景比較突出和集中(一個或多個「人物」),這樣能讓咱們很好的將物體(臉部+上半身)和背景分割,並且能保持穩定和連貫的角度;其次須要處理的物體始終一致(人物)。

 

腦中作了這些假設後,我就開始了理論研究、代碼實現以及數小時的訓練過程,建立可以一鍵輕鬆實現照片背景移除的自動化服務。

 

咱們工做的主要部分就是訓練模型,可是也不能低估部署模型的重要性。即使是表現良好的分割模型,也不如分類模型(好比 SqueezeNet)那樣緊湊,所以主動檢查了服務器部署和瀏覽器部署兩種選項。

 

語義分割

在面對深度學習和計算機視覺任務時,顯而易見,最適合解決圖像背景移除問題的技術就是語義分割。

 

固然也存在其它的一些方法,好比用深度檢測實現分割,但對於解決咱們這個問題來講,好像不太成熟。

 

語義分割,連同分類和物體檢測,是計算機視覺領域最有名的三大任務。分割實際上也是一種分類任務,也就是將全部像素進行歸類。不想圖像分類或圖像檢測,分割模型真的能讓咱們看到它「理解」了圖像,不只僅是說「這張圖像中有隻貓咪」,並且能在像素層面上指出貓咪在哪裏、是什麼貓咪。

 

那麼分割的工做原理是什麼?爲了能幫你們更好的理解這一點,咱們先來看看該領域早期的一些成果。

 

最先的想法是利用某些早期分類神經網絡,好比 VGG 和 AlexNet。在 2014 年時,VGG 是當時最早進的圖像分類模型,在今天仍然很是使用,由於其架構簡單直接。查看 VGG 靠前的層級時,你可能會注意到圍繞須要分類的數據項有不少較高的激活,更深一些的層有更強的激活,但因爲重複的池化操做這些激活的性質會變得粗糙。有了這點理解後,那麼就能夠假設分類訓練模型在略做調整後,也能用於發現或分割物體。

 

語義分割的早期結果每每伴隨着一些分類算法出現。下面是一些用 VGG 產生的較爲粗糙分割結果:

 

 

靠後層級的結果:

 

 

雙線性採樣以後的結果:

 

 

這些結果僅來自於將全鏈接層轉換爲原始形狀,但保留了空間特徵,獲得所有卷積的神經網絡。在上面的例子中,咱們往 VGG 中輸入一張 768*1024 的圖像,獲得一個 24*32*1000 的層。24*32 就是該圖像的池化版本(池化了 32),1000 就是 ImageNet 的類別數量,從中能夠導出分割結果。

 

爲了能讓預測更順暢些,研究人員使用了一種簡單的雙線性上採樣層。

 

在 FCN 論文中(https://arxiv.org/abs/1411.4038),研究人員優化了上面的理念。他們將一些層相連,從而獲取了更多的特徵解釋,而且依據上採樣率,將其命名爲FCN-32,FCN-16和FCN-8:

 

 

在層之間添加一些跳轉鏈接,能讓預測從初始圖像中編碼出更精細的細節。進一步訓練還能優化結果。

 

這項技術並不像以前想的那麼糟糕,並且證實了深度學習在語義分割任務上有很大的應用潛力。

 

 

FCN 解釋了分割的概念,研究人員也嘗試了幾種不一樣的架構用於語義分割。主要理念仍是同樣的:使用知名架構,上採樣,網絡層之間跳躍鏈接。這些技巧在現在的一些新的模型中仍然常見。

 

回到咱們的項目

在作了一些理論研究後,我確立了三種適用於此項任務的模型:FCN,Unet 和 Tiramisu,最後的 Tiramisu 模型採用了很是深的編碼器-解碼器架構。期間也考慮了 mask-RCNN,但實現它彷佛和咱們的任務內容相去甚遠。

 

FCN 看似並不相關,由於它的結果並不理想,但另外兩個模型的結果卻不錯:Unet 和 Tiramisu 不只結構緊湊,並且運行速度快。在模型實現方面,Unet 實現起來很是直接(我用的是 Keras),Tiramisu 也是易於實現。

 

接着用一些數據集開始訓練這兩種模型。我必須提一句,在首次嘗試 Tiramisu 後,發現其結果對我有更大的使用潛力,由於它能捕捉圖像中的鋒利邊緣。而 Unet 彷佛並不夠好,結果要遜於 Tiramisu。

 

 

數據

在使用什麼模型有了總體的方向後,接着就該蒐羅合適的數據集了。用於分割任務的數據並不像用於分類或檢測任務的數據那樣常見。此外,手動爲數據添加標籤也不現實。最多見的用於分割任務的數據集是 COCO 數據集(包含 90 個類別下的 8 萬張圖像)、VOC 數據集(包含 20 類別的 1 萬 1 千張圖像)和最新的 ADE20K 數據集。

 

咱們選擇 COCO 數據集(http://mscoco.org/),由於它裏面包含的人物圖像更多一些,更符合咱們的任務須要。

 

在考慮移除圖像背景的任務時,我比較好奇是使用和任務用途很是相關的圖像,仍是使用更通用的數據集。一方面,使用包含更多圖像和類的更爲通用的數據集,能讓模型處理更多的場景和挑戰。另外一方面,一個通宵咱們就能訓練超過15張圖像。若是咱們用整個COCO數據集訓練模型,最終模型會查看每張圖像兩次(平均來看),所以略微削減一點對咱們更好一點。另外,這樣也能生成更專一於咱們用途的模型。

 

另外一個值得提的事情是,最初用的 CamVid 數據集(http://mi.eng.cam.ac.uk/research/projects/VideoRec/CamVid/)訓練的Tiramisu模型。該數據集雖然有些缺陷,但重要的是,它的圖像比較一致:全部的圖像都是從汽車上拍攝的道路照片。所以很容易理解,從這樣的數據集中學習,對咱們的任務基本無用,所以短暫嘗試後,決定改用COCO數據集。

 

CamVid數據集中的圖像

 

COCO 數據集附有很是簡單明瞭的 API,能讓咱們確切地知道每張圖像中包含什麼物體。

 

通過一些試驗後,我決定精簡數據集:首先咱們過濾那些只有人物的圖像,這樣剩下了 4 萬張圖像。接着,丟棄全部包含不少人物的圖像,這樣剩下了只有 2 千張圖像,比較契合咱們產品的目標。最後,咱們只留下 20%-70% 的圖像區域被標記爲人物的照片,將背景中人物太小或存在奇怪物體的圖像。這樣通過處理後,最終的數據集包含了 1 萬 1 千張圖像,我認爲對於當前階段來講足夠了。

 

左圖:正常照片,中圖:太多人物,右圖:人物過小

 

Tiramisu 模型

 

如以前所說,咱們選用了 Tiramisu 模型。雖然它的全名「100 層 Tiramisu」暗示它是個巨大的模型,但實際上它很是簡練,只有 9 百萬個參數。做爲對比,VGG16 模型的參數多達130萬個。

 

Tiramisu 模型基於 DensNet 模型,它是個比較新穎的圖像分類模型,全部的層內部鏈接。並且,和 Unet 同樣,Tiramisu 模型爲上採樣層添加了跳躍鏈接。

 

若是仔細回想一下,這種架構比較符合 FCN 裏體現的理念:使用分類架構,上採樣,添加跳躍鏈接以獲取更精細的細節。

Tiramisu模型的總體架構

 

DenseNet 模型能夠看做 Resnet 模型的一個天然演變,但不是隻「記住」每一個層與相鄰層的鏈接,而是整個模型的全部層之間的鏈接。這些鏈接被稱爲「高速鏈接」。它會致使過濾器數量激增,這被稱爲「增加率」。Tiramisu 模型有16的增加率,所以咱們爲每一層添加 16 個新的過濾器,直到最終達到某一層有 1072 個過濾器。你可能以爲會有 1600 個層,畢竟被稱爲「100 層 Tiramisu」,但上採樣層會丟掉一些過濾器。

 

DenseNet模型架構示意圖

 

訓練

咱們按照初始論文所描述的方式訓練了模型:標準的交叉熵,學習率爲 1e-3 的 RMSProp 優化器,較小的衰減值。我將包含 1 萬 1 千張圖像的數據集進行了分拆,70% 用於訓練,20% 用於驗證,10% 用於測試。下方全部圖像都是取自咱們的測試集。

 

爲了能讓訓練計劃和初始論文一致,我將週期大小設置爲 500 張圖像。這樣也能讓咱們按期以不斷優化的結果保存模型,由於咱們以更多的數據訓練了模型。

 

此外,咱們只用兩個類訓練模型:背景和人物。咱們首先試着訓練 COCO 數據集中的一些類,不過很快就發現這對咱們訓練沒多少幫助。

 

數據問題

 

數據集的一些缺陷也損害的模型的性能:

 

  • 動物——咱們的模型有時會分割動物,這固然會形成很低的IOU。在咱們任務中往主要類別增長動物進去或者是其它東西會形成結果變差。
  • 身體部位——因爲咱們是用程序過濾數據集,就無法判斷人物類其實是人仍是某些人體部位,好比手和腳。這些圖像並不在咱們的目標範圍內,但仍是處處出現。

 

動物,人體部位,手持物體

 

  • 手持物體——數據集中的不少圖像都和運動相關,好比棒球帽、網球拍、滑雪板這些物件處處都有。對於怎麼分割這些物體,模型有點混亂。和上面出現動物的狀況同樣,將它們歸爲主要類或單獨的類,都有助於提升模型性能。

 

含運動設備的照片

 

  • 粗糙的真實數據——COCO數據集並不是按照逐個像素標記的,而是使用多邊形標註。有時會很好,但有時數據就比較粗糙,會妨礙模型學習。

 

很是粗糙的照片

 

結果

最終結果雖稱不上完美,但也算理想:測試集中的 IoU 爲 84.6%,而目前最好的結果爲 85%。獲得這個數據也是很是坎坷的,由於在不一樣的數據集和類中,它會不斷變更。有些類比較容易分割,好比房子、道路,在這些類中,大部分模型都能達到 90% 的 IoU;而在另外一些比較麻煩的類中,好比樹和人物,大部分模型只能達到 60% 的 IoU。爲了估量這方面的難度,咱們幫模型專一於單一類別,以及有限類型的圖像。

相關文章
相關標籤/搜索