一窥深度学习黑箱,拼接深层神经网络架构
在本文開始之前墻裂建議大家回顧下之前的文章,以便新老朋友絲滑入戲😼。
1. 一文參透神經網絡及其實現,揭開深度學習的神秘面紗
2. 由回歸到分類,繼續探尋神經網絡的美妙
本文概覽
在之前的兩篇文章中我們學習了簡單的單層神經網絡,實現了線性回歸、邏輯回歸和softmax回歸,已經可以解決一些簡單的回歸問題和分類問題,但是對于復雜問題的求解,單層神經網絡的性能是不夠的🙃,今天我們就一起來學習一下深層神經網絡又有哪些獨到之處。與以往一樣,我們還是順著技術的發展去講解,了解整個過程的來龍去脈。
簡單網絡對于簡單數據的處理是沒問題的,但是如今數據量爆炸的年代,解決實際問題僅靠簡單神經網絡卻是杯水車薪。比如說識別一張喵的照片😾
假設我們把圖片中的像素值視為特征,就算這張圖片是50×50的小圖片,也會存在著2500個特征,將這些特征與對應的權重相乘形成多項式,又是一個非常復雜的工作,更不用說再加上激活函數了,這時就需要更深層的神經網絡。有了技術限制就會有技術發展,行則將至,接下來我們一起來探索深度神經網絡。
1. 由單層到深層
1.1 邏輯與(AND)
同樣的,我們先挑單層神經網絡的毛病,之前我們實現的神經網絡給的數據都是同一組,也就是“邏輯與”數據。現在我們深入了解一下該數據。
| ?? | ???? | y_and | 
| 0 | 0 | 0 | 
| 0 | 1 | 0 | 
| 1 | 0 | 0 | 
| 1 | 1 | 1 | 
我們使用這組數據構建了二分類神經網絡,輸出的預測值與給出的真實值y_and相同,那么我們就認為這個分類的神經網絡起了作用。它是怎么實現分類的呢?我們知道分類就是將一堆數據分開嘛🦕,最簡單的就是將互不相干的兩類數據用一條直線將其劃分開。其實我們從中學就學會了這件事情,對于上面的數據,在分類之前我們要考慮一下怎么去可視化。
中學我們學習過y=ax+b這種簡單的一元函數,還記得當時怎么在紙上畫出來它的圖形嗎?現在讓我們換一個高級一點的說法,還記得當時怎么做的數據可視化嗎👀?我們將變量x作為橫軸,變量y作為縱軸,通過描點連線作出圖像表示,這便是將x和y進行了可視化。如法炮制,“邏輯與”數據中有兩個特征 x1,x2,我們將這兩個特征進行可視化,那么形成的式子就是x1 = ax2+ b
 ,其中a是權重,b是偏置。如此一來就將特征 的分布呈現在圖形之上。這一步可以用python中的matploitlib包實現非常簡單,在這里我就直接給出手繪圖像
可以看到根據標簽的不同,將特征點分為不同的顏色,紅色的點的坐標為(1,1),對應的標簽為1,因此兩類數據呈現在圖像之上。我們可以很輕松的找到一條直線將兩類數據劃分開,如圖所示
圖中這條紫色的直線就可以將兩類數據區分開,這條直線就叫做決策邊界(decision boundary)。這條直線的表達式為w1x1+w2x2+b=0w_1x_1+w_2x_2+b=0w1?x1?+w2?x2?+b=0 ,也就是之前我們提到過的累加求和的式子,我們用z來表示,即為 z=w1x1+w2x2+bz={w}_{1}{x}_{1}+{w}_{2}{x}_{2}+bz=w1?x1?+w2?x2?+b 令 x0 = 1,w0 = b , 就又變成了我們非常熟悉的一般表達式z=w0x0+w1x1+w2x2z={w}_{0}{{x}_{0}+w}_{1}{x}_{1}+{w}_{2}{x}_{2}z=w0?x0?+w1?x1?+w2?x2?
 通過上面的分析可以看的出,在相同特征的情況下,決策邊界由權重w所決定。所以說,權重就是神經網絡最后自己學習出來的,當學習到很好的權重參數,再進行計算的時候就可以得到一個很好的準確度。
與門結構
1.2 邏輯或(OR)
對“邏輯與”數據可視化后,我們將同樣的操作換到“邏輯或”數據上。
| ?? | ???? | y_or | 
| 0 | 0 | 0 | 
| 0 | 1 | 1 | 
| 1 | 0 | 1 | 
| 1 | 1 | 1 | 
邏輯或即有1則1,全0才0。我們繼續將其可視化,如圖
通過圖像可以看的出,對于”邏輯或“數據而言,我們也可以輕易的找到一條決策邊界將其進行二分類。
或門結構
1.3 邏輯與非(NAND)
“邏輯與非” 是"與門"和"非門"的疊加,先進行"與"運算,再進行"非"運算,有多個輸入和一個輸出。下面給出"與非門"的數據
| ?? | ???? | y_nand | 
| 0 | 0 | 1 | 
| 0 | 1 | 1 | 
| 1 | 0 | 1 | 
| 1 | 1 | 0 | 
將其可視化
下面給出與非門的網絡結構
1.4 邏輯異或(XOR)
上面的幾個邏輯運算我們可以很簡單的去找到決策邊界,那么接下來我們來看這么一組數據,異或門數據,異或運算是相同為0,不同為1。
| ?? | ???? | y_xor | 
| 0 | 0 | 0 | 
| 0 | 1 | 1 | 
| 1 | 0 | 1 | 
| 1 | 1 | 0 | 
同樣的,我們對這組數據進行可視化
好像有些問題,由上圖可以看出,之前可以用一條直線簡單的分開數據的方式在這里行不通了,那么大家思考一下對于這個異或門數據,它的決策邊界怎么畫呢?這種難以用直線分開的數據才是我們常見的數據,這也是單層神經網絡的局限性所在。有了問題就會有解決辦法,直線不能劃分那我們可以用曲線🌙。如圖
異或門數據的決策邊界是一條曲線,這條曲線就可以很好的劃分出兩類數據,但是單層神經網絡是實現不了曲線的決策邊界,為了解決這個問題,我們可以在神經網絡上疊加層來實現,也就有了深層神經網絡。
2. 拼湊深層神經網絡
2.1 疊加層解決異或問題
我們先來看一下異或運算的邏輯推導式
XNOR = ( x1 NAND x2 ) AND ( x1 OR x2 )從該推導式我們可以看到,邏輯異或可以由邏輯與非、邏輯或和邏輯與三種運算推導得出,那么我們嘗試去一步步拼湊該公式。首先是先構造一個“與非網絡”,然后再構造一個“或網絡”,這樣得到的兩個神經網絡作為“與網絡”的兩個輸入。根據上文中給出的網絡結構圖,可以得到
這便形成了一個多層神經網絡😉,圖中不同顏色代表了異或計算中的小網絡,小網絡之間互相連接,構成一個多層的神經網絡,將本來只能計算直線邊界的功能拓展到計算曲線邊界。由簡單到復雜,由單層到多層,可以看到簡單層的累積形成的復雜網絡就能實現很多難處理的功能,當然再加上各種激活函數會使模型變得更加復雜,一般認為越復雜的神經網絡其解決問題的能力也就越強, 相信大家在看完前兩篇文章之后再到這里應該能輕松的理解深層神經網絡。
我們將上圖一般化,就可以得到常見的神經網絡架構圖
2.2 異或網絡架構里的細節
在這個深層神經網絡中,三種邏輯運算就相當于激活函數,可以看得出除輸入層以外的層,每個神經元都接收的的是上一層的神經元和它們之間權重矩陣的累加求和,即z=w1x1+w2x2+bz={w}_{1}{x}_{1}+{w}_{2}{x}_{2}+bz=w1?x1?+w2?x2?+b 。得到的加權求和的值作為激活函數的輸入,即a(z)a(z)a(z) ,這里我們假設a是激活函數的函數名,這樣就做了一個運算,使得輸入加權求和后得到另外一個值 aia_iai? 。現在讓我們遮住左半部分再來看一下
如果只關注右半部分,這就和我們之前提到的單層神經網絡一樣,只不過這里的輸入特征不是 x1,x2x_1,x_2x1?,x2?了,而是變成了經過激活函數處理過的a1,a2a_1,a_2a1?,a2?和固定的偏置項b ,我們可以把現在的輸入a1,a2a_1,a_2a1?,a2? 看作 x1,x2x_1,x_2x1?,x2? 的變體,按照這個邏輯再去看隱藏層到輸出層的部分就非常的清晰明了,復雜網絡的內部結構都是相同的,但是奈于參數的隨機性和體量問題,我們沒有辦法去完全的理解深層神經網絡,這也是深度學習的黑盒問題的原因所在?。
3. 從頭搭建深層神經網絡
3.1 Pytorch實現
通過上文的分析我們可以知道,對于輸入層以外的所有層,每一個輸出都是由上一層的所有特征決定的(這里我們暫且叫特征,但是你明白的),這樣從左到右,學習我們給出的訓練集的算法就被稱為前向傳播(Forward Propagation)。那么我們就來簡單的去實現這個深層網絡的前向傳播算法。
同樣的我們給出一些簡單數據,我們準備300個樣本,每個樣本有10個特征,這300個樣本共有3種類別。現在給出神經網絡的架構,假設輸入層有8個神經元,隱藏層有6個神經元,輸出層有1個神經元,我們使用sigmoid、ReLU和softmax激活函數。現在讓我們一起來實現這個三層神經網絡吧。
網絡結構如圖所示,這種簡單的神經網絡其含有的參數量也是很多的,如果不借助深度學習框架,難以想象其中的復雜度
pytorch代碼實現
'''1.導包''' import torch import torch.nn as nn from torch.nn import functional as F'''2.生成數據''' torch.manual_seed(55) X = torch.rand((300,10),dtype=torch.float32) # 生成訓練數據 y = torch.randint(0, 3, size=(300,1)) # 生成 0,1,2 標簽'''3.定義神經網絡''' class DeepNN(nn.Module):def __init__(self,in_features,out_features):super(DeepNN,self).__init__()self.linear1 = nn.Linear(in_features, 8) # 定義網絡結構self.linear2 = nn.Linear(8, 6)self.linear3 = nn.Linear(6, out_features)def forward(self, X):a1 = torch.relu(self.linear1(X)) # z1 = self.linear1(X) 加權求和a2 = torch.sigmoid(self.linear2(a1)) # z2 = self.linear2(a1)a3 = F.softmax(self.linear3(a2),dim=1) # z3 = self.linear3(a2)return a3'''4.實例化''' model = DeepNN(10, 3)'''5.前向傳播''' model(X)上面就是整個深層神經網絡前向傳播的實現代碼,其中前向傳播之后會生成(300,3)的數據,即300個樣本分別被分為3類的概率值。
在jupyter lab 中運行如下
查看輸出結果的大小,如圖
如果我們取出概率最大的類別作為當前樣本的最終分類,那么每一個樣本都會預測出來對應的類別,有了預測值和真實值,就可以去計算預測的是否正確,其中的差值稱之為損失loss,將這個loss降到最低,得到的模型參數就是比較好的參數,也就能得到一個好的模型。
如何降低loss,這就會引出梯度下降法(Gradient Descent)和大名鼎鼎的反向傳播(BP,Backpropagation),限于篇幅,本文暫時不先介紹。
以上就是本文的全部內容了,希望能給到你一點點幫助,DDL就是第一生產力?。
分享知識,記錄生活,一起進步。
總結
以上是生活随笔為你收集整理的一窥深度学习黑箱,拼接深层神经网络架构的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 阈值法matlab程序,遗传算法优化BP
- 下一篇: LCD屏幕的面板构造
