學習深度學習,最常接觸到的就是各式各樣的神經網絡了,其中卷積神經網絡是諸多神經網絡中最典型最常用的神經網絡了。本文原始素材來源於freecodecamp博客,經本人翻譯首發於此。希望能幫助到大家!覺得不錯就點個讚,或者關注下我吧,後續我還會分享更多相關的精彩內容。
Everything you need to know to master Convolutional Neural Networks
作者: Tirmidzi Faizal Aflahi
本文開始之前,請大家看看下面的這張照片:
這其實不是一張真正的照片。您可以在新選項卡中打開圖像並放大圖像。你看到馬賽克了嗎?(特別留意下圖片右側車子的窗戶上的模糊區域)
實際上,這張圖片是由一個名為Artificial Intelligence的程序生成的。難道生成的還不夠現實嗎?這很棒,不是嗎?
這種黑技術,自Alex Krizhevsky和他的朋友通過ImageNet競賽首次推向公眾,到如今廣泛應用,也不過是短短的7年時間而已。ImageNet競賽在當時是一項一年一度的計算機視覺大賽,它的目標很簡單,就是將圖片按1000個不同類別進行分類,從阿拉斯加雪橇犬到衛生紙。Alex和朋友們建立了一個名為AlexNet的東西,贏得那年的冠軍,並且是以遠超於第二名的性能絕對優勢贏得了比賽。
該種黑科技技術稱為卷積神經網絡。它是深度神經網絡的一個子分支,在處理圖像時表現非常出色。
上圖是過去幾年,各冠軍方法贏得比賽時其對應的錯誤率。灰色柱狀是人類分類時對應的錯誤率,注意到,在2016年,深度學習的分類準確率實際上已經比人類表現還要好5%左右。
太可怕了,不是嗎?實際上,將深度學習引進到到這個領域,不是在改變遊戲玩法的規則,讓人更感覺是在破壞遊戲了。
卷積神經網絡體系結構
那麼,這項技術如何運作?
卷積神經網絡由於其獨特的過程而比其他深度神經網絡架構表現更好。CNN不是一次查看一個像素的圖像,而是將幾個像素組合在一起(例如上圖中的3×3像素),這樣他們就可以理解時間模式(Temporal Pattern)。
換句話說,CNN可以「看到」形成線或曲線的像素組。由於深度神經網絡的深層性質,在下一級別中,它們不會看到像素組,而是「看到」一些形成某組組合形狀的線和曲線。以此類推,直到他們形成完整的畫面。
如果你想深入了解CNN,你需要學習很多東西,從基本的東西,比如kernel,pooling layers等等。但是現在,您可以稍微划水,目前很多開源項目能夠幫你實現這項技術。
實際上,這個歸功於一種稱為遷移學習(Transfer Learning)的技術。
遷移學習
遷移學習是一種將已完成的深度學習模型重新用於另一個更具體任務的技術。
例如,假設您在火車管理公司工作,並想評估您的火車是否準時。您當然不想僅僅因為這個任務就增添其他員工專門做這件事情。
您可以重複使用ImageNet卷積神經網絡模型,也許是ResNet(2015年獲勝者提出的方法),並使用您的列車車隊圖像重新訓練網絡。你會做得很好。
Transfer Learning有兩個主要的競爭優勢:
比從頭開始訓練需要更少的圖像。ImageNet競賽有大約100萬張圖像可供訓練。使用遷移學習,您只需要使用1000張甚至100張圖像就可以訓練好表現良好的模型,因為它其實已經使用這100萬張圖像進行了訓練。需要更少的時間來達到良好的性能。為了訓練一個和ImageNet一樣好的模型,您需要花費數些天對網絡進行訓練,這還不包括如果網絡不能正常工作還需要更改網絡所需的時間。而使用遷移學習學習,您只需要幾個小時甚至幾分鐘即可完成某些任務的訓練。這無疑節省了很多時間。
圖像分類到圖像生成
得益於遷移學習的實現,許多方案都變成了可能。既然您可以處理一些圖像並告訴我們圖像的全部內容,那麼你是否能夠構建圖像本身呢?
接受挑戰!
生成對抗網絡此刻蠢蠢欲動,它表示對此沒有什麼壓力。
這項技術可以使用一些輸入生成圖片。
我們可以使用一個名為CycleGAN的對抗網絡繪畫生成生成逼真的照片,例如上面這些我所展示的圖片。在另一個用例中,它還可以利用低解析度的照片,生成更高解析度的照片。
太神奇了,不是嗎?
當然。現在你可以開始學習如何構建它們了。
卷積神經網絡教程
那麼,讓我們開始吧。你會發現入門其實非常簡單,但是掌握它卻又是另一個層面的事情了。
讓我們暫時把掌握它放在一邊。
瀏覽了好幾天後,我發現這個項目非常適合你。
航拍仙人掌識別
這是Kaggle比賽的入門教程項目。你的任務是確定航拍圖像中是否有柱狀仙人掌。
很簡單,嗯?
您將獲得17,500張圖像,然後在預測結果中輸出4,000張未標記的圖像的label。如果您的程序正確標記了所有4,000張圖像,則您的分數為1或100%。
這些圖像非常像您在上面看到的。可能包含或不包含一組柱狀仙人掌的區域的照片。這些照片是32×32像素。它顯示了不同方向的仙人掌,因為它們是航拍照片。
那麼你需要什麼?
Python的卷積神經網絡
是的,Python,深度學習的流行語言。對於框架,你有很多選擇,你幾乎可以為每個選擇做試驗和錯誤。選擇是:
Tensorflow,最受歡迎的深度學習庫。由谷歌的工程師建造,擁有最大的貢獻者基礎和大多數粉絲。由於社區規模如此之大,您可以輕鬆找到問題的解決方案。它將Keras作為高級抽象包裝器,對新手來說非常有利。Pytorch。我最喜歡的深度學習庫。純粹基於Python構建並遵循Python的優缺點。Python開發人員將非常熟悉這個庫。它有另一個名為FastAI的庫,它提供了Keras對Tensorflow的抽象。MXNet。Apache的深度學習庫。Theano。Tensorflow的前身CNTK。微軟也有自己的深度學習庫
在本教程中,讓我們使用我最喜歡的一個,Pytorch,以及它的抽象FastAI。
在開始之前,您需要安裝Python。轉到Python網站並下載所需內容。您需要確保安裝版本3.6+,否則您將使用的庫可能不支持它。
現在,打開命令行或終端並安裝這些東西
pip install numpy pip install pandas pip install jupyter
Numpy將用於存儲輸入的圖像。pandas用於處理CSV文件。Jupyter notebook是您使用Python交互式編碼所需的。
然後,前往Pytorch網站下載您需要的內容。您可能需要CUDA版本才能加快訓練速度。但要確保你有版本1.0+的Pytorch。
之後,安裝torchvision和FastAI:
pip install torchvision pip install fastai
使用命令jupyter notebook運行Jupyter,它將打開一個瀏覽器窗口。
現在,你準備好了。
準備數據
導入必要的代碼:
import numpy as npimport pandas as pd from pathlib import Path from fastai import * from fastai.vision import * import torch %matplotlib inline
你想做的一切都需要Numpy和Pandas。FastAI和Torch是您的深度學習庫。Matplotlib Inline將用於顯示圖表。
現在,從kaggle網站下載數據文件。
解壓縮zip數據文件並將它們放在jupyter notebook文件夾中。
假設您將notebook命名為Cacti。你的文件夾結構是這樣的:
Train folder包含了訓練步驟所需的所有圖像
Test folder包含了要提交的所有圖像
Train CSV 文件包含訓練數據; 使用列has_cactus映射圖像名稱,如果它具有cactus,則給出值1,否則為0。
Sample Submission CSV包含了您需要執行的提交格式。
train_df = pd.read_csv("train.csv")
將Train CSV文件加載到data frame。
data_folder = Path(".") train_img = ImageList.from_df(train_df, path=data_folder, folder='train')
使用ImageList from_df方法創建一個Load Generator ,將train_df 的data frame映射到train文件夾中的圖像。
數據擴充
這是一種從現有數據創建更多數據的技術。垂直翻轉的貓的圖像仍然是一隻貓。通過這樣做,您基本上可以將數據集乘以兩次,四次,甚至16次。
如果您碰巧只有很少的數據可用,那麼您將需要這種技術。
transformations = get_transforms(do_flip=True, flip_vert=True, max_rotate=10.0, max_zoom=1.1, max_lighting=0.2, max_warp=0.2, p_affine=0.75, p_lighting=0.75)
FastAI為您提供了一個很好的轉換方法來完成所有這些,它稱為get_transform。您可以垂直,水平,旋轉,縮放,添加光照/亮度以及扭曲圖像。
您可以使用上面提到的參數執行程序試試,或者您也可以打開文檔並詳細閱讀。
訓練準備
加載數據後,您需要為深度學習中最重要的階段(也就是訓練階段),準備好自己和數據。從根本上來說,這也就是深度學習中的學習。它從您的數據中學習,並相應地反饋並更新自身,以便它在您的數據上具有良好的性能。
對你的圖像列表進行以下方式的轉換:
test_df = pd.read_csv("sample_submission.csv")
test_img = ImageList.from_df(test_df, path=data_folder, folder='test')
train_img = train_img .split_by_rand_pct(0.01) .label_from_df() .add_test(test_img) .transform(transformations, size=128) .databunch(path='.', bs=64, device=torch.device('cuda:0')) .normalize(imagenet_stats)
對於訓練步驟,將一小部分訓練數據分隔出來,也就是大家熟知的驗證集。在訓練時,您不能去接觸這些數據,因為它們是模型的驗證工具。當您的卷積神經網絡在驗證集上表現良好時,它同樣會很大可能對將要提交的測試數據也表現良好。
FastAI中有一種稱為split_by_rand_pct的便捷方法,可將部分數據拆分為驗證數據。
它還具有databunch方法來執行批處理。我的batch值設置為64,因為受限於我的GPU限制。
然後,調用normalize方法來標準化您的圖像,因為您將使用預訓練的網絡。imagenet_stats將根據ImageNet競賽預訓練的網絡來對圖像標準化。
將測試數據添加到訓練圖像列表使得以後可以輕鬆預測而無需更多預處理。請記住,這些圖像不會受到訓練,也不會進行驗證。這裡只是讓測試圖片以與訓練圖像時相同的方式預處理數據而已。
transform方法中的參數值將對輸入圖片進行放大縮小,以匹配您將使用的神經網絡。我將使用的網絡名為DenseNet,它在ImageNet 2017上獲得了最佳論文獎,它需要128×128像素的圖像。
learn = cnn_learner(train_img, models.densenet161, metrics=[error_rate, accuracy])
您已完成訓練數據準備郭稱。現在,使用cnn_learner創建一個訓練方法。正如我之前所說,我將使用DenseNet作為預先訓練的網絡。您也可以使用TorchVision中提供的其他網絡。
單周期技術
你現在就可以開始訓練了。但是,在訓練包括卷積神經網絡在內的任何深度神經網絡時,你肯定會為一件事情感到困惑。那就是選擇正確的學習率。該算法稱為Gradient Descent,它將使用稱為學習率的一個參數來嘗試減少誤差。
更大的學習速率能夠使訓練步驟更快,但它更容易超越邊界。這使得錯誤可能像上左圖一樣失去控制。較小的學習速率雖然會使訓練步驟變慢,但它不容易失控。
因此,選擇正確的學習率非常重要。使它足夠大而不會失控。
說起來容易做起來難。
為此,有一個名叫Leslie Smith的人創造了一種稱為1-cycle policy的技術。
直覺上,您可能希望找到一個幾乎沒有錯誤的學習速率,哪怕存在一些改進空間也沒關係。我們在代碼中嘗試一下。
learn.lr_find() learn.recorder.plot()
它會列印出這樣的東西:
最小值大概為10^(-1)。所以,我覺得我們可以使用比這更小的值,不過也不能太小。也許3 * 10^ (- 2)是個不錯的選擇。我們來試試吧!
lr = 3e-02 learn.fit_one_cycle(5, slice(lr))
嘗試訓練幾步看看(我選擇step值5,不要太大也不要太小),讓我們看看結果。
納尼?
我們的簡單解決方案在我們分割預留的驗證集上得到了100%的準確性!它實際上是有效的。它只需要六分鐘的訓練。運氣也太好了!在現實生活中,您將進行多次迭代,以找出哪些算法比其他算法做得更好。
我已經迫不及待想要提交了!哈哈。讓我們預測下測試集,並提交結果。
preds,_ = learn.get_preds(ds_type=DatasetType.Test) test_df.has_cactus = preds.numpy()[:, 0]
由於您已將測試圖像放在訓練圖像列表中,因此無需預處理和加載測試集。
test_df.to_csv('submission.csv', index=False)
此行將創建一個包含圖像名稱的CSV文件,包含4,000個測試圖像的仙人掌列。
當我嘗試提交時,我才意識到我需要通過Kaggle內核提交CSV。我錯過了。
但是,幸運的是,Kaggle內核實際上與你的jupyter notebook相同。您可以複製粘貼筆notebook中的所有內容並在那裡提交。
bang!!!
我得到0.9999。這非常好。但是,當然,如果我的第一次嘗試是這樣的話,我想得到一個完美的分數。
所以,我在網絡上做了幾次調整,再一次,BAM!
我做到了,你也可以,事實上也沒有想像中的那麼難。
我學到的是
這個問題很容易。因此,在解決這個項目的問題時,您不會遇到任何奇怪的挑戰。這也是我稱它為最適合的項目之一。
當然,另外一方面來說,由於這個項目實在太簡單了,以至於很多人在這項目中得了滿分,我認為kaggle管理員有必要需要創建另一個提交測試集。一個更難的測試集。。
當然不管是什麼原因,我都建議您立即嘗試這個項目並獲得良好的成績。
最後的想法
卷積神經網絡對各種任務非常有用。從圖像識別到生成圖像。現在分析圖像並不像以前那麼難。當然,如果你嘗試,你也可以這樣做。
剛開始,儘量選擇一個有不錯數據集的好的卷積神經網絡項目,以便開個好頭。
祝好運!
整篇文章翻譯下來,感覺對老手幫助不是很大,哎