DenseNet論文翻譯及pytorch實現解析(上)

前言

  1. 文章較長,建議先碼後看;
  2. 資歷尚淺,覺得翻譯不當的已在文後括弧註明原文,望知友指正。

摘要

最近的研究表明,如果在靠近輸入層與輸出層之間的地方使用短連接(shorter connections),就可以訓練更深、更準確、更有效的卷積網路。在這篇文章中,我們基於這個觀點,介紹了稠密卷積網路(DenseNet),該網路在前饋時將每一層都與其他的任一層進行了連接。傳統的 L 層卷積網路有 L 個連接——每一層與它的前一層和後一層相連——我們的網路有 L(L+1)/2 個連接。每一層都將之前的所有層的特徵圖作為輸入,而它自己的特徵圖是之後所有層的輸入。DenseNets有一些很不錯的優點:有助於解決梯度消失問題,有利於特徵傳播,鼓勵特徵的重複利用,還可以減少參數量。我們在四個目標檢測任務(CIFAR-10,CIFAR-100,SVHN和ImageNet)中驗證了我們提出了結構。DenseNets在這些數據集上大都有較大的提高,而且使用更少的計算量就可以獲得更好的性能。

1. 介紹

在視覺檢測任務中,卷積神經網路(CNNs)已經成為佔有絕對優勢的機器學習方法。儘管它們在20年前就已經被提出來,但是計算機硬體和網路結構的改善才使訓練深層的卷積網路在最近成為現實。起初的LeNet5有5層,VGG有19層,只有去年的Highway網路和ResNets網路才克服了100層網路的障礙。

隨著CNNs變得越來越深,一個新的問題出現了:當輸入或梯度信息在經過很多層的傳遞之後,在到達網路的最後(或開始)可能會消失或者「被沖刷掉」(wash out)。很多最新的研究都說明了這個或者與這個相關的問題。ResNets網路和Highway網路將旁路信息(bypass signal)進行連接。隨機深度(stochastic depth)在訓練過程中隨機丟掉一些層,進而縮短了ResNets網路,獲得了更好的信息和梯度流。FractalNets使用不同數量的卷積block來重複的連接一些平行層,獲得更深的網路同時還保留了網路中的short paths。儘管這些方法在網路結構和訓練方法等方面有所不同,但它們都有一個關鍵點:它們都在前幾層和後幾層之間產生了短路徑(short paths)。

在這篇文章中,我們提出了一個結構,該結構是提煉上述觀點而形成的一種簡單的連接模式:為了保證能夠獲得網路層之間的最大信息,我們將所有層(使用合適的特徵圖尺寸)都進行互相連接。為了能夠保證前饋的特性,每一層將之前所有層的輸入進行拼接,之後將輸出的特徵圖傳遞給之後的所有層。結構如圖1所示。

重要的一點,與ResNets不同的是,我們不是在特徵傳遞給某一層之前將其進行相加(combine),而是將其進行拼接(concatenate)。因此,第 l 層有 l 個輸入,這些輸入是該層之前的所有卷積塊(block)的特徵圖,而它自己的特徵圖則傳遞給之後的所有 L-l 層。這就表示,一個 L 層的網路就有 L(L+1)/2 個連接,而不是像傳統的結構僅僅有 L 個連接。由於它的稠密連接模塊,所以我們更喜歡把這個方法稱為稠密卷積網路(DenseNets)。

該稠密連接模塊的一個優點是它比傳統的卷積網路有更少的參數,因為它不需要再重新學習多餘的特徵圖。傳統的前饋結構可以被看成一種層與層之間狀態傳遞的演算法。每一層接收前一層的狀態,然後將新的狀態傳遞給下一層。它改變了狀態,但也傳遞了需要保留的信息。ResNets將這種信息保留的更明顯,因為它加入了本身的變換(identity transformations)。最近很多關於ResNets的研究都表明ResNets的很多層是幾乎沒有起作用的,可以在訓練時隨機的丟掉。這篇論文[21]闡述了ResNets很像(展開的)循環神經網路,但是比循環神經網路有更多的參數,因為它每一層都有自己的權重。我們提出的DenseNet結構,增加到網路中的信息與保留的信息有著明顯的不同。DenseNet層很窄(例如每一層有12個濾波器),僅僅增加小數量的特徵圖到網路的「集體知識」(collective knowledge),並且保持這些特徵圖不變——最後的分類器基於網路中的所有特徵圖進行預測。

除了具有更好的參數利用率,DenseNets還有一個優點是它改善了網路中信息和梯度的傳遞,這就讓網路更容易訓練。每一層都可以直接利用損失函數的梯度以及最開始的輸入信息,相當於是一種隱形的深度監督(implicit deep supervision)。這有助於訓練更深的網路。此外,我們還發現稠密連接有正則化的作用,在更少訓練集的任務中可以降低過擬合。

我們在四個目標檢測任務(CIFAR-10,CIFAR-100,SVHN和ImageNet)中驗證了DenseNets。在和現有模型有相似準確率的前提下,我們的模型有更少的參數。此外,我們的網路還超過了目前在大部分的檢測任務都有最好結果的演算法。

2. 相關工作

自從神經網路被提出之後,網路結構的探索就成為了神經網路研究的一部分。最近神經網路的廣泛關注也給這個研究領域注入了新的生機。網路層數的增加也讓更多的人進行結構的改善、不同連接模式的探索、早期研究觀點的復現等方面的研究。

在1980s神經網路論文中提出的級聯結構很像我們提出的稠密網路。他們之前的工作主要關注在全連接的多層感知機上。最近,使用批梯度下降訓練的全連接的級聯網路也被提出來了。儘管在小數據集上有效,但該方法的網路卻有幾百個參數。[9,23,30,40]提出在CNNs中利用跨層連接獲得的多種特徵,這已經被證明在很多視覺任務上有效。和我們的工作類似,[1]使用和我們相似的跨層連接方式提出了一種純理論的網路框架。

HighWay是這些網路中第一個提出使用100多層的結構訓練一個端到端的網路。使用旁路(bypassing paths)和門控單元(gating units),HighWay網路可以很輕鬆的優化上百層的網路。旁路被認為是使深層網路容易訓練關鍵因素。該觀點在ResNets中被進一步證實,ResNets使用本身的特徵圖作為旁路。ResNets在很多圖像識別、定位和檢測任務(如ImageNet和COCO目標檢測)中都獲得了不錯的效果,並且還打破了之前的記錄。最近,一種可以成功訓練1202層ResNet的隨機深度(stochastic depth)被提出。隨機深度通過在訓練過程中隨機丟掉一些層來優化深度殘差網路的訓練過程。這表明深度(殘差)網路中並不是所有的層都是必要的,有很多層是冗餘的。我們論文的一部分就受到了該結論的啟發。預激活(pre-activation)的ResNets也有助於訓練超過1000層的網路。

一種讓網路更深(如跨層連接)的正交法(orthogonal approach)是增加網路的寬度。GooLeNet使用了「inception」模塊,將不同尺寸的濾波器產生的特徵進行組合連接。在[37]中,提出一種具有廣泛寬度的殘差模塊,它是ResNets的一種變形。事實上,只簡單的增加ResNets每一層的濾波器個數就可以提升網路的性能。FractalNets使用一個寬的網路結構在一些數據集上也獲得了不錯的效果。

DenseNets不是通過很深或者很寬的網路來獲得表徵能力,而是通過特徵的重複使用來利用網路的隱含信息,獲得更容易訓練、參數效率更高的稠密模型。將不同層學到的特徵圖進行組合連接,增加了之後層輸入的多樣性,提升了性能。這同時也指出了DenseNets和ResNets之間的主要差異。儘管inception網路也組合連接了不同層的特徵,但DenseNets更簡單,也更高效。

也有很多著名的網路結構獲得了不錯的結果。NIN結構將多層感知機與卷積層的濾波器相連來提取更複雜的特徵。在DSN中,通過輔助分類器來監督內部層,加強了前幾層的梯度。Ladder網路將橫向連接(lateral connection)引入到自編碼器中,在半監督學習任務中獲得不錯的效果。在[38]中,DFNs通過連接不同基礎網路的中間層來改善信息的傳遞。帶有可以最小化重建損失路徑(pathways that minimize reconstruction losses)的網路也可以改善圖像分類模型的性能。

3. DenseNets

假設一張圖片 x_{0}^{} 在卷積網路中傳播。網路共有 L 層,每一層都有一個非線性轉換 H_{l}left( cdot 
ight) ,其中 l 表示層的維度(即第幾層)。 H_{l}left( cdot 
ight) 是一個組合函數,有BN、ReLU、池化或卷積。我們用 x_{l} 表示 l^{th} 層的輸出。

ResNets。傳統的前饋網路是將 l^{th} 層的輸出作為 left( l+1 
ight)^{th} 層的輸入,可用該方程來表示: x_{l}=H_{l}left( x_{l-1} 
ight) 。ResNets增加了一個跨層連接,將自身與非線性轉換的結果相加:

ResNets的一個優點是可以直接將梯度從後層傳向前層。然而,自身與經過 H_{l} 得到的輸出是通過求和的形式來連接的,這可能使網路中信息的傳播受到影響。

稠密連接。為了更好的改善層與層之間信息的傳遞,我們提出一種不同的連接模式:將該層與之後的所有層進行連接,如圖1所示。因此, l^{th} 層將之前所有層的特徵圖 x_{0},...,x_{l-1} 作為輸入:

其中 [x_{0},...,x_{l-1}] 表示第 0,...,l-1 層輸出的特徵圖的進行拼接。由於它的稠密連接模式,我們稱該網路結構為稠密卷積網路(DenseNet)。為了便於表達,我們把方程(2)中 H_{l}left( cdot 
ight) 的多個輸入表示為一個向量。

組合函數。受[12]的啟發,我們將 H_{l}left( cdot 
ight) 定義為三種操作的組合函數,分別是:BN、ReLU和3x3卷積。

池化層。當特徵圖的尺寸改變時,方程(2)中連接操作就會出現問題。然而,卷積網路有一個基礎的部分——下採樣層,它可以改變特徵圖的尺寸。為了便於下採樣的實現,我們將網路劃分為多個稠密連接的dense block,如圖2所示。

我們將每個block之間的層稱為過渡層,完成卷積和池化的操作。在我們的實驗中,過渡層由BN層、1x1卷積層和2x2平均池化層組成。

增長速率(growth rate)。如果每個函數 H_{l} 都產生 k 個特徵圖,之後的 l^{th} 層就有 k_{0}+k	imes(l-1) 個特徵圖作為輸入,其中 k_{0} 表示該層的通道數。DenseNet和現存網路結構的一個很重要的不同是,DenseNet的網路很窄,如 k=12 。我們將超參數 k 稱為網路的增長速率。我們會在文章的第4部分進行說明,一個很小的增長速率在我們測試的數據集上就可以獲得不錯的效果。這種情況的一種解釋是,每一層都可以和它所在的block中之前的所有特徵圖進行連接,使得網路具有了「集體知識」(collective knowledge)。可以將特徵圖看作是網路的全局狀態。每一層相當於是對當前狀態增加 k 個特徵圖。增長速率控制著每一層有多少信息對全局狀態有效。全局狀態一旦被寫定,就可以在網路中的任何地方被調用,而不用像傳統的網路結構那樣層與層之間的不斷重複。

Bottleneck層。儘管每一層只產生 k 個輸出特徵圖,但它卻有更多的輸入。在[36,11]中已經說明可以在bottleneck層中3x3的卷積之前加入1x1的卷積實現降維,可以減小計算量。我們發現這種設計對DenseNet極其有效,我們將具有bottleneck層,即BN-ReLU-Conv(1x1)-BN-ReLU-Conv(3x3)的結構稱為DenseNet-B。在我們的實驗中,我們令1x1的卷積生成 4k 個特徵圖。

Compression。為了簡化模型,我們在過渡層中減小了特徵圖的數量。如果一個dense block有 m 個特徵圖,我們讓之後的過渡層生成 	heta m 個輸出特徵圖,其中 0< 	heta leq1 表示compression係數。當 	heta = 1 時,經過過渡層的特徵圖數量沒有改變。我們定義 	heta <1 的DenseNet為DenseNet-C,並且在我們的實驗中 	heta = 0.5 。如果bottleneck和過渡層都有 	heta < 1 ,我們稱該模型為DenseNet-BC。

實現細節。在除了ImageNet外的所有數據集上,我們實驗中使用的DenseNet都有三個dense block,每一個block都有相同的層數。在進入第一個dense block之前,輸入圖像先經過了16個(DenseNet-BC中是兩倍的增長速率)卷積。對於3x3的卷積層,使用一個像素的零填充來保證特徵圖尺寸不變。在兩個dense block之間的過渡層中,我們在2x2的平均池化層之後增加了1x1的卷積。在最後一個dense block之後,使用全局平均池化和softmax分類器。三個dense block的特徵圖的尺寸分別是32x32,16x16,8x8。我們改變一些參數 left{L = 40, k = 12 
ight} left{L = 100, k = 12 
ight} left{L = 100, k = 24 
ight} ,在基本的DenseNet上做了一些實驗。對於DenseNet-BC,分別設置 left{L = 100, k = 12 
ight} left{L =250 , k = 24 
ight} left{L = 190, k = 40 
ight}

對於在ImageNet數據集上的實驗,我們使用4個dense block的DenseNet-BC結構,圖片的輸入是224x224。最開始的卷積層有 2k (64)個卷積,卷積核是7x7,步長是2;其餘所有層的特徵圖都設為 k 。在ImageNet數據集上的網路如表1所示。

4. 實驗

我們在一些檢測任務的數據集上證明DenseNet的有效性,並且和現有的一些網路進行了對比,特別是ResNet和它的變形。

4.1 數據集

CIFAR。兩種CIFAR數據集都是32x32的彩色圖。CIFAR-10(C10)是10類,CIFAR-100(C100)是100類。訓練集和測試集分別有50000和10000張圖片,我們從訓練集中選5000張作為驗證集。我們採用在這兩個數據集上廣泛使用的數據增強方式(鏡像/平移)。用在數據集後的「+」來表示使用了這種數據增強方式(如C10+)。至於預處理,我們使用每個顏色通道的均值和標準差來歸一化。最後,我們使用全部的50000張訓練圖片,在訓練結束時記錄測試誤差。

SVHN。SVHN數據集是32x32的彩色數字圖。訓練集有73257張圖片,測試集有26032張,有531131張作為額外的訓練。在接下來實驗中,我們沒有使用任何的數據增強,從訓練集中選取6000張圖片作為驗證集。我們用驗證集誤差最小的模型來進行測試。我們對像素值執行除255操作,歸一化到[0,1]。

ImageNet。ILSVARC 2012分類數據集有1.2百萬張訓練集,50000張驗證集,共1000類。我們採用和論文[8,11,12]同樣的數據增強方式,在測試時使用single-crop或10-crop將圖片尺寸變為224x224。根據[11,12,13],我們記錄了在驗證集上的分類誤差。

4.2 訓練

所有的網路均使用隨機梯度下降法(SGD)進行訓練。在CIFAR和SVHN數據上,我們令 batch size = 64 ,分別訓練了300輪和40輪。最初的學習率都為0.1,分別在訓練總輪數的50%和75%時,將學習率變為原來的0.1倍。在ImageNet上,我們將模型訓練了90輪, batch size = 256 。初始學習率設為0.1,在第30輪和第40輪分別將學習率縮小10倍。受GPU內存的限制,我們設最大的模型(DenseNet-161) batch size=128 。為了彌補小batch size的不足,我們將模型訓練了100輪,並且在90輪時將學習率除以10。

根據[8],我們設置梯度衰減值為10e-4,Nesterov動量設為0.9。我們採用論文[10]中介紹的權重初始化方式。對於三種沒有使用數據增強的數據,如C10、C100和SVHN,我們在每個卷積層(除了第一層)之後增加了一層dropout層,並且設置失活率為0.2。對每個任務和每個模型都只進行一次測試。

4.3 在CIFAR和SVHN上的分類結果

我們使用不同的深度( L )、不同的增長速率( k ),來分別訓練DenseNets。在CIFAR和SVHN上的結果如表2所示。為了突出結果,我們對其做了標記,將性能優於現存模型的結果加粗,將該數據集上的最好結果用藍色標註。

準確率。可能最惹人注目的是表2最後一行的結果,其是 L=190、k=40 的DenseNet-BC網路在CIFAR上的結果,性能已超過現存的所有模型。在C10+上錯誤率為3.46%,在C100+上的錯誤率為17.18%。在C100+上的誤差率遠低於寬ResNet(wide ResNet)網路。我們在C10和C100(無數據增強)上的誤差很喜人:比FractalNet和使用dropout正則項的結果低了接近30%。在SVHN上, L=100、k=24 的DenseNet(使用dropout)也遠超寬ResNet的最好結果。然而,250層的DenseNet-BC的性能卻沒有提升太多。這可能是因為SVHN的任務很簡單,複雜的模型往往會導致過擬合。

容量(capacity)。不考慮compression或bottleneck層, Lk 越大,模型性能越好。我們把這歸功於模型容量的增加。這在C10+和C100+這兩列中得到了很好的證明。在C10+這列,誤差率從5.24%降到了4.10%,最後到了3.74%,因為模型的參數量從1M增加到7M,最後到了27.2M。在C100+這列,我們可以看到相似的結果。這表明DenseNets可以使用更大更深的模型來增加表徵能力,也表明它們沒有出現過擬合或者殘差網路的優化困難等問題。

參數效率。表2的結果表明DenseNets比常見的網路(特別是ResNets)的參數效率更高。使用bottleneck結構並且在過渡層使用降維操作的DenseNet-BC的參數利用率極其高。例如,我們的250層模型只有15.3M的參數量,但是它的性能卻遠超其他參數量超過30M的模型,像FractalNet和寬ResNets。我們也將 L=100、k=12 的DenseNet-BC性能與1001層pre-activation的ResNet 進行了比較(如,在C10+的誤差 4.51%vs4.62%,在C100+的誤差:22.27%vs22.71%)。這兩個網路在C10+數據上的訓練loss和測試誤差如圖4(右圖)。1001層的深度ResNet收斂到一個更低的loss,但卻有相似的測試誤差。我們會在接下來對這個內容做更深入的探討。

擬合能力。更高效利用參數的一個作用是DenseNets不易發生過擬合。在不使用數據增強的數據集上,我們發現到DenseNet結構和之前的工作相比較,其改進還是很明顯的。在C10上,誤差降了29%,從7.33%降到了5.19%。在C100上,降了大約30%,從28.2%降到了19.64%。通過實驗,我們發現一個潛在的過擬合現象:在C10上,通過將 k 從12增加到24,模型的參數量增加了4倍,而誤差卻從5.77%增加到5.83%。DenseNet-BC的bottleneck和compression層似乎是應對這種現象的一種有效措施。

4.4 ImageNet分類結果

我們在ImageNet分類任務上測試了不同深度和增長速率的DenseNet-BC的誤差,並且和ResNet結構的性能進行了比較。為了對這兩種結構有一個公平的比較,我們排除了其他所有的因素,如數據預處理方式、優化器設置。我們僅僅將DenseNet-BC網路替代ResNet模型,而保留ResNet的其他實驗參數不變。

我們記錄了DenseNets在ImageNet上single-crop和10-crop的驗證誤差,如表3所示。

DenseNets和ResNets single-crop的top-1驗證誤差如圖3所示,其中左圖以參數量為變數,右圖以flops為變數。

如圖3所示,與ResNets相比,在相同性能的前提下DenseNets參數量和計算量更小。例如,擁有20M參數的DenseNet-201的誤差率和擁有超過40M參數的101-ResNet誤差率相近。從圖3的右圖也可以看到類似的結果:和ResNet-50計算量接近的DenseNet大約是ResNet-101計算量的兩倍。

值得注意的是,我們是修改和ResNets對應的超參數而不是DenseNets的。我們相信還可以通過修改更多的超參數來優化DenseNet在ImageNet上的性能。

5. 討論

從表面來看,DenseNets和ResNets很像:方程(2)和方程(1)的不同主要在輸入 H_{l}left( cdot 
ight) (進行拼接而不是求和)。然而,這個小的改變卻給這兩種網路結構的性能帶來了很大的差異。

模型簡化性(compactness)。將輸入進行連接的直接結果是,DenseNets每一層學到的特徵圖都可以被以後的任一層利用。該方式有助於網路特徵的重複利用,也因此得到了更簡化的模型。

圖4左邊的兩張圖展示了實驗的結果,左圖比較了所有DenseNets的參數效率,中圖對DenseNts和ResNets的參數效率進行了比較。我們在C10+數據上訓練了不同深度的多個小模型,並繪製出準確率。和一些流行的網路(如AlwxNet、VGG)相比,pre-activation的ResNets的準確率明顯高於其他網路。之後,我們將DenseNet( k=12 )與該網路進行了比較。DenseNet的訓練集同上節。

如圖4,DenseNet-BC是參數效率最高的一個DenseNet版本。此外,DenseNet-BC僅僅用了大概ResNets 1/3的參數量就獲得了相近的準確率(中圖)。該結果與圖3的結果相一致。如圖4右圖,僅有0.8M參數量的DenseNet-BC和有10.2M參數的101-ResNet準確率相近。

隱含的深度監督(implicit deep supervision)。稠密卷積網路可以提升準確率的一個解釋是,由於更短的連接,每一層都可以從損失函數中獲得監督信息。可以將DenseNets理解為一種「深度監督」(deep supervision)。深度監督的好處已經在之前的深度監督網路(DSN)中說明,該網路在每一隱含層都加了分類器,迫使中間層也學習判斷特徵(discriminative features)。

DensNets和深度監督網路相似:網路最後的分類器通過最多兩個或三個過渡層為所有層都提供監督信息。然而,DenseNets的損失函數值和梯度不是很複雜,這是因為所有層之間共享了損失函數。

隨機vs確定連接。稠密卷積網路與殘差網路的隨機深度正則化(stochastic depth

regularzation)之間有著有趣的關係。在隨機深度中,殘差網路隨機丟掉一些層,直接將周圍的層進行連接。因為池化層沒有丟掉,所以該網路和DenseNet有著相似的連接模式:以一定的小概率對相同池化層之間的任意兩層進行直接連接——如果中間層隨機丟掉的話。儘管這兩個方法在根本上是完全不一樣的,但是DenseNet關於隨機深度的解釋會給該正則化的成功提供依據。

特徵重複利用。根據設計來看,DenseNets允許每一層獲得之前所有層(儘管一些是通過過渡層)的特徵圖。我們做了一個實驗來判斷是否訓練的網路可以重複利用這個機會。我們首先在C10+數據上訓練了 L=40、k=12 的DenseNet。對於每個block的每個卷積層 l ,我們計算其與 s 層連接的平均權重。三個dense block的熱度圖如圖5所示。

平均權重表示卷積層與它之前層的依賴關係。位置 (l,s) 處的一個紅點表示層 l 充分利用了前 s 層產生的特徵圖。由圖可以得出以下結論:

  1. 在同一個block中,所有層都將它的權重傳遞給其他層作為輸入。這表明早期層提取的特徵可以被同一個dense block下深層所利用;
  2. 過渡層的權重也可以傳遞給之前dense block的所有層,也就是說DenseNet的信息可以以很少的間接方式從第一層流向最後一層;
  3. 第二個和第三個dense block內的所有層分配最少的權重給過渡層的輸出,表明過渡層輸出很多冗餘特徵。這和DenseNet-BC強大的結果有關係;
  4. 儘管最後的分類器也使用通過整個dense block的權重,但似乎更關注最後的特徵圖,表明網路的最後也會產生一些高層次的特徵。

6. 結論

我們提出了一個新的卷積網路結構,稱之為稠密卷積網路(DenseNet)。它將兩個相同特徵圖尺寸的任意層進行連接。這樣我們就可以很自然的設計上百層的網路,還不會出現優化困難的問題。在我們的實驗中,隨著參數量的增加,DenseNets的準確率也隨之提高,而且也沒有出現較差表現或過擬合的現象。通過超參數的調整,該結構在很多比賽的數據上都獲得了不錯的結果。此外,DenseNets有更少的參數和計算量。因為我們只是在實驗中調整了對於殘差網路的超參數,所以我們相信通過調整更多的超參數和學習率,DenseNets的準確率還會有更大的提升。

遵循這個簡單的連接規則,DenseNets可以很自然的將自身映射(identity mappings)、深度監督(deep supervision)和深度多樣化(diversified depth)結合在一起。根據我們的實驗來看,該結構通過對網路特徵的重複利用,可以學習到更簡單、準確率更高的模型。由於簡化了內部表徵和降低了特徵冗餘,DenseNets可能是目前計算機視覺領域中在卷積網路方面非常不錯的特徵提取器。在以後的工作中我們計劃研究DenseNets下的特徵遷移工作。


後記:

  1. densenet論文;
  2. 當然densenet被人詬病說內存消耗多,另有對其進行改進版本,抽空也可總結下。

推薦閱讀:

【筆記】Finding Tiny Faces
PyTorch中如何使用tensorboard可視化
深度學習入門該用PyTorch還是Keras?熱門公開課換框架背後的學問
python3.6.1及TensorFlow和PyTorch
知乎「看山杯」 奪冠記

TAG:深度学习DeepLearning | 卷积神经网络CNN | PyTorch |