『壹』 BP人工神經網路方法
(一)方法原理
人工神經網路是由大量的類似人腦神經元的簡單處理單元廣泛地相互連接而成的復雜的網路系統。理論和實踐表明,在信息處理方面,神經網路方法比傳統模式識別方法更具有優勢。人工神經元是神經網路的基本處理單元,其接收的信息為x1,x2,…,xn,而ωij表示第i個神經元到第j個神經元的連接強度或稱權重。神經元的輸入是接收信息X=(x1,x2,…,xn)與權重W={ωij}的點積,將輸入與設定的某一閾值作比較,再經過某種神經元激活函數f的作用,便得到該神經元的輸出Oi。常見的激活函數為Sigmoid型。人工神經元的輸入與輸出的關系為
地球物理勘探概論
式中:xi為第i個輸入元素,即n維輸入矢量X的第i個分量;ωi為第i個輸入與處理單元間的互聯權重;θ為處理單元的內部閾值;y為處理單元的輸出。
常用的人工神經網路是BP網路,它由輸入層、隱含層和輸出層三部分組成。BP演算法是一種有監督的模式識別方法,包括學習和識別兩部分,其中學習過程又可分為正向傳播和反向傳播兩部分。正向傳播開始時,對所有的連接權值置隨機數作為初值,選取模式集的任一模式作為輸入,轉向隱含層處理,並在輸出層得到該模式對應的輸出值。每一層神經元狀態隻影響下一層神經元狀態。此時,輸出值一般與期望值存在較大的誤差,需要通過誤差反向傳遞過程,計算模式的各層神經元權值的變化量
(二)BP神經網路計算步驟
(1)初始化連接權值和閾值為一小的隨機值,即W(0)=任意值,θ(0)=任意值。
(2)輸入一個樣本X。
(3)正向傳播,計算實際輸出,即根據輸入樣本值、互聯權值和閾值,計算樣本的實際輸出。其中輸入層的輸出等於輸入樣本值,隱含層和輸出層的輸入為
地球物理勘探概論
輸出為
地球物理勘探概論
式中:f為閾值邏輯函數,一般取Sigmoid函數,即
地球物理勘探概論
式中:θj表示閾值或偏置;θ0的作用是調節Sigmoid函數的形狀。較小的θ0將使Sigmoid函數逼近於閾值邏輯單元的特徵,較大的θ0將導致Sigmoid函數變平緩,一般取θ0=1。
(4)計算實際輸出與理想輸出的誤差
地球物理勘探概論
式中:tpk為理想輸出;Opk為實際輸出;p為樣本號;k為輸出節點號。
(5)誤差反向傳播,修改權值
地球物理勘探概論
式中:
地球物理勘探概論
地球物理勘探概論
(6)判斷收斂。若誤差小於給定值,則結束,否則轉向步驟(2)。
(三)塔北雅克拉地區BP神經網路預測實例
以塔北雅克拉地區S4井為已知樣本,取氧化還原電位,放射性元素Rn、Th、Tc、U、K和地震反射
S4井位於測區西南部5線25點,是區內唯一已知井。該井在5390.6m的侏羅系地層獲得40.6m厚的油氣層,在5482m深的震旦系地層中獲58m厚的油氣層。取S4井周圍9個點,即4~6線的23~25 點作為已知油氣的訓練樣本;由於區內沒有未見油的鑽井,只好根據地質資料分析,選取14~16線的55~57點作為非油氣的訓練樣本。BP網路學習迭代17174次,總誤差為0.0001,學習效果相當滿意。以學習後的網路進行識別,得出結果如圖6-2-4所示。
圖6-2-4 塔北雅克拉地區BP神經網路聚類結果
(據劉天佑等,1997)
由圖6-2-4可見,由預測值大於0.9可得5個大封閉圈遠景區,其中測區南部①號遠景區對應著已知油井S4井;②、③號油氣遠景區位於地震勘探所查明的托庫1、2號構造,該兩個構造位於沙雅隆起的東段,其西段即為1984年鑽遇高產油氣流的Sch2井,應是含油氣性好的遠景區;④、⑤號遠景區位於大澇壩構造,是yh油田的組成部分。
『貳』 如何從零使用 Keras + TensorFlow 開發一個復雜深度學習模型
Keras 是提供一些高可用的 Python API ,能幫助你快速的構建和訓練自己的深度學習模型,它的後端是 TensorFlow 或者 Theano 。本文假設你已經熟悉了 TensorFlow 和卷積神經網路,如果,你還沒有熟悉,那麼可以先看看這個10分鍾入門 TensorFlow 教程和卷積神經網路教程,然後再回來閱讀這個文章。
在這個教程中,我們將學習以下幾個方面:
為什麼選擇 Keras?為什麼 Keras 被認為是深度學習的未來?
在Ubuntu上面一步一步安裝Keras。
Keras TensorFlow教程:Keras基礎知識。
了解 Keras 序列模型
4.1 實際例子講解線性回歸問題
使用 Keras 保存和回復預訓練的模型
Keras API
6.1 使用Keras API開發VGG卷積神經網路
6.2 使用Keras API構建並運行SqueezeNet卷積神經網路。
『叄』 求PSO—BP神經網路訓練方法,matlab實現的
輸入層、隱層的神經元激勵函數選為S型函數,輸出層採用線性函數purelin。各層的節點數分別為3、10、2,訓練步數選為1500次。在Matlab中進行BP神經網路的建立、訓練、模擬,結果如下:
T=[0.23 0.23];目標輸出值
P=[-04953 -0.4915 ;0.4889 0.6160; 0.3708 0.4535]; 輸入矩陣三行兩列
net=newff(minmax(P),[5,12,1],{'tansig','tansig','purelin'},'traingd');網路建立、訓練
net.trainParam.epochs=1500;訓練步數
net.trainParam.goal=0.00001;均方誤差
[net,tr]=train(net,P,T);進行訓練
y=sim(net,P)輸出的結果
『肆』 從零開始用Python構建神經網路
從零開始用Python構建神經網路
動機:為了更加深入的理解深度學習,我們將使用 python 語言從頭搭建一個神經網路,而不是使用像 Tensorflow 那樣的封裝好的框架。我認為理解神經網路的內部工作原理,對數據科學家來說至關重要。
這篇文章的內容是我的所學,希望也能對你有所幫助。
神經網路是什麼?
介紹神經網路的文章大多數都會將它和大腦進行類比。如果你沒有深入研究過大腦與神經網路的類比,那麼將神經網路解釋為一種將給定輸入映射為期望輸出的數學關系會更容易理解。
神經網路包括以下組成部分
? 一個輸入層,x
? 任意數量的隱藏層
? 一個輸出層,?
? 每層之間有一組權值和偏置,W and b
? 為隱藏層選擇一種激活函數,σ。在教程中我們使用 Sigmoid 激活函數
下圖展示了 2 層神經網路的結構(注意:我們在計算網路層數時通常排除輸入層)
2 層神經網路的結構
用 Python 可以很容易的構建神經網路類
訓練神經網路
這個網路的輸出 ? 為:
你可能會注意到,在上面的等式中,輸出 ? 是 W 和 b 函數。
因此 W 和 b 的值影響預測的准確率. 所以根據輸入數據對 W 和 b 調優的過程就被成為訓練神經網路。
每步訓練迭代包含以下兩個部分:
? 計算預測結果 ?,這一步稱為前向傳播
? 更新 W 和 b,,這一步成為反向傳播
下面的順序圖展示了這個過程:
前向傳播
正如我們在上圖中看到的,前向傳播只是簡單的計算。對於一個基本的 2 層網路來說,它的輸出是這樣的:
我們在 NeuralNetwork 類中增加一個計算前向傳播的函數。為了簡單起見我們假設偏置 b 為0:
但是我們還需要一個方法來評估預測結果的好壞(即預測值和真實值的誤差)。這就要用到損失函數。
損失函數
常用的損失函數有很多種,根據模型的需求來選擇。在本教程中,我們使用誤差平方和作為損失函數。
誤差平方和是求每個預測值和真實值之間的誤差再求和,這個誤差是他們的差值求平方以便我們觀察誤差的絕對值。
訓練的目標是找到一組 W 和 b,使得損失函數最好小,也即預測值和真實值之間的距離最小。
反向傳播
我們已經度量出了預測的誤差(損失),現在需要找到一種方法來傳播誤差,並以此更新權值和偏置。
為了知道如何適當的調整權值和偏置,我們需要知道損失函數對權值 W 和偏置 b 的導數。
回想微積分中的概念,函數的導數就是函數的斜率。
梯度下降法
如果我們已經求出了導數,我們就可以通過增加或減少導數值來更新權值 W 和偏置 b(參考上圖)。這種方式被稱為梯度下降法。
但是我們不能直接計算損失函數對權值和偏置的導數,因為在損失函數的等式中並沒有顯式的包含他們。因此,我們需要運用鏈式求導發在來幫助計算導數。
鏈式法則用於計算損失函數對 W 和 b 的導數。注意,為了簡單起見。我們只展示了假設網路只有 1 層的偏導數。
這雖然很簡陋,但是我們依然能得到想要的結果—損失函數對權值 W 的導數(斜率),因此我們可以相應的調整權值。
現在我們將反向傳播演算法的函數添加到 Python 代碼中
為了更深入的理解微積分原理和反向傳播中的鏈式求導法則,我強烈推薦 3Blue1Brown 的如下教程:
Youtube:https://youtu.be/tIeHLnjs5U8
整合並完成一個實例
既然我們已經有了包括前向傳播和反向傳播的完整 Python 代碼,那麼就將其應用到一個例子上看看它是如何工作的吧。
神經網路可以通過學習得到函數的權重。而我們僅靠觀察是不太可能得到函數的權重的。
讓我們訓練神經網路進行 1500 次迭代,看看會發生什麼。 注意觀察下面每次迭代的損失函數,我們可以清楚地看到損失函數單調遞減到最小值。這與我們之前介紹的梯度下降法一致。
讓我們看看經過 1500 次迭代後的神經網路的最終預測結果:
經過 1500 次迭代訓練後的預測結果
我們成功了!我們應用前向和方向傳播演算法成功的訓練了神經網路並且預測結果收斂於真實值。
注意預測值和真實值之間存在細微的誤差是允許的。這樣可以防止模型過擬合並且使得神經網路對於未知數據有著更強的泛化能力。
下一步是什麼?
幸運的是我們的學習之旅還沒有結束,仍然有很多關於神經網路和深度學習的內容需要學習。例如:
? 除了 Sigmoid 以外,還可以用哪些激活函數
? 在訓練網路的時候應用學習率
? 在面對圖像分類任務的時候使用卷積神經網路
我很快會寫更多關於這個主題的內容,敬請期待!
最後的想法
我自己也從零開始寫了很多神經網路的代碼
雖然可以使用諸如 Tensorflow 和 Keras 這樣的深度學習框架方便的搭建深層網路而不需要完全理解其內部工作原理。但是我覺得對於有追求的數據科學家來說,理解內部原理是非常有益的。
這種練習對我自己來說已成成為重要的時間投入,希望也能對你有所幫助
『伍』 人工智慧時代,神經網路的原理及使用方法 | 微課堂
人工智慧時代已經悄然來臨,在計算機技術高速發展的未來,機器是否能代替人腦?也許有些讀者會說,永遠不可能,因為人腦的思考包含感性邏輯。事實上,神經網路演算法正是在模仿人腦的思考方式。想不想知道神經網路是如何「思考」的呢?下面我向大家簡單介紹一下神經網路的原理及使用方法。
所謂人工智慧,就是讓機器具備人的思維和意識。人工智慧主要有三個學派——行為主義、符號主義和連接主義。
行為主義是基於控制論,是在構建感知動作的控制系統。理解行為主義有個很好的例子,就是讓機器人單腳站立,通過感知要摔倒的方向控制兩只手的動作,保持身體的平衡,這就構建了一個感知動作控制系統。
符號主義是基於算數邏輯和表達式。求解問題時,先把問題描述為表達式,再求解表達式。如果你在求解某個問題時,可以用if case這樣的條件語句,和若干計算公式描述出來,這就使用了符號主義的方法,比如「專家系統」。符號主義可以認為是用公式描述的人工智慧,它讓計算機具備了理性思維。但是人類不僅具備理性思維,還具備無法用公式描述的感性思維。比如,如果你看過這篇推送,下回再見到「符號主義」幾個字,你會覺得眼熟,會想到這是人工智慧相關的知識,這是人的直覺,是感性的。
連接主義就是在模擬人的這種感性思維,是在仿造人腦內的神經元連接關系。這張圖給出了人腦中的一根神經元,左側是神經元的輸入,「軸突」部分是神經元的輸出。人腦就是由860億個這樣的神經元首尾相接組成的網路。
神經網路可以讓計算機具備感性思維。我們首先理解一下基於連接主義的神經網路設計過程。這張圖給出了人類從出生到24個月神經網路的變化:
隨著我們的成長,大量的數據通過視覺、聽覺湧入大腦,使我們的神經網路連接,也就是這些神經元連線上的權重發生了變化,有些線上的權重增強了,有些線上的權重減弱了。
我們要用計算機仿出這些神經網路連接關系,讓計算機具備感性思維。
首先需要准備數據,數據量越大越好,以構成特徵和標簽對。如果想識別貓,就要有大量貓的圖片和這張圖片是貓的標簽構成特徵標簽對,然後搭建神經網路的網路結構,再通過反向傳播優化連接的權重,直到模型的識別准確率達到要求,得到最優的連線權重,把這個模型保存起來。最後用保存的模型輸入從未見過的新數據,它會通過前向傳播輸出概率值,概率值最大的一個就是分類和預測的結果。
我們舉個例子來感受一下神經網路的設計過程。鳶尾花可以分為三類:狗尾鳶尾、雜色鳶尾和佛吉尼亞鳶尾。我們拿出一張圖,需要讓計算機判斷這是哪類鳶尾花。人們通過經驗總結出了規律:通過測量花的花萼長、花萼寬、花瓣長、花瓣寬分辨出鳶尾花的類別,比如花萼長>花萼寬,並且花瓣長/花瓣寬>2,則可以判定為這是第一種,雜色鳶尾。看到這里,也許有些讀者已經想到用if、case這樣的條件語句來實現鳶尾花的分類。沒錯,條件語句根據這些信息可以判斷鳶尾花分類,這是一個非常典型的專家系統,這個過程是理性計算。只要有了這些數據,就可以通過條件判定公式計算出是哪類鳶尾花。但是我們發現鳶尾花的種植者在識別鳶尾花的時候並不需要這么理性的計算,因為他們見識了太多的鳶尾花,一看就知道是哪種,而且隨著經驗的增加,識別的准確率會提高。這就是直覺,是感性思維,也是我們這篇文章想要和大家分享的神經網路方法。
這種神經網路設計過程首先需要採集大量的花萼長、花萼寬、花瓣長、花瓣寬,和它們所對應的是哪種鳶尾花。花萼長、花萼寬、花瓣長、花瓣寬叫做輸入特徵,它們對應的分類叫做標簽。大量的輸入特徵和標簽對構建出數據集,再把這個數據集喂入搭建好的神經網路結構,網路通過反向傳播優化參數,得到模型。當有新的、從未見過的輸入特徵,送入神經網路時,神經網路會輸出識別的結果。
展望21世紀初,在近十年神經網路理論研究趨向的背景下,神經網路理論的主要前沿領域包括:
一、對智能和機器關系問題的認識進一步增長。
研究人類智力一直是科學發展中最有意義,也是空前困難的挑戰性問題。人腦是我們所知道的唯一智能系統,具有感知識別、學習、聯想、記憶、推理等智能。我們通過不斷 探索 人類智能的本質以及聯結機制,並用人工系統復現或部分復現,製造各種智能機器,這樣可使人類有更多的時間和機會從事更為復雜、更富創造性的工作。
神經網路是由大量處理單元組成的非線性、自適應、自組織系統,是在現代神經科學研究成果的基礎上提出的,試圖模擬神經網路加工、記憶信息的方式,設計一種新的機器,使之具有人腦風格的信息處理能力。智能理論所面對的課題來自「環境——問題——目的」,有極大的誘惑力與壓力,它的發展方向將是把基於連接主義的神經網路理論、基於符號主義的人工智慧專家系統理論和基於進化論的人工生命這三大研究領域,在共同追求的總目標下,自發而有機地結合起來。
二、神經計算和進化計算的重大發展。
計算和演算法是人類自古以來十分重視的研究領域,本世紀30年代,符號邏輯方面的研究非常活躍。近年來,神經計算和進化計算領域很活躍,有新的發展動向,在從系統層次向細胞層次轉化里,正在建立數學理論基礎。隨著人們不斷 探索 新的計算和演算法,將推動計算理論向計算智能化方向發展,在21世紀人類將全面進入信息 社會 ,對信息的獲取、處理和傳輸問題,對網路路由優化問題,對數據安全和保密問題等等將有新的要求,這些將成為 社會 運行的首要任務。因此,神經計算和進化計算與高速信息網路理論聯系將更加密切,並在計算機網路領域中發揮巨大的作用,例如大范圍計算機網路的自組織功能實現就要進行進化計算。
人類的思維方式正在轉變,從線性思維轉到非線性思維神經元,神經網路都有非線性、非局域性、非定常性、非凸性和混沌等特性。我們在計算智能的層次上研究非線性動力系統、混沌神經網路以及對神經網路的數理研究,進一步研究自適應性子波、非線性神經場的興奮模式、神經集團的宏觀力學等。因為,非線性問題的研究是神經網路理論發展的一個最大動力,也是它面臨的最大挑戰。
以上就是有關神經網路的相關內容,希望能為讀者帶來幫助。
以上內容由蘇州空天信息研究院謝雨宏提供。
『陸』 如何用代碼編寫一個神經網路異或運算器
配置環境、安裝合適的庫、下載數據集……有時候學習深度學習的前期工作很讓人沮喪,如果只是為了試試現在人人都談的深度學習,做這些麻煩事似乎很不值當。但好在我們也有一些更簡單的方法可以體驗深度學習。近日,編程學習平台 Scrimba 聯合創始人 Per Harald Borgen 在 Medium 上發文介紹了一種僅用30行 JavaScript 代碼就創建出了一個神經網路的教程,而且使用的工具也只有 Node.js、Synaptic.js 和瀏覽器而已。另外,作者還做了一個互動式 Scrimba 教程,也許能幫你理解其中的復雜概念。
Synaptic.js:http://synaptic.juancazala.com
Node.js:http://nodejs.org
Scrimba 教程:http://scrimba.com/casts/cast-1980
Synaptic.js 讓你可以使用 Node.js 和瀏覽器做深度學習。在這篇文章中,我將介紹如何使用 Synaptic.js 創建和訓練神經網路。
//創建網路const { Layer, Network }= window.synaptic;var inputLayer = new Layer(2);var hiddenLayer = new Layer(3);var outputLayer = new Layer(1);
inputLayer.project(hiddenLayer);
hiddenLayer.project(outputLayer);var myNetwork = new Network({
input: inputLayer,
hidden:[hiddenLayer],
output: outputLayer
});//訓練網路——學習異或運算var learningRate =.3;for (var i =0; i <20000; i++)
{//0,0=>0
myNetwork.activate([0,0]);
myNetwork.propagate(learningRate,[0]);//0,1=>1
myNetwork.activate([0,1]);
myNetwork.propagate(learningRate,[1]);//1,0=>1
myNetwork.activate([1,0]);
myNetwork.propagate(learningRate,[1]);//1,1=>0
myNetwork.activate([1,1]);
myNetwork.propagate(learningRate,[0]);
}//測試網路console.log(myNetwork.activate([0,0]));//[0.0]console.log(myNetwork.activate([0,1]));//[0.]console.log(myNetwork.activate([1,0]));//[0.]console.log(myNetwork.activate([1,1]));//[0.0]
我們將創建一個最簡單的神經網路:一個可以執行異或運算的網路。上面就是這個網路的全部代碼,但在我們深入解讀這些代碼之前,首先我們先了解一下神經網路的基礎知識。
神經元和突觸
神經網路的基本構造模塊是神經元。神經元就像是一個函數,有幾個輸入,然後可以得到一個輸出。神經元的種類有很多。我們的網路將使用 sigmoid 神經元,它可以輸入任何數字並將其壓縮到0 到1 之間。下圖就是一個 sigmoid 神經元。它的輸入是5,輸出是1。箭頭被稱為突觸,可以將該神經元與網路中的其它層連接到一起。
現在訓練這個網路:
// train the network - learn XORvar learningRate =.3;for (var i =0; i <20000; i++){ //0,0=>0
myNetwork.activate([0,0]);
myNetwork.propagate(learningRate,[0]);//0,1=>1
myNetwork.activate([0,1]);
myNetwork.propagate(learningRate,[1]);//1,0=>1
myNetwork.activate([1,0]);
myNetwork.propagate(learningRate,[1]);//1,1=>0
myNetwork.activate([1,1]);
myNetwork.propagate(learningRate,[0]);
}
這里我們運行該網路20000次。每一次我們都前向和反向傳播4 次,為該網路輸入4 組可能的輸入:[0,0][0,1][1,0][1,1]。
首先我們執行 myNetwork.activate([0,0]),其中[0,0]是我們發送給該網路的數據點。這是前向傳播,也稱為激活這個網路。在每次前向傳播之後,我們需要執行反向傳播,這時候網路會更新自己的權重和偏置。
反向傳播是通過這行代碼完成的:myNetwork.propagate(learningRate,[0]),其中 learningRate 是一個常數,給出了網路每次應該調整的權重的量。第二個參數0 是給定輸入[0,0]對應的正確輸出。
然後,該網路將自己的預測與正確的標簽進行比較,從而了解自己的正確程度有多少。
然後網路使用這個比較為基礎來校正自己的權重和偏置值,這樣讓自己的下一次猜測更加正確一點。
這個過程如此反復20000次之後,我們可以使用所有四種可能的輸入來檢查網路的學習情況:
->[0.0]console.log(myNetwork.activate([0,1]));
->[0.]console.log(myNetwork.activate([1,0]));
->[0.]console.log(myNetwork.activate([1,1]));
->[0.0]
如果我們將這些值四捨五入到最近的整數,我們就得到了正確的異或運算結果。
這樣就完成了。盡管這僅僅只碰到了神經網路的表皮,但也足以幫助你進一步探索 Synaptic 和繼續學習了。http://github.com/cazala/synaptic/wiki 這里還包含了更多好教程。
『柒』 關於用神經網路建立數學模型的方法
用神經網路建立數學模型的方法如下:
1、准備數據集:神經網路在模式識別、分類、預測等方面具有很強的學習能力和表達能力,在建立數學模型方面也能發揮重要的作用。對於要建立的數學模型,需要准備一定量的數據作為樣本,包括輸入數據和對應的輸出數據。數據集要保證數據量足夠且具有代表性,輸入數據和輸出數據之間具有一定的關系,能夠反映實際問題。
4、利用神經網路進行訓練和預測:訓練神經網路的目的是讓磨純神經網路學習到輸入數據和輸出數據之間的映射關系。訓練過程中要選擇合適的損失函數和優化演算法,以便讓神經網路在訓練過程中不斷優化自身的參數,提高預測的准確性和泛化能力。訓練完成後,可以利用神經網路進行預測,輸入新的數據,通過神經網路輸出相應的預測結果。
數學模型的概念
數學模型是一種通過數學方法描述和分析現實問題的工具。它可以將復雜的現實問題轉化為可描述和可分析的數學表達式,通過定量分析、簡化問題、預測和驗證等手段幫助人們更好地理解和解決問題。
『捌』 Pytorch_循環神經網路RNN
RNN是Recurrent Neural Networks的縮寫,即循環神經網路,它常用於解決序列問題。RNN有記憶功能,除了當前輸入,還把上下文環境作為預測的依據。它常用於語音識別、翻譯等場景之中。
RNN是序列模型的基礎,盡管能夠直接調用現成的RNN演算法,但後續的復雜網路很多構建在RNN網路的基礎之上,如Attention方法需要使用RNN的隱藏層數據。RNN的原理並不復雜,但由於其中包括循環,很難用語言或者畫圖來描述,最好的方法是自己手動編寫一個RNN網路。本篇將介紹RNN網路的原理及具體實現。
在學習循環神經網路之前,先看看什麼是序列。序列sequence簡稱seq,是有先後順序的一組數據。自然語言處理是最為典型的序列問題,比如將一句話翻譯成另一句話時,其中某個詞彙的含義不僅取決於它本身,還與它前後的多個單詞相關。類似的,如果想預測電影的情節發展,不僅與當前的畫面有關,還與當前的一系列前情有關。在使用序列模型預測的過程中,輸入是序列,而輸出是一個或多個預測值。
在使用深度學習模型解決序列問題時, 最容易混淆的是,序列與序列中的元素 。在不同的場景中,定義序列的方式不同,當分析單詞的感情色彩時,一個單詞是一個序列seq;當分析句子感情色彩時,一個句子是一個seq,其中的每個單詞是序列中的元素;當分析文章感情色彩時,一篇文章是一個seq。簡單地說,seq是最終使用模型時的輸入數據,由一系列元素組成。
當分析句子的感情色彩時,以句為seq,而句中包含的各個單詞的含義,以及單詞間的關系是具體分析的對象,此時,單詞是序列中的元素,每一個單詞又可有多維特徵。從單詞中提取特徵的方法將在後面的自然語言處理中介紹。
RNN有很多種形式,單個輸入單個輸入;多個輸入多個輸出,單個輸入多個輸出等等。
舉個最簡單的例子:用模型預測一個四字短語的感情色彩,它的輸入為四個元素X={x1,x2,x3,x4},它的輸出為單個值Y={y1}。字的排列順序至關重要,比如「從好變壞」和「從壞變好」,表達的意思完全相反。之所以輸入輸出的個數不需要一一對應,是因為中間的隱藏層,變向存儲中間信息。
如果把模型設想成黑盒,如下圖所示:
如果模型使用全連接網路,在每次迭代時,模型將計算各個元素x1,x2...中各個特徵f1,f2...代入網路,求它們對結果y的貢獻度。
RNN網路則要復雜一些,在模型內部,它不是將序列中所有元素的特徵一次性輸入模型,而是每一次將序列中單個元素的特徵輸入模型,下圖描述了RNN的數據處理過程,左圖為分步展示,右圖將所有時序步驟抽象成單一模塊。
第一步:將第一個元素x1的特徵f1,f2...輸入模型,模型根據輸入計算出隱藏層h。
第二步:將第二個元素x2的特徵輸入模型,模型根據輸入和上一步產生的h再計算隱藏層h,其它元素以此類推。
第三步:將最後一個元素xn的特徵輸入模型,模型根據輸入和上一步產生的h計算隱藏層h和預測值y。
隱藏層h可視為將序列中前面元素的特徵和位置通過編碼向前傳遞,從而對輸出y發生作用,隱藏層的大小決定了模型攜帶信息量的多少。隱藏層也可以作為模型的輸入從外部傳入,以及作為模型的輸出返回給外部調用。
本例仍使用上篇中的航空乘客序列數據,分別用兩種方法實現RNN:自己編寫程序實現RNN模型,以及調用Pytorch提供的RNN模型。前一種方法主要用於剖析原理,後一種用於展示常用的調用方法。
首先導入頭文件,讀取乘客數據,做歸一化處理,並將數據切分為測試集和訓練集,與之前不同的是加入了create_dataset函數,用於生成序列數據,序列的輸入部分,每個元素中包括兩個特徵:前一個月的乘客量prev和月份值mon,這里的月份值並不是關鍵特徵,主要用於在常式中展示如何使用多個特徵。
第一步:實現模型類,此例中的RNN模型除了全連接層,還生成了一個隱藏層,並在下一次前向傳播時將隱藏層輸出的數據與輸入數據組合後再代入模型運算。
第二步,訓練模型,使用全部數據訓練500次,在每次訓練時,內部for循環將序列中的每個元素代入模型,並將模型輸出的隱藏層和下一個元素一起送入下一次迭代。
第三步:預測和作圖,預測的過程與訓練一樣,把全部數據拆分成元素代入模型,並將每一次預測結果存儲在數組中,並作圖顯示。
需要注意的是,在訓練和預測過程中,每一次開始輸入新序列之前,都重置了隱藏層,這是由於隱藏層的內容只與當前序列相關,序列之間並無連續性。
程序輸出結果如下圖所示:
經過500次迭代,使用RNN的效果明顯優於上一篇中使用全連接網路的擬合效果,還可以通過調整超參數以及選擇不同特徵,進一步優化。
使用Pytorch提供的RNN模型,torch.nn.RNN類可直接使用,是循環網路最常用的解決方案。RNN,LSTM,GRU等循環網路都實現在同一源碼文件torch/nn/moles/rnn.py中。
第一步:創建模型,模型包含兩部分,第一部分是Pytorch提供的RNN層,第二部分是一個全連接層,用於將RNN的輸出轉換成輸出目標的維度。
Pytorch的RNN前向傳播允許將隱藏層數據h作為參數傳入模型,並將模型產生的h和y作為函數返回值。形如: pred, h_state = model(x, h_state)
什麼情況下需要接收隱藏層的狀態h_state,並轉入下一次迭代呢?當處理單個seq時,h在內部前向傳遞;當序列與序列之間也存在前後依賴關系時,可以接收h_state並傳入下一步迭代。另外,當模型比較復雜如LSTM模型包含眾多參數,傳遞會增加模型的復雜度,使訓練過程變慢。本例未將隱藏層轉到模型外部,這是由於模型內部實現了對整個序列的處理,而非處理單個元素,而每次代入的序列之間又沒有連續性。
第二步:訓練模型,與上例中把序列中的元素逐個代入模型不同,本例一次性把整個序列代入了模型,因此,只有一個for循環。
Pythorch支持批量處理,前向傳遞時輸入數據格式是[seq_len, batch_size, input_dim),本例中輸入數據的維度是[100, 1, 2],input_dim是每個元素的特徵數,batch_size是訓練的序列個數,seq_len是序列的長度,這里使用70%作為訓練數據,seq_len為100。如果數據維度的順序與要求不一致,一般使用transpose轉換。
第三步:預測和作圖,將全部數據作為序列代入模型,並用預測值作圖。
程序輸出結果如下圖所示:
可以看到,經過500次迭代,在前100個元素的訓練集上擬合得很好,但在測試集效果較差,可能存在過擬合。