司法鑒定牽手深度學習:Kaggle 相機型號識別大賽深度分析

圖片來源:https://habr.com/company/ods/blog/415571/

雷鋒網 AI 科技評論按:大約一年前,Kaggle 舉辦了一個名為「相機型號識別」(https://www.kaggle.com/c/sp-society-camera-model-identification)的計算機視覺挑戰賽,任務是確定出用來拍攝某張圖像的照相機的型號。比賽結束后,Arthur Kuzin, Artur Fattakhov, Ilya Kibardin, Ruslan Dutov 和 Vladimir Iglovikov 決定寫一篇科技報告,向大家介紹如何解決這個問題,並分享他們在此過程中獲得的心得體會。這篇文章被在西雅圖舉辦的第二屆網絡犯罪調查大數據分析國際研討會(http://folk.ntnu.no/andriis/bdaccip2018/)接受,而 Vladimir Iglovikov 將於 2018 年 12 月 10 日在大會上對這篇論文進行報告。以下是他對報告內容(https://arxiv.org/abs/1810.02981)的擴展版。

本文的作者共有 5 人:

Arthur Fattakhov, Arthur Kuzin, 以及 Ilya Kibrdin 是本次比賽亞軍團隊,他們的最終得分為 0.987。Vladimir Iglovikov 是獲得第 9 名的團隊的成員,最終得分為 0.985。這兩支團隊的解決方案非常相似,因此他們決定寫一份技術報告。Ruslan 是深圳大學大數據研究院的一名研究生,他幫助完成了文本方面的工作,這對於這篇論文的順利發表至關重要。

在本文接下來的部分,作者會把亞軍團隊所使用的方法稱為「我們」的解決方案。此外,也將跳過一些不重要的技術細節。亞軍的解決方案的代碼可以在 GitHub( https://github.com/ikibardin/kaggle-camera-model-identification)上獲得。比賽結束后,他們還根據自己的認識進行了一組單獨實驗。本文主要是關於進一步的研究。

正文如下,雷鋒網 AI 科技評論編譯整理:

相機型號檢測是圖像處理的眾多應用之一。例如,在司法鑒定領域,判斷出一幅圖片是使用谷歌 Pixel 還是 iPhone 拍攝或許會非常重要,這可以進一步確定出誰可能是非法圖像的所有者,甚至確定誰是知識產權的合法所有者,這種系統甚至可以用於在「誹謗或傳播假新聞」的案件中發現犯罪嫌疑人。

計算機將圖像存儲為數字矩陣和相應的元數據,在最簡單的情況下,相機型號通常會被存儲在圖像元數據中,此時對型號的識別就成為一個非常簡單的問題。但是圖像元數據可能不可靠,而且很容易被不法用戶操縱。

還有一種更複雜、但更可靠的方法。圖像採集完成後,數碼相機將在一系列後續處理步驟之後,創建一個針對圖像的保真度和內存佔用進行優化后的圖像。這些算法是一些高度非線性、極其複雜的方法,例如去馬賽克、噪聲濾波、修正鏡頭畸變等。不同型號的相機使用不同的算法,這意味着每個算法在特定的型號上都會給出特定的輸出,我們可以將這些數據作為機器學習工作流中使用的特徵。

當然,目前已經有很多關於這個主題的文獻,大多數現有的文獻在此基礎上提出了基於 SVM 或類似的分類算法的人工特徵提取步驟。例如,當我碰到這個問題時,我腦海中出現的第一個想法就是取一張圖像,用它減去自身經過平滑處理后的圖像,然後計算出這種差異的不同統計量(比如均值、中值、標準差、不同的分位數),然後利用他們作為輸入訓練 xgboost 集成學習模型。關於如何進行相機模型檢測的第一篇論文所使用的方法與我剛才描述的方法非常接近,其它後續的論文提出了一些更複雜的模型,但方法非常相似。方法無外乎:基於領域知識的人工特徵提取,在此基礎上加入邏輯回歸、決策樹或支持向量機等等。

將這種方法擴展到新的相機型號也是一件很困難的事。假設我們想為一款新發佈的相機進行這種檢測。那麼,專家應該花多少時間來找出哪些特性將有助於將其與其他型號的相機區分開來?另一方面,深度學習方法可以同時解決這些問題。一般來說,深度學習就好比一種強大的野獸,如果你知道如何馴服它,它可能會幫助你創建高度精確的黑盒模型。

像往常一樣,你幾乎不可能通過翻閱文獻試圖找到「最好的方法」。幾乎每篇論文都會告訴你,他們和其他人不一樣,而他們的方法是最先進的。想要解決這個問題,你就需要在同一數據集上對不同方法進行評估。這樣的比較不會告訴你哪種算法總體上更好,但是你可以看出在給定的數據集上用某種特定的度量標準去評價時哪種算法更好。這並不意味着算法在類似的數據集上的性能排名一定是相同的,比如在 CIFAR 數據集上最先進的架構可能在 ImageNet 上表現不佳,反之亦然。但是有這樣一個標準一致的比較總比沒有好。

在這次的挑戰賽中,582 支參賽團隊將在兩個月的時間內在實時排行榜上比拼他們的算法。582 對於 kaggle 競賽的參賽隊伍數來說是一個相對較大的數字,這就保證了這個問題將由一些有着不同專業背景和技能的人來解決。一些參賽人員在工業界和學術界從事司法鑒定的相關工作,還有一些像我一樣的參賽人員,則有着計算機視覺方面的經驗,但我們對這樣的相機識別問題並沒有很深刻的認識,也不知道有人有興趣解決它。

大賽組織者準備了一套由 10 個相機拍攝的 2750 張照片(每個相機拍攝了 275 張照片)組成的訓練集。

我們需要區分的相機型號有:

1. Sony NEX-7

2. Motorola Moto X

3. Motorola Nexus 6

4. Motorola DROID MAXX

5. LG Nexus 5x

6. Apple iPhone 6

7. Apple iPhone 4s

8. HTC One M7

9. Samsung Galaxy S4

10. Samsung Galaxy Note 3

為了增加比賽難度,組織者共用了 20 部不同的手機來收集圖像,其中有 10 部被用於建立訓練集,另外 10 部被用於建立測試集。這意味着在訓練過程中,你的模型可能學習到的並不是與後續處理算法相關的針對特定相機型號的特性,而是會過擬合特定手機產生的特定的輸出。

測試集中的圖像是用 10 個與訓練集中對應相同型號的相機拍攝的,但使用的是相同型號的第二台設備。例如,如果在訓練數據中使用 iPhone6 拍攝的圖像是使用 Ben Hamner 的第一台 iPhone 6 拍的,那麼在測試數據中使用 iPhone6 拍攝的圖像則是使用 Ben Hamner 的第二台 iPhone 6 拍的,因為他在玩風箏時在海灣丟失了第一部手機。

此外。訓練集中的圖像是完整全尺寸的,而在測試中只使用了圖像中央裁剪出的 512x512 像素的部分。之所以這樣處理,是因為徑向畸變在圖像的兩側更加明顯。一些論文僅僅基於徑向畸變特徵就取得了較好的結果。然而,目前還尚不清楚它們能帶來多大的幫助,但組織者決定禁止參與者利用這些特徵。

在許多情況下,通常存儲在計算機上的圖像會受到不同類型的圖像變換的影響,如 jpeg 壓縮、伽馬變換、對比度、亮度、大小等方面的變換。

從實用的角度來看,模型最好能對這些變換具有很強的魯棒性,組織者對一半的測試圖像進行了類似的變換,如下所示:

1. JPEG 壓縮質量因子 = 70

2. JPEG 壓縮質量因子 = 90 

3. 通過因子 = 0.5 的雙三次插值進行縮放

4. 通過因子 = 0.8 的雙三次插值進行縮放

5. 通過因子 = 1.5 的雙三次插值進行縮放

6. 通過因子 = 2.0 的雙三次插值進行縮放

7. 使用 gamma = 0.8 的伽馬校正

8. 使用 gamma = 1.2 的伽馬校正

如上文所述,不同型號的相機拍出來的圖片的規模在千兆位元組,我們可以利用這些數據提取出相應相機型號。Kaggle 上的不同競賽對於使用外部數據有不同的規則,但在本項比賽中,Kaggle 允許我們使用外部的圖像數據訓練模型。一般來說,所有允許使用外部數據的競賽都有一個規則,Kaggle 規定所有其他的參賽者也可以訪問這些數據。在任何此類競賽中,Kaggle 論壇上都會專門設有一個論壇,參與者可以在其中分享他們將使用的數據和預訓練的模型。

這次比賽是個例外,管理員忘記在規則中添加關於共享數據的條款,這就改變了遊戲規則。

深度學習模型的優勢在於,它們可以從大量的訓練數據中獲取知識。此外,我們還應該特別注意到,許多訓練標籤可能是錯誤的,但這個問題也比較好解決,只要錯誤標籤的百分比小於某個閾值(比如百分之十五),這個訓練數據集就是一個好的數據集。使用的數據越多,你的模型就越好。

參與者可能並不是司法鑒定專家,但他們肯定知道更多的數據對深度學習來說是更好的。通常,在競賽中,你試圖從給定的數據集中獲取最多的信息,在進行了一些實驗之後,你會選擇一個性能良好的模型,巧妙地選擇數據增強的方式,探索相關領域知識,花時間開發一個智能訓練計劃,訓練損失函數等等。如果你沒有更好的選擇,完成所有這些步驟都很重要。

我們在 Flickr、Yandex、Fotki、Wikipedia 上爬到了一些數據,而在這種情況下,我們的團隊擁有的原始圖像數據總量約為 500GB。我們可以使用所有這些數據,但是為了加速訓練,並潛在地提高模型質量,我們進行對數據進行了過濾。

在訓練過程中,我們需要的是未經處理的數據,即不受 Photoshop 、LightRoom 或類似圖像編輯軟件的影響,不進行縮放的高質量圖像。

不同型號相機的數據集樣本數。上表給出了包含外部和組織者提供的數據集的最終數據集。

首先,我們刪除掉了元數據中包含 Photoshop 和 LightRoom 的圖像。接着,我們刪除了 JPEG 質量低於 95 的圖像。第三,我們讓不同的相機拍攝固定尺寸的照片。如果圖像的大小與我們預期的不匹配,我們就會認為這些圖像是經過了縮放的。我們刪除了不滿足這些條件的圖像。

這並不意味着我們得到的所有圖像都是未經處理的,比如有人可能使用質量為 10% 的 JPEG壓縮,然後再應用質量為 99% 的 JPEG 壓縮。實際上,壓縮后的質量仍然是 10%,但是對於軟件來說,很難分析出壓縮因子是 10 而不是 99。我認為這是不可能做到的。但我在研究這個問題時,我看到一些論文也試圖識別出這種「二次 JPEG 壓縮」。再說一次,我甚至不知道存在這樣的問題。

經過過濾,我們得到了 78,807 張爬取的圖像,我們認為這些圖像是原始的,未經處理的。這些圖像的類別分佈是不均勻的。正如你可以想到的那樣,並非所有手機都同樣受歡迎,或者說手機型號與用戶拍照並上傳至互聯網的頻率之間存在相關性。因此,對於某些類別的手機所得到的圖像,我們所得到的樣本就相對較少一些:

總的來說,這個機器學習工作流類似於利用 ImageNet 進行遷移學習,你會使用預訓練的網絡,去掉最後一個預測 1000 個類的層,用一個預測你所需要的類別的層替換它。在本例中,這個層的輸出類別數是10。在此之後,你可以使用分類交叉熵作為損失函數並訓練網絡。有很多方法可以做到這一點,而第 1 名的解決方案和第 50 名的解決方案之間的區別通常不在他們使用的網絡類型,而在於訓練過程以及進行訓練的人。從實踐的角度來看,與其說深度學習是科學,不如說更像是鍊金術。因此,當一個人從事不同的工作時,直覺是至關重要的。

Remi Cadene 在 GitHub 上的代碼庫(https://github.com/Cadene/pretrained-models.pytorch)提供了一個 PyTorch 框架下的帶權重的網絡列表,人們可以使用類似的 API 獲得不同的網絡和預訓練的權重,從而使他們的實驗能夠快速進行。這個代碼庫被參賽人員廣泛使用。各個參賽隊伍用 Resnet、VGG、DPN 和所有其它類型的網絡進行了實驗。

對於這個問題,一個經驗性的結論是:DenseNet(https://arxiv.org/abs/1608.06993) 的性能會稍好一些,但是團隊之間的差異非常小,所以不清楚這樣的說法是否為真。什麼是 DenseNet 呢?DenseNet是一種架構,它進一步推動了在 Resnet 類型的網絡中使用跳躍連接的想法。

更多的跳躍連接!

DenseNet 論文的作者將卷積塊中的所有層連接起來,跳躍連接簡化了梯度流,使得訓練深層網絡成為可能。在跳躍連接成為主流之前,處理只有 19 層的 VGG19 網絡是一件痛苦的事情,但是在引入它們之後,使用具有 100 多個層的網絡處理高度抽象特性就不再是一個困難的問題了。

研究人員相信,這樣做會使得損失表面更加平滑,防止基於梯度下降的訓練過程陷入許多局部最小值。

圖片來源:https://arxiv.org/abs/1712.09913

除此之外,網絡是相對標準的,它使用了一組具有批量歸一化和 ReLu 層的卷積塊,卷積塊之間使用了最大池化層,最後是全局平均池化和全連接層。需要注意的是,全局平均池化層允許我們使用不同大小的圖像作為輸入。

研究社區中的一些人認為 DenseNet 的性能總是優於 Resnet,因為它是相對較后提出的,並成為了 CVPR 2017 最佳論文。然而,事實並非如此!在原始論文中,DenseNet 在 CIFAR 上取得了良好的結果,但在數據更多樣化的 ImageNet 數據集上,更深的DenseNet 才能得到與更淺的 ResNet 網絡相當的準確率。 

DenseNet比Resnet更好/更差嗎?這個問題得視情況而定。在「Planet: Understanding the Amazon from Space challenge」競賽(https://www.kaggle.com/c/planet-understanding-the-amazon-from-space)中,我們團隊使用  DenseNet,從 900 多支團隊中奪得第 7 名,這一網絡在這次比賽中表現得更好,但它在 ImageNet 上的表現較差。

我和我的合作者對此進行了深入的討論,有人認為跳躍連接不僅平滑了損失表面,而且還降低了模型容量。這也許可以解釋為什麼 DenseNet 在像 CIFAR 這樣的非多樣化問題中表現更好,但是需要在 ImageNet 這樣的多樣化的數據集上增加網絡的深度,以補償容量的損失。基於這種推測,我們可以認為當數據集不是非常多樣化且不需要大容量的網絡時,DenseNet 的性能會很好。但是當判別特性高度抽象時,我們就可能需要非常深的網絡。

相機檢測任務屬於這一類問題嗎?我不知道。從經驗上說它確實是的,但我們並沒有足夠的證據證明這一點。

在訓練過程中加入智能的正則化標準方法是使用數據增強。不同的問題可能受益於不同的數據增強方法。同樣的,如果你擁有更好的直覺,你可能會選出更好的數據增強方法和參數。

對於這個問題,我們使用了:

1. Dihedral Group D4 變換:將圖像旋轉 90、180、270 度,以及進行翻轉操作。

2. 伽馬變換:我們在 [80,120] 的範圍內均勻地選擇了伽馬參數。

3. 質量因子參數從 70 到 90 均勻採樣的 JPEG 壓縮。

4. 縮放因子在 [0.5,2] 的範圍內的變換。

使用 albumentations 程序庫(https://github.com/albu/albumentations)的代碼如下:

 import albumentations as albu

def train_transform(image, p=1):
   aug = albu.Compose([albu.RandomRotate90(p=0.5),
                       albu.HorizontalFlip(p=0.5),
                       albu.RandomGamma(gamma_limit=(80, 120), p=0.5),
                       albu.JpegCompression(quality_lower=70, quality_upper=90, p=0.5),
                       albu.RandomScale(scale_limit=(0.5, 2), interpolation=cv2.INTER_CUBIC, p=1)
                       ], p=p)
   return aug(image=image)['image']

左圖是我最近去 Bishop 攀岩時的原始照片;右圖是翻轉過來的結果,其顏色深一些。後者是進行了伽馬變換得到的結果。在這裡我們也應用了 JPEG 壓縮,但由於這類圖像的質量 [70:90] 相對較高,肉眼很難看出它的效果。

組織者告訴我們他們用三次插值來進行縮放,如果不知道使用三次插值,我們會交替使用不同的插值方式。一般來說,機器學習競賽社區中經常會使用這種技巧,但是我還沒在文獻中看到對這樣的方法的描述。

如果我們想要添加這些替代方法,代碼將會更複雜一些,但思路仍然是相對直觀的。

import albumentations as albu

def train_transform(image, p=1):
   scale_limit = (0.5, 2)    aug = albu.Compose([
       albu.RandomRotate90(p=0.5),
       albu.HorizontalFlip(p=0.5),
       albu.RandomGamma(gamma_limit=(80, 120), p=0.5),
       albu.JpegCompression(quality_lower=70, quality_upper=90, p=0.5),
       albu.OneOf([albu.RandomScale(scale_limit=scale_limit, interpolation=cv2.INTER_NEAREST, p=0.5),
                   albu.RandomScale(scale_limit=scale_limit, interpolation=cv2.INTER_LINEAR, p=0.5),
                   albu.RandomScale(scale_limit=scale_limit, interpolation=cv2.INTER_CUBIC, p=0.5),
                   albu.RandomScale(scale_limit=scale_limit, interpolation=cv2.INTER_AREA, p=0.5),
                   albu.RandomScale(scale_limit=scale_limit, interpolation=cv2.INTER_LANCZOS4, p=0.5),
                   ], p=0.5),
   ], p=p)
   return aug(image=image)['image']

原圖的分辨率很大,在全分辨率上對它們進行縮放是不明智的,因此我們進行了兩次連續裁剪(縮放前後各一次)。

import albumentations as albu

def train_transform(image, p=1):
   aug = albu.Compose([
       albu.RandomCrop(height=960, width=960, p=1),
       albu.RandomRotate90(p=0.5),
       albu.HorizontalFlip(p=0.5),
       albu.RandomGamma(gamma_limit=(80, 120), p=0.5),
       albu.JpegCompression(quality_lower=70, quality_upper=90, p=0.5),
       albu.RandomScale(scale_limit=(0.5, 2), interpolation=cv2.INTER_CUBIC, p=1)
       albu.RandomCrop(height=480, width=480, p=1),
   ], p=p)
   return aug(image=image)['image']

我們使用 Adam 優化器對網絡進行了 100 個 epoch 的訓練,初始學習率為 0.001。

為了獲得更高的準確率,當學習速率在不同的值之間振蕩時,我們還採用了循環學習速率方法進行改進。 

你從這張圖中可以猜到,學習速率在第 17 個 epoch 前後降低了。圖中存在兩個連續衰減的損失峰,一個大約在第 42 個 epoch 左右,另一個大約在第 53 個 epoch 左右。在訓練過程中,網絡容易陷入局部極小值,而這些振蕩有助於跳出這些局部最小值。

在進行推斷時,我們對測試圖像進行增強,對在不同的 480x480 的裁剪圖像上的預測結果進行平均。

我們還想評估不同的變換是如何降低模型準確率的。 

我們通過綠色的部分顯示了訓練中使用的參數的範圍。正如預期的那樣,在特定的參數範圍內,準確率沒有顯著下降。這表明,如果我們使用深度學習方法,並擁有足夠的數據,加強數據增強可能會提升模型的魯棒性。

我們想要回答的另一個問題是,如果我們在測試時減小輸入到網絡中的裁剪圖像的大小,準確率會如何變化?

我認為網絡正在學習的特性是局部的,所以不需要進行大的裁剪,但似乎事實並非如此。要想在 10 個類上獲得 90% 以上的精度,就必須有至少 250x250 的裁剪圖片作為輸入,這可能意味着後續處理算法在網絡捕獲的像素之間創建了遠距離的相關性聯繫。

我們還想證實:當訓練數據量增加時,模型的準確率也會提高。正如你在上圖中看到的,這樣的情況並沒有發生。我想 25k 圖片對於一個高質量的模型來說已經足夠了。如果我們需要檢測的不是 10 個類,而是 1000 個類,那麼模型質量的提升可能會更加顯著。

總結:

1. 利用 ImageNet 預訓練模型進行的遷移學習在相機檢測等使用低級特徵的任務中,可以取得很好的性能。

2. DenseNet 的性能更好,但我們相信,如果我們從 Cadene 提供的代碼列表中任意選擇預訓練好的網絡,它的表現也會類似。

3. 在訓練中使用數據增強技術會幫助模型提升魯棒性。

4. 如果你能獲取到更多的帶標籤的數據,盡量去獲取吧。在大多數情況下,儘管利用領域知識可以提供額外的重要幫助,「暴力」地處理大量數據可能比使用複雜的解決方案提高模型性能更容易。

文中略過的內容:

1. 是否有必要添加額外的輸出來顯示出圖像是否被修改過?

2. checkpoint averaging 等技巧。

3. 其他架構的性能如何?

4. 如何將集成學習技術應用到這個問題上。

5. 測試集中的類是平衡的,我們可以如何利用。

6. 如何將偽標記技術(一種半監督學習技術)應用於此任務。

7. 對那些我們嘗試過、但是沒有成功的方法進行討論。

8. 解釋網絡學習到的特徵是什麼?

9. 評價指標的細微差別。

所有這些議題都很重要,但我不認為它們有太大的影響,或者我更願意就每一個議題單獨進行討論。

註:本文作者將於 2018 年 12 月 10-13 日在美國西雅圖舉行的 IEEE 2018 大數據國際會議「第二屆網絡犯罪調查與預防大數據分析國際研討會」上做與本文相關的報告。

(完)

via towardsdatascience

雷鋒網 AI 科技評論編譯整理


想在手機閱讀更多iPhone 遊戲資訊?下載【香港矽谷】Android應用
分享到Facebook
技術平台: Nasthon Systems