自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

詳解如何用深度學習消除背景,實現摳圖

人工智能 深度學習 開發(fā)
在機器學習方興未艾的過去幾年里,我一直想要親自開發(fā)具有實用價值且基于機器學習的產品。然后幾個月前,在我學習了由 Fast.AI 所提供的深度學習課程之后,我意識到機會來了。當前的機遇是:深度學習的技術優(yōu)勢使得許多之前不能完成的事情變得可能,并且還有許多新興工具被開發(fā)出來,這使得深度學習的部署過程變得更加簡單。

在上述課程中,我遇到了 Alon Burg——一名經驗豐富的 web 開發(fā)人員,我們剛好趣味相投。所以為了實現這么一款產品,我們?yōu)樽约涸O定了一些目標:

  1. 提高自身的深度學習技巧

  2. 提高自身的 AI 產品部署技巧

  3. 針對市場需求,開發(fā)具有實用價值的產品

  4. 產品要有趣

  5. 要分享我們的經驗

綜合考慮以上的目標,我們進行了頭腦風暴:

  1. 哪些東西是沒被做過的(或者說還不夠完善)

  2. 產品的設計以及實現難度不能太大——因為我們的計劃是花上 2-3 個月的時間,每周只在這上邊花個 1 天時間

  3. 用戶接口要足夠簡單,容易上手——因為我們希望用戶能夠輕松學會如何使用這個產品,畢竟該產品開發(fā)的初衷不是為了科學驗證

  4. 用于訓練深度學習模型的數據要容易獲取——因為有機器學習經驗的人基本都知道,有時數據比算法來的更加重要

  5. 將采用***的深度學習技巧(這種技巧還未被 Google、Amazon 等公司投入商業(yè)化應用),但是也不能太過于新穎(以便于我們可以在網上找到參考例子)

  6. 產品將具備有生產的潛力

我們最早的想法是從醫(yī)療項目入手,因為醫(yī)療領域與我們的初衷很接近,并且那時認為(現在依然認為)深度學習在醫(yī)療領域還存在著大量機會。但是,我們意識到這將違背有關于數據收集那一條,數據要容易獲取的原則。因此我們退而求其次,選擇了做背景消除(Background removal)。

背景消除這項任務如果由人類純手工來做,或者借助諸如 Photoshop、Power Point 等工具來實現都是非常簡單的。然而,全自動化的背景消除卻是一項充滿挑戰(zhàn)的任務。并且根據我們的了解,目前還沒有一款產品能夠在背景消除任務中實現非常好的效果,不過有些廠商已經進行了嘗試。

那么問題來了,我們需要消除什么樣的背景?這是一個很重要的問題。因為一個模型越是具體(比如說對物體、角度等方面有詳細規(guī)定),它***的分割效果也越好。在我們剛開始時,我們將這個范圍定義得比較廣:一個通用的背景消除器將能夠從任何類型的圖片中自動識別出前景與背景。但是在我們訓練出了***個模型之后,我們意識到如果將精力集中于一組特定的圖像上,將取得更好的效果。因此,我們決定專注于肖像以及自拍類型的照片。

背景消除樣例

自拍的圖像具有突出和集中的前景(一個或者多個 “人”),這樣使得背景和物體(臉部和上半身)間能實現較好的分割,并且能保持一個相對穩(wěn)定的角度。

在做了這些基本假設之后,我們開始了理論研究、代碼實現和長達數小時模型訓練的旅程,以創(chuàng)建能夠一鍵輕松消除背景的服務。其中最重要的一部分工作是訓練模型,但是也不能低估了正確部署模型的重要性。另外當前***的分割模型還無法像分類模型(比如 SqueezeNet)那么緊湊。并且我們還主動檢查了服務器和瀏覽器的部署選項。

如果你想了解更多關于我們產品的部署過程,建議你去閱讀這兩篇文章,它們分別從服務器端和客戶端的角度介紹了該項目。

如果你只是想了解模型和它的訓練過程,那么請接著閱讀吧。

語義分割

當我們開始認真思考深度學習和計算機視覺中各項技術的時候,顯而易見的,最適于用來實現背景消除任務的技術是語義分割。

當然也有其它的策略,比如說通過深度檢測器實現分割,但是這個對于我們而言似乎還不夠成熟。

語義分割(Semantic segmentation)是一項眾所周知計算機視覺任務,與圖像分類和物體檢測并列為計算機視覺領域的三大挑戰(zhàn)。分割的過程可以視為將圖像中的每個像素點分類到圖像中某一個物體類別上,所以分割實際上也是分類任務。與圖像分類或檢測不同,語義分割真正展現出了對圖像 “理解”。因為它并不只是簡單地指明 “圖像中有只貓”,而且還在像素的級別上直接指出了圖中的貓在哪個位置,以及貓所占的范圍。

那么分割究竟是如何實現的呢?為了更好的理解這一點,我們將回顧一下該領域的一些早期工作。

最早的想法是采用一些早期的分類網絡,比如 VGG 和 Alexnet。VGG 是 2014 年用于處理圖像分類任務***進的模型,并且由于它簡單明了的網絡結構,使得它在今天依然非常有用。在 VGG 較靠前的網絡層中,在要進行分類的物體周圍會具有較高的激活,并且在更深的層次中將具有更強的激活。但是由于重復的池化(Pooling)操作使得這些激活的性質相對粗糙。有了這點基本理解之后,我們可以假設分類訓練模型在進行一些調整之后也能被應用于尋找或者分割圖像中的物體。

語義分割的早期結果與分類算法一起出現。在這篇文章中,你將看到一些通過 VGG 實現的分割結果,但是結果比較粗糙。

[[215858]]

較后邊網絡的結果:

校車的分割結果,淺紫色(29)代表了校車類別
 

經過雙線性上采樣之后:  

這些結果僅來自于將全連接層轉換為原始形狀,而保持了原本的空間特征。在上邊所展示的實例中,我們輸入一張 768*1024 的圖像到 VGG 中,然后獲得一層 24*32*1000,其中 24*32 是該圖像池化后的版本,而 1000 則指的是 Image-net 的類別數量,從中可以導出分割結果。

為了實現平滑預測,研究員使用了一個簡單的雙線性上采樣層。

在 FCN 的論文中,研究員進一步改進了上述的方法。他們連接了一些層次,以便于獲取更多的特征解釋,并且依據上采樣率,分別被命名為 FCN-32、FCN-16 和 FCN-8。

在層之間添加一些跳躍連接允許預測器從原始圖像獲取更精細的細節(jié)。進一步的訓練更能提高結果。

這種技術本身并不像以前所想那么糟糕,并且證明了深度學習在語義分割領域的潛力。

FCN 的處理結果,圖像來自論文

FCN 為語義分割打開了一扇通往新世界的大門,研究員為此任務嘗試了不同的網絡結構。但是核心思想保持不變:使用已知的結構、上采樣和網絡層間跳躍連接。這些技巧在較新的模型中依然常見。

你可以在這幾個貼子中進一步獲取語義分割領域的發(fā)展情況:

  • http://blog.qure.ai/notes/semantic-segmentation-deep-learning-review
  • https://blog.athelas.com/a-brief-history-of-cnns-in-image-segmentation-from-r-cnn-to-mask-r-cnn-34ea83205de4
  • -https://meetshah1995.github.io/semantic-segmentation/deep-learning/pytorch/visdom/2017/06/01/semantic-segmentation-over-the-years.html

另外你可能也發(fā)現了,大多數語義分割方法都保持了編碼 - 解碼(Encoder-decoder)的架構模式。

回到項目

在一番調研之后,我們將目光聚集在了三個模型上:FCN、Unet。其中 Tiramisu 采用了非常深的編碼 - 解碼架構。我們也對 Mask-RCNN 有些想法,但是實現它似乎已經超出了本項目的范圍。

FCN 由于效果太差,首先被我們舍棄。而另外兩個模型的結果還不錯:Tiramisu 和 Unet 的主要優(yōu)勢在于模型緊湊和計算快速。就實現方面而言,Unet 非常容易實現(采用 Keras)而 Tiramisu 也可以實現。并且我們也使用了來自 Jeremy Howard's 的 Deep learning 課程中***一堂課所提供的 Tiramisu 的實現代碼。

保留著兩個候選的模型,我們進入到了下一步——開始訓練模型。必須說明的一點是,當我***次嘗試了 Tiramisu 模型之后,就被它驚人的結果所深深捕獲,因為它能夠捕獲到圖像中的尖銳邊緣。另一方面,Unet 似乎還不夠好,它的結果也是差強人意。

 

數據

既然在模型選擇方面已經有個大概方向,那么接下來我們將開始尋找合適的訓練數據。用于訓練分割模型的數據并不像分類或者檢測那樣常見。事實上,圖像分割最常用的幾個數據集分別是 COCO,它包含有 90 種類別,大概有 8 萬張圖像;VOC pascal,它包含有 20 種類別和 1.1 萬張圖像;以及最近發(fā)布的 ADE20K。

最終我們選擇采用 COCO 數據集,因為它包含有許多關于 “人” 這一類別的圖像,而這正是我們所感興趣的。

考慮到產品所要實現的任務,我們還需要考慮是只使用與任務最相關的那一部分數據集,還是使用更多的更一般的數據?一方面,使用具有更多圖像和類別的更一般性的數據集,將使得模型具備有處理更多場景和更具挑戰(zhàn)性的圖像;而另一方面,一個通宵的時間我們能夠訓練 15 萬張圖像。因此如果我們將完整的 COCO 數據集都用于訓練模型,則一個通宵的時間下來,平均而言,每張圖像將被使用 2 次左右。所以采用更加精簡的部分數據將對模型訓練有益,此外,它將使得模型更加集中。

還有一件值得一提的事是,Tiramisu 模型原本是在 CamVid 數據集上進行訓練的,該數據具有一些缺陷,但最重要的是它的圖像內容非常單調——所有的圖像都是道路與汽車。相信你可以很容易就理解,從這樣的數據集中進行學習(即便它包含有人)對我們的最終目的也沒有任何好處,所以經過短暫的考慮,我們選擇了放棄而改用 COCO。

來自 CamVid 數據集的樣例

COCO 數據集附有非常簡單明了的 API,這可以讓我們準確地知道每張圖像上都包含了哪些物體(根據 90 個預定義的類別)。

經過一番實驗,我們決定精簡數據集。首先,我們選出了那些包含有人物的圖像,這樣的圖像有 4 萬張。然后,我們繼續(xù)將那些包含有太多人物的圖像剔除,剩余的圖片中只包含有 1 到 2 個人,因為這樣的圖像與我們的產品目標最契合。最終,我們只留下那些圖中有 20%~70% 的區(qū)域被標記為人的圖像,而繼續(xù)移除了那些背景中人物過小,或者是存在某些怪異東西的圖片。最終,精簡后的數據集包含有 1.1 萬張圖像,而我們認為這個數據量在現階段已經足夠了。

左邊:好樣例,中間:包含有太多元素,右邊:目標主體太小

 

Tiramisu 模型

如上所述,我們在 Jeremy Howard 的課程中學習到了 Tiramisu 模型。雖然它的全名 “100 層 Tiramisu” 可能暗示了它是一個巨大的模型,但事實上它非常地經濟,甚至只有 900 萬個參數,而 VGG16 則擁有超過 1.3 億個參數。

Tiramisu 模型是參考了 DensNet 的設計而提出的。而 DensNet 是一個最近提出的圖像分類模型,在這個模型中所有層都相互連接。此外,Tiramisu 還在上采樣層添加了跳躍連接(Skip connections),這一點和 Unet 一樣。

如果你還記得,這個架構是符合 FCN 所提出的想法的:使用分類架構、上采樣和跳躍連接進行細化。

Tiramisu 的通用架構

DenseNet 模型可以看作是 ResNet 模型的一個自然演變,但是 DenseNet 不是 “記住” 層與層之間的關系,而是記住了模型中的所有層。這種連接被稱為高速公路連接(Highway connections)。它導致了過濾器數量激增,這被定義為 “增長率”。Tiramisu 的增長率為 16,因此在每一層我們需要添加 16 個新的濾波器,直到達到某一層具有 1072 個濾波器。你也許會期望 1600 層,因為模型的名字是 “100 層 Tiramisu”,然而上采樣層降低了一些濾波器。

Densenet 模型草圖,早期的濾波器堆疊在整個模型中

 

訓練

我們按照原始論文所述的方式對模型進行了訓練:標準的交叉熵、采用 1e-3 學習率的 RMSProp 優(yōu)化器和較小的衰減值。我們將精簡后的 1.1 萬張圖像分成了 70% 的訓練集和 20% 的驗證集,以及 10% 的測試集。接下來展示的所有圖片均來自測試集。

為了保證我們的訓練過程與論文中的保持一致,我將 Epoch size 設置為每 500 張圖像,這使得我們能夠隨著每個結果的改進而定期保存模型,因為我們對更多的數據進行了訓練(原論文使用的 CamVid 數據集包含的圖像少于 1 千)。

此外,我們只在兩種類別上進行訓練:背景與人,而論文中則使用了 12 種類別。我們一開始嘗試在 COCO 的類別上進行訓練,但是發(fā)現這對訓練并沒有太大幫助。

 

數據問題

一些數據集的缺陷阻礙了模型的表現能力:

  • 動物——我們的模型有時候分割動物,這將導致較低的 IoU。在我們任務中往主要類別增加動物進去或者是其它東西將導致結果變差。

  • 軀干——由于我們是通過程序自動化地過濾了數據集,所以無法判斷一張包含有人物的圖片是真的有一個人,還是說僅僅只有一些軀干,比如手或者腳。這些圖像并不在我們的目標范圍內,但是它們還是出現在了數據集中。

動物,軀干,手持物體

  • 手持物體——數據集中的許多圖像都是與運動有關的,圖中人物總是伴隨著棒球棒、網球拍和滑雪板等出現。我們的模型在某種程度上混淆了應該如何去區(qū)分圖中的人和物。與在動物的案例中一樣,將它們歸為主體的一部分或則區(qū)分開來都將有助于提高模型的表現力。

  • 粗糙的真實數據(Ground truth)——COCO 數據集不是按像素進行逐個標記,而是使用了多邊形進行標注。有些時候,這種程度的標注已經足夠了,但是有些時候,這樣的真實數據還是過于粗糙,從而阻礙了模型的學習。

原圖以及粗糙的真實數據

 

結果

我們的結果非常令人滿意,雖然還有些美中不足:我們在測試集上取得 IoU 是 84.6,而目前***的成績則是 85。這個數據(IoU)也是棘手的,因為它在不同的數據集和類別中會發(fā)生波動。有些類別本身就更容易進行分割,例如房子、道路等,許多模型都能很容易取得 90 的 IoU。另一些更加具有挑戰(zhàn)性的類別有樹和人,在這些類別的分割上大多數模型只能達到 60 的 IoU。為了衡量這一困難,我們幫助網絡專注于單一的類別和有限類型的照片。

盡管我們仍然覺得目前的成果尚不足以達到 “可以投入使用(Production ready)” 的標準要求,但是現在是一個暫停下來好好討論結果的好時機,因為大約有 50% 的照片都給出了不錯的結果。

以下是一些比較好的例子。

從左到右分別是:圖像,真實數據,輸出結果(來自測試集)

 

調試與記錄

訓練神經網絡的很重要一部分工作就是進行調試。開始一個神經網絡的訓練非常容易,只要獲取數據輸入網絡,然后就開始進行訓練,最終再看看輸出結果如何。但是我們發(fā)現,跟蹤網絡訓練的每一步都是非常重要的,所以我們?yōu)樽约褐谱髁讼鄳墓ぞ?,以便于能在每個步驟中檢查結果。

以下是一些常見的挑戰(zhàn),以及我們所采取的措施:

  1. 早期問題——該模型可能無法訓練。這可能是因為一些固有的問題,或者由于某種預處理錯誤,例如忘記歸一化數據塊導致的。無論如何,將結果可視化出來將非常有幫助。這有一個與該主題有關的貼子。

  2. 調試網絡——在確定沒有重大問題之后,網絡將以預定義的損失開始訓練。在語義分割領域主要的衡量指標是 IoU——交疊率(Intersect over union)。我們花了一段時間才開始采用 IoU 作為模型訓練的主要指標(而不是交叉熵)。另一個有用的做法是在每一個時期(Epoch)展示一些模型的預測結果。這個帖子很好地介紹了如何調試機器學習模型。另外請注意 IoU 在 keras 中并不是標準的損失函數,但是可以很容易在網上找到現成的,比如這個。我們也利用這個 Gist 來繪制每個時期的損失和預測結果。

  3. 機器學習的版本控制——通常一個模型都會具有許多參數,有些參數比較難以跟蹤。我必須說明我們還沒找到***的方法解決這個問題,除了比較頻繁地寫出配置信息(并使用 keras 回調自動保存***模型,參見下文)。

  4. 調試工具——在完成了以上所有措施后,我們將能夠在每一個步驟檢驗我們工作,但是依然無法做到無縫檢測。因此,最重要的一步是將上述步驟結合起來,并創(chuàng)建一個 Jupyter 筆記本,我么能夠借助它實現無縫地加載每個模型和每個圖像,并且能夠快速檢測它的結果。這樣我們可以很容易發(fā)現模型之間的差異、模型的缺陷以及其它問題。

以下是我們模型的改進示例,以及參數調整和額外的訓練。

保存在驗證集上取得*** IoU 成績的模型(Keras 提供了一個非常棒的回調函數,使得這件事變得非常簡單):

callbacks = [keras.callbacks.ModelCheckpoint(hist_model, verbose=1,save_best_only =True, monitor= ’val_IOU_calc_loss’), plot_losses]

除了可能的代碼錯誤的正常調試之外,我們還注意到,模型的錯誤是 “可預測的”。如 “切割” 身體部分超出了正常的軀干范圍,沒必要的軀干延伸,光照不足,照片質量低和照片中細節(jié)過多等。其中一些在添加不同數據集中特定圖像時被處理掉了,但是其它的一些則依然是一項還有待處理的挑戰(zhàn)。為了在下個版本能夠提升結果,我們將使用專門針對 “硬” 圖像的擴充進行訓練模型。

數據集問題我們在之前已經談到過了?,F在來看看模型面臨的一些挑戰(zhàn):

  1. 衣服——非常亮或者非常黑的衣服有時會被當成背景

  2. “挖洞”——有些本應該不錯的結果卻有出現類似于被挖了一個洞情況

衣服和 “挖洞”

  3. 燈光——雖然光照不足和圖像模糊的情況在照片中很常見,但是 COCO 數據集卻不常見這類情況。因此,除了使用標準難度的模型來處理之外,我們還沒有為那些富有挑戰(zhàn)的圖像做好準備。這一問題可以通過獲取更多數據,或者增強數據(Data augmentation)來解決。

光照不足的樣例

 

未來

進一步訓練

我們的訓練數據訓練了 300 多個時期,在這之后,模型開始變得過擬合。由于我們的結果已經非常接近于發(fā)布的成績,因此我們沒有機會應用數據增強的基本做法。

訓練所用的輸入圖像統(tǒng)一被調整為 224*224 大小。更進一步地,采用更多的數據和更大分辨率的圖像(COCO 圖像的原始大小約為 600*1000)進行訓練模型也對提高最終的結果有幫助。

CRF 和其它增強

在某些階段,我們發(fā)現有些結果的邊緣存在噪點??梢圆捎?CRF 模型來改善這一問題。在這個博客中,作者展示了 CRF 的簡單使用樣例。

但是該方法對我們的工作來說還不是很有幫助,也許是因為只有當結果比較粗糙的時候該方法才會有所幫助。

摳圖(Matting)

即使我們目前取得了這樣的結果,但是在實際的分割中還是不夠***。諸如頭發(fā)、細膩的衣服、樹枝和其它精美的物品永遠無法被***分割。事實上,這種非常精細的分割任務被稱為摳圖(Matting),它定義了一種不同的挑戰(zhàn)。這里展示了一個當前***進的摳圖樣例,該項工作是在今年早些時候的 NVIDIA 大會上發(fā)表的。

摳圖樣例,輸入包含了 Trimap

摳圖任務與其它圖像相關的任務不太一樣,因為它的輸入中不僅有原始圖像還有三分圖(Trimap)。三分圖指的是圖像邊緣的輪廓,這也使得它成了 “半監(jiān)督” 問題。

我們使用摳圖進行了一些實驗,就是將我們的分割圖像作為三分圖使用,但是卻沒有取得任何有意義的結果。

還有一個問題就是缺乏使用的訓練數據集。 

總結

正如一開始所說的,我們的目標是開發(fā)出一款具有意義的深度學習產品。正如你可以在 Alon 的貼子里看到的那樣,部署相對而言更加容易和快速。另一方面,模型的訓練才是最棘手的——特別是需要花上一晚的時間進行訓練,此時你就需要進行仔細規(guī)劃、調試和記錄結果。

事實證明,要在研究和嘗試新事物以及訓練和改進模型之間取得平衡是一件不容易的事情。由于使用了深度學習,我們總是覺得***的模型或者最適合我們的模型就躲在某個角落,只需要多進行一次 Google 搜索或者多閱讀一篇論文就將會引導我們發(fā)現它。但是在實踐中,我們實際的改進來自于從原始的模型中一點點地 “擠壓”。而且如上所述,我們仍然覺得有更多的地方可以繼續(xù)改進。 

 

責任編輯:龐桂玉 來源: 機器學習算法與Python學習
相關推薦

2024-03-26 09:11:13

TensorFlow深度學習Pipeline

2017-11-27 17:29:43

深度學習TensorFlow安卓設備

2018-08-16 08:19:30

2017-09-09 06:04:22

深度學習人物圖像神經網絡

2017-12-06 15:46:31

深度學習結構化數據NLP

2020-10-16 14:59:32

機器學習人工智能神經網絡

2018-03-20 15:33:05

深度學習加密貨幣

2017-09-15 18:13:57

機器學習深度學習語音識別

2023-12-01 18:06:19

2018-03-23 09:29:56

深度學習神經網絡前端設計模型

2020-04-07 14:45:35

開源摳圖 技術

2021-08-30 15:27:05

AI 數據人工智能

2011-03-15 09:10:47

iptablesNAT

2011-03-15 14:26:23

iptablesNAT

2018-05-18 09:57:04

深度學習乳腺癌神經網絡

2017-05-16 15:00:24

深度學習

2020-10-23 15:29:48

iPad摳圖PC

2020-10-14 10:25:20

深度學習機器學習神經網絡

2021-01-03 17:24:01

人工智能AI

2022-06-28 10:18:12

深度學習模型
點贊
收藏

51CTO技術棧公眾號