干貨深入理解神經網絡(深度神經網絡通俗理解)

      網友投稿 1226 2022-05-30

      本文將介紹用于解決實際問題的深度學習架構的不同模塊。前一章使用PyTorch的低級操作構建了如網絡架構、損失函數和優化器這些模塊。本章將介紹用于解決真實問題的神經網絡的一些重要組件,以及PyTorch如何通過提供大量高級函數來抽象出復雜度。本章還將介紹用于解決真實問題的算法,如回歸、二分類、多類別分類等。

      本文將討論如下主題:

      詳解神經網絡的不同構成組件;

      探究PyTorch中用于構建深度學習架構的高級功能;

      應用深度學習解決實際的圖像分類問題。

      1 詳解神經網絡的組成部分

      上一章已經介紹了訓練深度學習算法需要的幾個步驟。

      1.構建數據管道。

      2.構建網絡架構。

      3.使用損失函數評估架構。

      4.使用優化算法優化網絡架構的權重。

      上一章中的網絡由使用PyTorch數值運算構建的簡單線性模型組成。盡管使用數值運算為玩具性質的問題搭建神經架構很簡單,但當需要構建解決不同領域的復雜問題時,如計算機視覺和自然語言處理,構建一個架構就迅速變得復雜起來。大多數深度學習框架,如PyTorch、TensorFlow和Apache MXNet,都提供了抽象出很多復雜度的高級功能。這些深度學習框架的高級功能稱為層(layer)。它們接收輸入數據,進行如同在前面一章看到的各種變換,并輸出數據。解決真實問題的深度學習架構通常由1~150個層組成,有時甚至更多。抽象出低層的運算并訓練深度學習算法的過程如圖3.1所示。

      圖3.1

      1.1 層——神經網絡的基本組成

      在本章的剩余部分,我們會見到各種不同類型的層。首先,先了解其中最重要的一種層:線性層,它就是我們前面講過的網絡層結構。線性層應用了線性變換:

      {-:-}Y

      =Wx

      +b

      線性層之所以強大,是因為前一章所講的功能都可以寫成單一的代碼行,如下所示。

      from torch.nn import Linear

      myLayer = Linear(in_features=10,out_features=5,bias=True)

      上述代碼中的myLayer層,接受大小為10的張量作為輸入,并在應用線性變換后輸出一個大小為5的張量。下面是一個簡單例子的實現:

      可以使用屬性weights和bias訪問層的可訓練參數:

      線性層在不同的框架中使用的名稱有所不同,有的稱為dense層,有的稱為全連接層(fully connected layer)。用于解決真實問題的深度學習架構通常包含不止一個層。在PyTorch中,可以用多種方式實現。

      一個簡單的方法是把一層的輸出傳入給另一層:

      inp = Variable(torch.randn(1,10))

      myLayer = Linear(in_features=10,out_features=5,bias=True)

      myLayer(inp)

      每一層都有自己的學習參數,在多個層的架構中,每層都學習出它本層一定的模式,其后的層將基于前一層學習出的模式構建。把線性層簡單堆疊在一起是有問題的,因為它們不能學習到簡單線性表示以外的新東西。我們通過一個簡單的例子看一下,為什么把線性層堆疊在一起的做法并不合理。

      假設有具有如下權重的兩個線性層:

      以上包含兩個不同層的架構可以簡單表示為帶有另一不同層的單層。因此,只是堆疊多個線性層并不能幫助我們的算法學習任何新東西。有時,這可能不太容易理解,我們可以用下面的數學公式對架構進行可視化:

      {-:-}Y

      = 2(3X

      1

      ) -2?Linear layers

      {-:-}Y

      = 6(X

      1

      ) -1?Linear layers

      為解決這一問題,相較于只是專注于線性關系,我們可以使用不同的非線性函數,幫助學習不同的關系。

      深度學習中有很多不同的非線性函數。PyTorch以層的形式提供了這些非線性功能,因為可以采用線性層中相同的方式使用它們。

      一些流行的非線性函數如下所示:

      sigmoid

      tanh

      ReLU

      Leaky ReLU

      1.2 非線性激活函數

      非線性激活函數是獲取輸入,并對其應用數學變換從而生成輸出的函數。我們在實戰中可能遇到數個非線性操作。下面會講解其中幾個常用的非線性激活函數。

      sigmoid激活函數的數學定義很簡單,如下:

      ![\sigma \left ( x \right )=1/\left ( 1+e^{-x} \right )](http://latex.codecogs.com/gif.latex?\sigma%20\left%20(%20x%20\right%20%29=1/\left%20(%201+e^{-x}%20\right%20%29)

      簡單來說,sigmoid函數以實數作為輸入,并以一個0到1之間的數值作為輸出。對于一個極大的負值,它返回的值接近于0,而對于一個極大的正值,它返回的值接近于1。圖3.2所示為sigmoid函數不同的輸出。

      圖3.2

      sigmoid函數曾一度被不同的架構使用,但由于存在一個主要弊端,因此最近已經不太常用了。當sigmoid函數的輸出值接近于0或1時,sigmoid函數前一層的梯度接近于0,由于前一層的學習參數的梯度接近于0,使得權重不能經常調整,從而產生了無效神經元。

      非線性函數tanh將實數值輸出為-1到1之間的值。當tanh的輸出極值接近-1和1時,也面臨梯度飽和的問題。不過,因為tanh的輸出是以0為中心的,所以比sigmoid更受偏愛,如圖3.3所示。

      圖3.3

      近年來ReLU變得很受歡迎,我們幾乎可以在任意的現代架構中找到ReLU或其某一變體的身影。它的數學公式很簡單:

      {-:-}f(x)=max(0,x)

      簡單來說,ReLU把所有負值取作0,正值保持不變??梢詫eLU函數進行可視化,如圖3.4所示。

      圖3.4

      使用ReLU函數的一些好處和弊端如下。

      有助于優化器更快地找到正確的權重集合。從技術上講,它使隨機梯度下降收斂得更快。

      計算成本低,因為只是判斷了閾值,并未計算任何類似于sigmoid或tangent函數計算的內容。

      ReLU有一個缺點,即當一個很大的梯度進行反向傳播時,流經的神經元經常會變得無效,這些神經元稱為無效神經元,可以通過謹慎選擇學習率來控制。我們將在第4章中討論調整學習率的不同方式時,了解如何選擇學習率。

      Leaky ReLU嘗試解決一個問題死角,它不再將飽和度置為0,而是設為一個非常小的數值,如0.001。對某些用例,這一激活函數提供了相較于其他激活函數更優異的性能,但它不是連續的。

      1.3 PyTorch中的非線性激活函數

      PyTorch已為我們實現了大多數常用的非線性激活函數,我們可以像使用任何其他的層那樣使用它們。讓我們快速看一個在PyTorch中使用ReLU激活函數的例子:

      在上面這個例子中,輸入是包含兩個正值、兩個負值的張量,對其調用ReLU函數,負值將取為0,正值則保持不變。

      現在我們已經了解了構建神經網絡架構的大部分細節,我們來構建一個可用于解決真實問題的深度學習架構。上一章中,我們使用了簡單的方法,因而可以只關注深度學習算法如何工作。后面將不再使用這種方式構建架構,而是使用PyTorch中正常該用的方式構建。

      PyTorch中所有網絡都實現為類,創建PyTorch類的子類要調用nn.Module,并實現__init__和forward方法。在init方法中初始化層,這一點已在前一節講過。在forward方法中,把輸入數據傳給init方法中初始化的層,并返回最終的輸出。非線性函數經常被forward函數直接使用,init方法也會使用一些。下面的代碼片段展示了深度學習架構是如何用PyTrorch實現的:

      如果你是Python新手,上述代碼可能會比較難懂,但它全部要做的就是繼承一個父類,并實現父類中的兩個方法。在Python中,我們通過將父類的名字作為參數傳入來創建子類。init方法相當于Python中的構造器,super方法用于將子類的參數傳給父類,我們的例子中父類就是nn.Module。

      待解決的問題種類將基本決定我們將要使用的層,處理序列化數據問題的模型從線性層開始,一直到長短期記憶(LSTM)層?;谝鉀Q的問題類別,最后一層是確定的。使用機器學習或深度學習算法解決的問題通常有三類,最后一層的情況通常如下。

      對于回歸問題,如預測T恤衫的銷售價格,最后使用的是有一個輸出的線性層,輸出值為連續的。

      將一張給定的圖片歸類為T恤衫或襯衫,用到的是sigmoid激活函數,因為它的輸出值不是接近1就是接近0,這種問題通常稱為二分類問題。

      對于多類別分類問題,如必須把給定的圖片歸類為T恤、牛仔褲、襯衫或連衣裙,網絡最后將使用softmax層。讓我們拋開數學原理來直觀理解softmax的作用。舉例來說,它從前一線性層獲取輸入,并輸出給定數量樣例上的概率。在我們的例子中,將訓練它預測每個圖片類別的4種概率。記住,所有概率相加的總和必然為1。

      干貨|深入理解神經網絡(深度神經網絡通俗理解)

      一旦定義好了網絡架構,還剩下最重要的兩步。一步是評估網絡執行特定的回歸或分類任務時表現的優異程度,另一步是優化權重。

      優化器(梯度下降)通常接受一個標量值,因而loss函數應生成一個標量值,并使其在訓練期間最小化。某些用例,如預測道路上障礙物的位置并判斷是否為行人,將需要兩個或更多損失函數。即使在這樣的場景下,我們也需要把損失組合成一個優化器可以最小化的標量。最后一章將詳細討論把多個損失值組合成一個標量的真實例子。

      上一章中,我們定義了自己的loss函數。PyTorch提供了經常使用的loss函數的實現。我們看看回歸和分類問題的loss函數。

      回歸問題經常使用的loss函數是均方誤差(MSE)。它和前面一章實現的loss函數相同??梢允褂肞yTorch中實現的loss函數,如下所示:

      對于分類問題,我們使用交叉熵損失函數。在介紹交叉熵的數學原理之前,先了解下交叉熵損失函數做的事情。它計算用于預測概率的分類網絡的損失值,損失總和應為1,就像softmax層一樣。當預測概率相對正確概率發散時,交叉熵損失增加。例如,如果我們的分類算法對圖3.5為貓的預測概率值為0.1,而實際上這是只熊貓,那么交叉熵損失就會更高。如果預測的結果和真實標簽相近,那么交叉熵損失就會更低。

      圖3.5

      下面是用Python代碼實現這種場景的例子。

      為了在分類問題中使用交叉熵損失,我們真的不需要擔心內部發生的事情——只要記住,預測差時損失值高,預測好時損失值低。PyTorch提供了loss函數的實現,可以按照如下方式使用。

      PyTorch包含的其他一些loss函數如表3.1所示。

      表3.1

      計算出網絡的損失值后,需要優化權重以減少損失,并改善算法準確率。簡單起見,讓我們看看作為黑盒的優化器,它們接受損失函數和所有的學習參數,并微量調整來改善網絡性能。PyTorch提供了深度學習中經常用到的大多數優化器。如果大家想研究這些優化器內部的動作,了解其數學原理,強烈建議瀏覽以下博客:

      http://colah.github.io/posts/2015-08-Backprop/

      PyTorch提供的一些常用的優化器如下:

      ADADELTA

      Adagrad

      Adam

      SparseAdam

      Adamax

      ASGD

      LBFGS

      RMSProp

      Rprop

      SGD

      第4章中將介紹更多算法細節,以及一些優勢和折中方案考慮。讓我們看看創建任意optimizer的一些重要步驟:

      optimizer = optim.SGD(model.parameters(), lr = 0.01)

      在上面的例子中,創建了SGD優化器,它把網絡的所有學習參數作為第一個參數,另外一個參數是學習率,學習率決定了多大比例的變化調整可以作用于學習參數。第4章將深入學習率和動量(momentum)的更多細節,它們是優化器的重要參數。創建了優化器對象后,需要在循環中調用zero_grad()方法,以避免參數把上一次optimizer調用時創建的梯度累加到一起:

      再一次調用loss函數的backward方法,計算梯度值(學習參數需要改變的量),然后調用optimizer.step()方法,用于真正改變調整學習參數。

      現在已經講述了幫助計算機識別圖像所需要的大多數組件。我們來構建一個可以區分狗和貓的復雜深度學習模型,以將學到的內容用于實踐。

      1.4 使用深度學習進行圖像分類

      解決任何真實問題的重要一步是獲取數據。Kaggle提供了大量不同數據科學問題的競賽。我們將挑選一個2014年提出的問題,然后使用這個問題測試本章的深度學習算法,并在第5章中進行改進,我們將基于卷積神經網絡(CNN)和一些可以使用的高級技術來改善圖像識別模型的性能。大家可以從https://www.kaggle.com/c/dogs-vs-cats/data下載數據。數據集包含25,000張貓和狗的圖片。在實現算法前,預處理數據,并對訓練、驗證和測試數據集進行劃分是需要執行的重要步驟。數據下載完成后,可以看到對應數據文件夾包含了如圖3.6所示的圖片。

      圖3.6

      當以圖3.7所示的格式提供數據時,大多數框架能夠更容易地讀取圖片并為它們設置標簽的附注。也就是說每個類別應該有其所包含圖片的獨立文件夾。這里,所有貓的圖片都應位于cat文件夾,所有狗的圖片都應位于dog文件夾。

      圖3.7

      Python可以很容易地將數據調整成需要的格式。請先快速瀏覽一下代碼,然后,我們將講述重要的部分。

      上述代碼所做的處理,就是獲取所有圖片文件,并挑選出2,000張用于創建驗證數據集。它把圖片劃分到了cats和dogs這兩個類別目錄中。創建獨立的驗證集是通用的重要實踐,因為在相同的用于訓練的數據集上測試算法并不合理。為了創建validation數據集,我們創建了一個圖片數量長度范圍內的數字列表,并把圖像無序排列。在創建validation數據集時,我們可使用無序排列的數據來挑選一組圖像。讓我們詳細解釋一下每段代碼。

      下面的代碼用于創建文件:

      files = glob(os.path.join(path,'*/*.jpg'))

      glob方法返回特定路徑的所有文件。當圖片數量巨大時,也可以使用iglob,它返回一個迭代器,而不是將文件名載入到內存中。在我們的例子中,只有25,000個文件名,可以很容易加載到內存里。

      可以使用下面的代碼混合排列文件:

      shuffle?=?np.random.permutation(no_of_images)

      上述代碼返回25,000個0~25,000范圍內的無序排列的數字,可以把其作為選擇圖片子集的索引,用于創建validation數據集。

      可以創建驗證代碼,如下所示:

      上述代碼創建了validation文件夾,并在train和valid目錄里創建了對應的類別文件夾(cats和dogs)。

      可以用下面的代碼對索引進行無序排列:

      在上面的代碼中,我們使用無序排列后的索引隨機抽出2000張不同的圖片作為驗證集。同樣地,我們把訓練數據用到的圖片劃分到train目錄。

      現在已經得到了需要格式的數據,我們來快速看一下如何把圖片加載成PyTorch張量。

      PyTorch的torchvision.datasets包提供了一個名為ImageFolder的工具類,當數據以前面提到的格式呈現時,它可以用于加載圖片以及相應的標簽。通常需要進行下面的預處理步驟。

      1.把所有圖片轉換成同等大小。大多數深度學習架構都期望圖片具有相同的尺寸。

      2.用數據集的均值和標準差把數據集歸一化。

      3.把圖片數據集轉換成PyTorch張量。

      PyTorch在transforms模塊中提供了很多工具函數,從而簡化了這些預處理步驟。例如,進行如下3種變換:

      調整成256 ×256大小的圖片;

      轉換成PyTorch張量;

      歸一化數據(第5章將探討如何獲得均值和標準差)。

      下面的代碼演示了如何使用ImageFolder類進行變換和加載圖片:

      train對象為數據集保留了所有的圖片和相應的標簽。它包含兩個重要屬性:一個給出了類別和相應數據集索引的映射;另一個給出了類別列表。

      把加載到張量中的數據可視化往往是一個最佳實踐。為了可視化張量,必須對張量再次變形并將值反歸一化。下面的函數實現了這樣的功能:

      現在,可以把張量傳入前面的imshow函數,將張量轉換成圖片:

      imshow(train[50][0])

      上述代碼生成的輸出如圖3.8所示。

      圖3.8

      在深度學習或機器學習中把圖片進行批取樣是一個通用實踐,因為當今的圖形處理器(GPU)和CPU都為批量圖片的操作進行了優化。批尺寸根據我們使用的GPU種類而不同。每個GPU都有自己的內存,可能從2GB到12GB不等,有時商業GPU內存會更大。PyTorch提供了DataLoader類,它輸入數據集將返回批圖片。它抽象出了批處理的很多復雜度,如應用變換時的多worker的使用。下面的代碼把前面的train和valid數據集轉換到數據加載器(data loader)中:

      DataLoader類提供了很多選項,其中最常使用的選項如下。

      shuffle:為true時,每次調用數據加載器時都混合排列圖片。

      num_workers:負責并發。使用少于機器內核數量的worker是一個通用的實踐。

      對于大多的真實用例,特別是在計算機視覺中,我們很少構建自己的架構。可以使用已有的不同架構快速解決我們的真實問題。在我們的例子中,使用了流行的名為ResNet的深度學習算法,它在2015年贏得了不同競賽的冠軍,如與計算機視覺相關的ImageNet。為了更容易理解,我們假設算法是一些仔細連接在一起的不同的PyTorch層,并不關注算法的內部。在第5章學習卷積神經網絡(CNN)時,我們將看到一些關鍵的ResNet算法的構造塊。PyTorch通過torchvision.models模塊提供的現成應用使得用戶更容易使用這樣的流行算法。因而,對于本例,我們快速看一下如何使用算法,然后再詳解每行代碼:

      models.resnet18(pertrained = True)對象創建了算法的實例,實例是PyTorch層的集合。我們打印出model_ft,快速地看一看哪些東西構成了ResNet算法。算法的一小部分看起來如圖3.9所示。這里沒有包含整個算法,因為這很可能會占用幾頁內容。

      圖3.9

      可以看出,ResNet架構是一個層的集合,包含的層為Conv2d、BatchNorm2d和?MaxPool2d,這些層以一種特有的方式組合在一起。所有這些算法都將接受一個名為pretrained的參數。當pretrained為True時,算法的權重已為特定的ImageNet分類問題微調好。ImageNet預測的類別有1000種,包括汽車、船、魚、貓和狗等。訓練該算法,使其預測1000種ImageNet類別,權重調整到某一點,讓算法得到最高的準確率。我們為用例使用這些保存好并與模型共享的權重。與以隨機權重開始的情況相比,算法以微調好的權重開始時會趨向于工作得更好。因而,我們的用例將從預訓練好的權重開始。

      ResNet算法不能直接使用,因為它是用來預測1,000種類別,而對于我們的用例,僅需預測貓和狗這兩種類別。為此,我們拿到ResNet模型的最后一層——linear層,并把輸出特征改成2,如下面的代碼所示:

      model_ft.fc?=?nn.Linear(num_ftrs,?2)

      如果在基于GPU的機器上運行算法,需要在模型上調用cuda方法,讓算法在GPU上運行。強烈建議在裝備了GPU的機器上運行這些算法;有了GPU后,用很少的錢就可以擴展出一個云實例。下面代碼片段的最后一行告知PyTorch在GPU上運行代碼:

      if?is_cuda: ????model_ft?=?model_ft.cuda()

      前一節中,我們已經創建了DataLoader實例和算法?,F在訓練模型。為此我們需要loss函數和optimizer:

      在上述代碼中,創建了基于CrossEntropyLoss的loss函數和基于SGD的優化器。StepLR函數幫助動態修改學習率。第4章將討論用于調優學習率的不同策略。

      下面的train_model函數獲取模型輸入,并通過多輪訓練調優算法的權重降低損失:

      上述函數的功能如下。

      1.傳入流經模型的圖片并計算損失。

      2.在訓練階段反向傳播。在驗證/測試階段,不調整權重。

      3.每輪訓練中的損失值跨批次累加。

      4.存儲最優模型并打印驗證準確率。

      上面的模型在運行25輪后,驗證準確率達到了87%。下面是前面的train_model函數在Dogs vs. Cats數據集上訓練時生成的日志;為了節省篇幅,本書只包含了最后幾輪的結果。

      接下來的章節中,我們將學習可以以更快的方式訓練更高準確率模型的高級技術。前面的模型在Titan X GPU上運行了30分鐘的時間,后面將講述有助于更快訓練模型的不同技術。

      2 小結

      本章通過使用SGD優化器調整層權重,講解了PyTorch中神經網絡的全生命周期——從構成不同類型的層,到加入激活函數、計算交叉熵損失,再到優化網絡性能(即最小化損失)。

      本章還介紹了如何應用流行的ResNet架構解決二分類和多類別分類問題。

      同時,我們嘗試解決了真實的圖像分類問題,把貓的圖片歸類為cat,把狗的圖片歸類為dog。這些知識可以用于對不同的實體進行分類,如辨別魚的種類,識別狗的品種,劃分植物種子,將***癌歸類成Type1、Type2和Type3型等。

      本文摘自《PyTorch深度學習》

      譯者:王海玲, 劉江峰

      本書在不深入數學細節的條件下,給出了多個先進深度學習架構的直觀解釋,如ResNet、DenseNet、Inception和Seq2Seq等,也講解了如何進行遷移學習,如何使用預計算特征加速遷移學習,以及如何使用詞向量、預訓練的詞向量、LSTM和一維卷積進行文本分類。

      閱讀完本書后,讀者將會成為一個熟練的深度學習人才,能夠利用學習到的不同技術解決業務問題。

      本文轉載自異步社區

      高性能計算 人工智能

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:excel取消表格分頁符的方法教程(Excel表格取消分頁符)
      下一篇:探索CPU的調度原理(CPU的調度)
      相關文章
      亚洲av无码成人精品区一本二本| 国产偷窥女洗浴在线观看亚洲| 亚洲?v无码国产在丝袜线观看| 亚洲人成77777在线播放网站不卡| 中文字幕中韩乱码亚洲大片| 亚洲av无码乱码在线观看野外 | 亚洲精品第一国产综合野| 久久久影院亚洲精品| 亚洲国产精品成人久久| 亚洲精品卡2卡3卡4卡5卡区| 亚洲中文字幕无码永久在线| 亚洲日韩精品一区二区三区 | 亚洲区小说区图片区QVOD| 中文字幕亚洲乱码熟女一区二区| 久久精品国产精品亚洲| 亚洲无码精品浪潮| 中文字幕亚洲一区二区三区| 亚洲精品国产成人片| 亚洲成AV人在线观看天堂无码| 亚洲热线99精品视频| 亚洲情综合五月天| 亚洲精品成人av在线| 亚洲网址在线观看| 亚洲精品在线电影| 亚洲一级免费毛片| 亚洲色丰满少妇高潮18p| 久久亚洲中文字幕无码| av在线亚洲欧洲日产一区二区| 亚洲色欲一区二区三区在线观看| 亚洲精品无码久久千人斩| 亚洲av无码一区二区三区不卡| 亚洲男人第一av网站| 亚洲人成电影网站| 亚洲日韩精品无码专区加勒比| 国产成人人综合亚洲欧美丁香花 | 亚洲成年人啊啊aa在线观看| 亚洲视频在线一区二区| 亚洲AV永久无码精品水牛影视| 337p欧洲亚洲大胆艺术| 亚洲最大中文字幕无码网站| 色欲aⅴ亚洲情无码AV蜜桃|