lstm代碼java lstm代碼keras

好答案送分啊

作 者: precom (皮蛋)

創(chuàng)新互聯(lián)建站堅(jiān)信:善待客戶,將會(huì)成為終身客戶。我們能堅(jiān)持多年,是因?yàn)槲覀円恢笨芍档眯刨?。我們從不忽悠初訪客戶,我們用心做好本職工作,不忘初心,方得始終。10多年網(wǎng)站建設(shè)經(jīng)驗(yàn)創(chuàng)新互聯(lián)建站是成都老牌網(wǎng)站營(yíng)銷服務(wù)商,為您提供成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、網(wǎng)站設(shè)計(jì)、H5頁(yè)面制作、網(wǎng)站制作、品牌網(wǎng)站建設(shè)、微信平臺(tái)小程序開發(fā)服務(wù),給眾多知名企業(yè)提供過(guò)好品質(zhì)的建站服務(wù)。

其中的opDb.java

============================================

package ymbean;

import java.sql.*;

import java.util.*;

import java.text.*;

import com.chinazjj.sql.dsql;

import com.chinazjj.util.dutil;

//其他的包dsql,dutil中的內(nèi)容我就不再貼了,在本文件中用到的兩個(gè)函數(shù)都很簡(jiǎn)

public class opDb {

private String inquire_value="",inquire_item="",disptype="",inqtyp

e="";

private String inquire_num="",inquire_addr="",inquire_name="";

private dutil ldutil=new dutil();

public opDb() {

}

public void setinquire_item(String name) { inquire_item= name

;}

public void setinquire_value( String name ) { inquire_value = ldut

il.chineseToUnicode(name);}

public void setdisptype(String name) { disptype=name;}

public void setinqtype(String name) { inqtype=name;}

public void setinquire_num( String name ) { inquire_num = ldutil.c

hineseToUnicode(name);}

public void setinquire_addr( String name ) { inquire_addr = ldutil

.chineseToUnicode(name);}

public void setinquire_name( String name ) { inquire_name = ldutil

.chineseToUnicode(name);}

public String getinquire_dndata()

{

return "";

}

public ResultSet executeQuery(String sql)

{

ResultSet rs = null;

Statement lstmt = null;

try {

lstmt = connectdb();

rs = lstmt.executeQuery(sql);

System.out.println("executeQuery: "+sql);

} catch(SQLException ex) { System.err.println("executeQuery: " +

ex.getMessage());}

return rs;

}

public Statement getStmt()

{

Statement lstmt = null;

lstmt = connectdb();

return lstmt;

}

public String executeUpdate(String sql)

{

ResultSet rs = null;

Statement lstmt = null;

try {

lstmt = connectdb();

lstmt.executeUpdate(sql);

System.out.println("executeUpdate: "+sql);

lstmt.executeUpdate("commit");

}

catch(SQLException ex) { System.err.println("executeQuery: " + e

x.getMessage());

return(ex.getMessage());

}

return("executeUpdate ok");

}

public Statement connectdb()

{

Statement lstmt=null;

Connection conn=null;

final String connect_string="jdbc:oracle:thin:scott/tiger@192.168.

0.1:1521:clubdb";

final String driver_string="oracle.jdbc.driver.OracleDriver";

dsql mysql=new dsql();

lstmt=mysql.dconnectdb(driver_string,connect_string);

return lstmt;

}

public Statement connectdb(String connect_string)

{

Statement lstmt=null;

Connection conn=null;

final String driver_string="oracle.jdbc.driver.OracleDriver";

dsql mysql=new dsql();

lstmt=mysql.dconnectdb(driver_string,connect_string);

return lstmt;

}

//=========other function ===================================

public String getCurrentDate(String ldateform)

{

return(new SimpleDateFormat(ldateform).format(new java.util.Date(

)));

}

//========"/n" to ";br;" =====================================

//去掉奇怪的:

public String removeComment(String Content){

String makeContent=new String();

StringTokenizer strToken=new StringTokenizer(Content,"\n");

String tempToken=null;

while(strToken.hasMoreTokens()){

tempToken=strToken.nextToken();

if(tempToken.indexOf(":")!=0)

makeContent=makeContent+tempToken+"\n";

}

return makeContent;

}

//將/n轉(zhuǎn)換成為回車;br;

public String addBr(String Content){

String makeContent=new String();

StringTokenizer strToken=new StringTokenizer(Content,"\n");

while(strToken.hasMoreTokens()){

makeContent=makeContent+";br;"+strToken.nextToken();

}

return makeContent;

}

//將;br;轉(zhuǎn)換成為回車/n

public String addCr(String Content){

String makeContent=new String();

StringTokenizer strToken=new StringTokenizer(Content,";br;");

while(strToken.hasMoreTokens()){

makeContent=makeContent+"\n"+strToken.nextToken();

}

return makeContent;

}

//====================================================================

=====

public boolean getIdentify(String name1,String pwd1)

{

try

{

String sql="select * from club_users where username='" + name1 + "'

and password='" + pwd1 + "'";

ResultSet rs = executeQuery(sql);

if(rs.next()) { rs.close(); return(true);}

else { rs.close();return(false);}

}catch (Exception e) { return(false);}

}

public void counts(String pagename)

{

executeUpdate("update call_count set counts=counts + 1 where pagenam

e='"+pagename+"'");

}

//==================張家界市民虛擬社區(qū)管理============================

======

public String getDeptSuper(String vp) //取版主

{

String vst="未知";

try{

String sql="select administrator from club_cvcdept where deptno=

'"+vp+"'";

ResultSet rs = executeQuery(sql);

if(rs.next()) vst=rs.getString(1);

rs.close();

} catch (Exception e) {}

return vst;

}

public String getDeptName(String vp) //取版名

{

String vst="未知";

try{

String sql="select deptnote from club_cvcdept where deptno='"+vp

+"'";

ResultSet rs = executeQuery(sql);

if(rs.next()) vst=rs.getString(1);

rs.close();

} catch (Exception e) {}

return vst;

}

public String getUserEmail(String vp) //取社區(qū)用戶email

{

String vst="未知";

try{

String sql="select email from club_users where username='"+vp+"'

";

ResultSet rs = executeQuery(sql);

if(rs.next()) vst=rs.getString(1);

rs.close();

} catch (Exception e) {}

return vst;

}

public Object getaValue(String vp) //取社區(qū)用戶email及其他

{

Object vst=null;

try{

String sql=vp;

ResultSet rs = executeQuery(sql);

if(rs.next()) vst=rs.getObject(1);

rs.close();

} catch (Exception e) {}

return vst;

}

public String getsValue(String vp) //取社區(qū)用戶email及其他

{

String vst="";

try{

String sql=vp;

ResultSet rs = executeQuery(sql);

if(rs.next()) vst=rs.getString(1);

rs.close();

} catch (Exception e) {}

return vst;

}

}//end opDb.java

參考資料:

人工神經(jīng)網(wǎng)絡(luò)概念梳理與實(shí)例演示

人工神經(jīng)網(wǎng)絡(luò)概念梳理與實(shí)例演示

神經(jīng)網(wǎng)絡(luò)是一種模仿生物神經(jīng)元的機(jī)器學(xué)習(xí)模型,數(shù)據(jù)從輸入層進(jìn)入并流經(jīng)激活閾值的多個(gè)節(jié)點(diǎn)。

遞歸性神經(jīng)網(wǎng)絡(luò)一種能夠?qū)χ拜斎霐?shù)據(jù)進(jìn)行內(nèi)部存儲(chǔ)記憶的神經(jīng)網(wǎng)絡(luò),所以他們能夠?qū)W習(xí)到數(shù)據(jù)流中的時(shí)間依賴結(jié)構(gòu)。

如今機(jī)器學(xué)習(xí)已經(jīng)被應(yīng)用到很多的產(chǎn)品中去了,例如,siri、Google Now等智能助手,推薦引擎——亞馬遜網(wǎng)站用于推薦商品的推薦引擎,Google和Facebook使用的廣告排名系統(tǒng)。最近,深度學(xué)習(xí)的一些進(jìn)步將機(jī)器學(xué)習(xí)帶入公眾視野:AlphaGo 打敗圍棋大師李世石事件以及一些圖片識(shí)別和機(jī)器翻譯等新產(chǎn)品的出現(xiàn)。

在這部分中,我們將介紹一些強(qiáng)大并被普遍使用的機(jī)器學(xué)習(xí)技術(shù)。這當(dāng)然包括一些深度學(xué)習(xí)以及一些滿足現(xiàn)代業(yè)務(wù)需求傳統(tǒng)方法。讀完這一系列的文章之后,你就掌握了必要的知識(shí),便可以將具體的機(jī)器學(xué)習(xí)實(shí)驗(yàn)應(yīng)用到你所在的領(lǐng)域當(dāng)中。

隨著深層神經(jīng)網(wǎng)絡(luò)的精度的提高,語(yǔ)音和圖像識(shí)別技術(shù)的應(yīng)用吸引了大眾的注意力,關(guān)于AI和深度學(xué)習(xí)的研究也變得更加普遍了。但是怎么能夠讓它進(jìn)一步擴(kuò)大影響力,更受歡迎仍然是一個(gè)問(wèn)題。這篇文章的主要內(nèi)容是:簡(jiǎn)述前饋神經(jīng)網(wǎng)絡(luò)和遞歸神經(jīng)網(wǎng)絡(luò)、怎樣搭建一個(gè)遞歸神經(jīng)網(wǎng)絡(luò)對(duì)時(shí)間系列數(shù)據(jù)進(jìn)行異常檢測(cè)。為了讓我們的討論更加具體化,我們將演示一下怎么用Deeplearning4j搭建神經(jīng)網(wǎng)絡(luò)。

一、什么是神經(jīng)網(wǎng)絡(luò)?

人工神經(jīng)網(wǎng)絡(luò)算法的最初構(gòu)思是模仿生物神經(jīng)元。但是這個(gè)類比很不可靠。人工神經(jīng)網(wǎng)絡(luò)的每一個(gè)特征都是對(duì)生物神經(jīng)元的一種折射:每一個(gè)節(jié)點(diǎn)與激活閾值、觸發(fā)的連接。

連接人工神經(jīng)元系統(tǒng)建立起來(lái)之后,我們就能夠?qū)@些系統(tǒng)進(jìn)行訓(xùn)練,從而讓他們學(xué)習(xí)到數(shù)據(jù)中的一些模式,學(xué)到之后就能執(zhí)行回歸、分類、聚類、預(yù)測(cè)等功能。

人工神經(jīng)網(wǎng)絡(luò)可以看作是計(jì)算節(jié)點(diǎn)的集合。數(shù)據(jù)通過(guò)這些節(jié)點(diǎn)進(jìn)入神經(jīng)網(wǎng)絡(luò)的輸入層,再通過(guò)神經(jīng)網(wǎng)絡(luò)的隱藏層直到關(guān)于數(shù)據(jù)的一個(gè)結(jié)論或者結(jié)果出現(xiàn),這個(gè)過(guò)程才會(huì)停止。神經(jīng)網(wǎng)絡(luò)產(chǎn)出的結(jié)果會(huì)跟預(yù)期的結(jié)果進(jìn)行比較,神經(jīng)網(wǎng)絡(luò)得出的結(jié)果與正確結(jié)果的不同點(diǎn)會(huì)被用來(lái)更正神經(jīng)網(wǎng)絡(luò)節(jié)點(diǎn)的激活閾值。隨著這個(gè)過(guò)程的不斷重復(fù),神經(jīng)網(wǎng)絡(luò)的輸出結(jié)果就會(huì)無(wú)限靠近預(yù)期結(jié)果。

二、訓(xùn)練過(guò)程

在搭建一個(gè)神經(jīng)網(wǎng)絡(luò)系統(tǒng)之前,你必須先了解訓(xùn)練的過(guò)程以及網(wǎng)絡(luò)輸出結(jié)果是怎么產(chǎn)生的。然而我們并不想過(guò)度深入的了解這些方程式,下面是一個(gè)簡(jiǎn)短的介紹。

網(wǎng)絡(luò)的輸入節(jié)點(diǎn)收到一個(gè)數(shù)值數(shù)組(或許是叫做張量多維度數(shù)組)就代表輸入數(shù)據(jù)。例如, 圖像中的每個(gè)像素可以表示為一個(gè)標(biāo)量,然后將像素傳遞給一個(gè)節(jié)點(diǎn)。輸入數(shù)據(jù)將會(huì)與神經(jīng)網(wǎng)絡(luò)的參數(shù)相乘,這個(gè)輸入數(shù)據(jù)被擴(kuò)大還是減小取決于它的重要性,換句話說(shuō),取決于這個(gè)像素就不會(huì)影響神經(jīng)網(wǎng)絡(luò)關(guān)于整個(gè)輸入數(shù)據(jù)的結(jié)論。

起初這些參數(shù)都是隨機(jī)的,也就是說(shuō)神經(jīng)網(wǎng)絡(luò)在建立初期根本就不了解數(shù)據(jù)的結(jié)構(gòu)。每個(gè)節(jié)點(diǎn)的激活函數(shù)決定了每個(gè)輸入節(jié)點(diǎn)的輸出結(jié)果。所以每個(gè)節(jié)點(diǎn)是否能夠被激活取決于它是否接受到足夠的刺激強(qiáng)度,即是否輸入數(shù)據(jù)和參數(shù)的結(jié)果超出了激活閾值的界限。

在所謂的密集或完全連接層中,每個(gè)節(jié)點(diǎn)的輸出值都會(huì)傳遞給后續(xù)層的節(jié)點(diǎn),在通過(guò)所有隱藏層后最終到達(dá)輸出層,也就是產(chǎn)生輸入結(jié)果的地方。在輸出層, 神經(jīng)網(wǎng)絡(luò)得到的最終結(jié)論將會(huì)跟預(yù)期結(jié)論進(jìn)行比較(例如,圖片中的這些像素代表一只貓還是狗?)。神經(jīng)網(wǎng)絡(luò)猜測(cè)的結(jié)果與正確結(jié)果的計(jì)算誤差都會(huì)被納入到一個(gè)測(cè)試集中,神經(jīng)網(wǎng)絡(luò)又會(huì)利用這些計(jì)算誤差來(lái)不斷更新參數(shù),以此來(lái)改變圖片中不同像素的重要程度。整個(gè)過(guò)程的目的就是降低輸出結(jié)果與預(yù)期結(jié)果的誤差,正確地標(biāo)注出這個(gè)圖像到底是不是一條狗。

深度學(xué)習(xí)是一個(gè)復(fù)雜的過(guò)程,由于大量的矩陣系數(shù)需要被修改所以它就涉及到矩陣代數(shù)、衍生品、概率和密集的硬件使用問(wèn)題,但是用戶不需要全部了解這些復(fù)雜性。

但是,你也應(yīng)該知道一些基本參數(shù),這將幫助你理解神經(jīng)網(wǎng)絡(luò)函數(shù)。這其中包括激活函數(shù)、優(yōu)化算法和目標(biāo)函數(shù)(也稱為損失、成本或誤差函數(shù))。

激活函數(shù)決定了信號(hào)是否以及在多大程度上應(yīng)該被發(fā)送到連接節(jié)點(diǎn)。階梯函數(shù)是最常用的激活函數(shù), 如果其輸入小于某個(gè)閾值就是0,如果其輸入大于閾值就是1。節(jié)點(diǎn)都會(huì)通過(guò)階梯激活函數(shù)向連接節(jié)點(diǎn)發(fā)送一個(gè)0或1。優(yōu)化算法決定了神經(jīng)網(wǎng)絡(luò)怎么樣學(xué)習(xí),以及測(cè)試完誤差后,權(quán)重怎么樣被更準(zhǔn)確地調(diào)整。最常見的優(yōu)化算法是隨機(jī)梯度下降法。最后, 成本函數(shù)常用來(lái)衡量誤差,通過(guò)對(duì)比一個(gè)給定訓(xùn)練樣本中得出的結(jié)果與預(yù)期結(jié)果的不同來(lái)評(píng)定神經(jīng)網(wǎng)絡(luò)的執(zhí)行效果。

Keras、Deeplearning4j 等開源框架讓創(chuàng)建神經(jīng)網(wǎng)絡(luò)變得簡(jiǎn)單。創(chuàng)建神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)時(shí),需要考慮的是怎樣將你的數(shù)據(jù)類型匹配到一個(gè)已知的被解決的問(wèn)題,并且根據(jù)你的實(shí)際需求來(lái)修改現(xiàn)有結(jié)構(gòu)。

三、神經(jīng)網(wǎng)絡(luò)的類型以及應(yīng)用

神經(jīng)網(wǎng)絡(luò)已經(jīng)被了解和應(yīng)用了數(shù)十年了,但是最近的一些技術(shù)趨勢(shì)才使得深度神經(jīng)網(wǎng)絡(luò)變得更加高效。

GPUs使得矩陣操作速度更快;分布式計(jì)算結(jié)構(gòu)讓計(jì)算能力大大增強(qiáng);多個(gè)超參數(shù)的組合也讓迭代的速度提升。所有這些都讓訓(xùn)練的速度大大加快,迅速找到適合的結(jié)構(gòu)。

隨著更大數(shù)據(jù)集的產(chǎn)生,類似于ImageNet 的大型高質(zhì)量的標(biāo)簽數(shù)據(jù)集應(yīng)運(yùn)而生。機(jī)器學(xué)習(xí)算法訓(xùn)練的數(shù)據(jù)越大,那么它的準(zhǔn)確性就會(huì)越高。

最后,隨著我們理解能力以及神經(jīng)網(wǎng)絡(luò)算法的不斷提升,神經(jīng)網(wǎng)絡(luò)的準(zhǔn)確性在語(yǔ)音識(shí)別、機(jī)器翻譯以及一些機(jī)器感知和面向目標(biāo)的一些任務(wù)等方面不斷刷新記錄。

盡管神經(jīng)網(wǎng)絡(luò)架構(gòu)非常的大,但是主要用到的神經(jīng)網(wǎng)絡(luò)種類也就是下面的幾種。

3.1前饋神經(jīng)網(wǎng)絡(luò)

前饋神經(jīng)網(wǎng)絡(luò)包括一個(gè)輸入層、一個(gè)輸出層以及一個(gè)或多個(gè)的隱藏層。前饋神經(jīng)網(wǎng)絡(luò)可以做出很好的通用逼近器,并且能夠被用來(lái)創(chuàng)建通用模型。

這種類型的神經(jīng)網(wǎng)絡(luò)可用于分類和回歸。例如,當(dāng)使用前饋網(wǎng)絡(luò)進(jìn)行分類時(shí),輸出層神經(jīng)元的個(gè)數(shù)等于類的數(shù)量。從概念上講, 激活了的輸出神經(jīng)元決定了神經(jīng)網(wǎng)絡(luò)所預(yù)測(cè)的類。更準(zhǔn)確地說(shuō), 每個(gè)輸出神經(jīng)元返回一個(gè)記錄與分類相匹配的概率數(shù),其中概率最高的分類將被選為模型的輸出分類。

前饋神經(jīng)網(wǎng)絡(luò)的優(yōu)勢(shì)是簡(jiǎn)單易用,與其他類型的神經(jīng)網(wǎng)絡(luò)相比更簡(jiǎn)單,并且有一大堆的應(yīng)用實(shí)例。

3.2卷積神經(jīng)網(wǎng)絡(luò)

卷積神經(jīng)網(wǎng)絡(luò)和前饋神經(jīng)網(wǎng)絡(luò)是非常相似的,至少是數(shù)據(jù)的傳輸方式類似。他們結(jié)構(gòu)大致上是模仿了視覺(jué)皮層。卷積神經(jīng)網(wǎng)絡(luò)通過(guò)許多的過(guò)濾器。這些過(guò)濾器主要集中在一個(gè)圖像子集、補(bǔ)丁、圖塊的特征識(shí)別上。每一個(gè)過(guò)濾器都在尋找不同模式的視覺(jué)數(shù)據(jù),例如,有的可能是找水平線,有的是找對(duì)角線,有的是找垂直的。這些線條都被看作是特征,當(dāng)過(guò)濾器經(jīng)過(guò)圖像時(shí),他們就會(huì)構(gòu)造出特征圖譜來(lái)定位各類線是出現(xiàn)在圖像的哪些地方。圖像中的不同物體,像貓、747s、榨汁機(jī)等都會(huì)有不同的圖像特征,這些圖像特征就能使圖像完成分類。卷積神經(jīng)網(wǎng)絡(luò)在圖像識(shí)別和語(yǔ)音識(shí)別方面是非常的有效的。

卷積神經(jīng)網(wǎng)絡(luò)與前饋神經(jīng)網(wǎng)絡(luò)在圖像識(shí)別方面的異同比較。雖然這兩種網(wǎng)絡(luò)類型都能夠進(jìn)行圖像識(shí)別,但是方式卻不同。卷積神經(jīng)網(wǎng)絡(luò)是通過(guò)識(shí)別圖像的重疊部分,然后學(xué)習(xí)識(shí)別不同部分的特征進(jìn)行訓(xùn)練;然而,前饋神經(jīng)網(wǎng)絡(luò)是在整張圖片上進(jìn)行訓(xùn)練。前饋神經(jīng)網(wǎng)絡(luò)總是在圖片的某一特殊部分或者方向進(jìn)行訓(xùn)練,所以當(dāng)圖片的特征出現(xiàn)在其他地方時(shí)就不會(huì)被識(shí)別到,然而卷積神經(jīng)網(wǎng)絡(luò)卻能夠很好的避免這一點(diǎn)。

卷積神經(jīng)網(wǎng)絡(luò)主要是用于圖像、視頻、語(yǔ)音、聲音識(shí)別以及無(wú)人駕駛的任務(wù)。盡管這篇文章主要是討論遞歸神經(jīng)網(wǎng)絡(luò)的,但是卷積神經(jīng)網(wǎng)絡(luò)在圖像識(shí)別方面也是非常有效的,所以很有必要了解。

3.3遞歸神經(jīng)網(wǎng)絡(luò)

與前饋神經(jīng)網(wǎng)絡(luò)不同的是,遞歸神經(jīng)網(wǎng)絡(luò)的隱藏層的節(jié)點(diǎn)里有內(nèi)部記憶存儲(chǔ)功能,隨著輸入數(shù)據(jù)的改變而內(nèi)部記憶內(nèi)容不斷被更新。遞歸神經(jīng)網(wǎng)絡(luò)的結(jié)論都是基于當(dāng)前的輸入和之前存儲(chǔ)的數(shù)據(jù)而得出的。遞歸神經(jīng)網(wǎng)絡(luò)能夠充分利用這種內(nèi)部記憶存儲(chǔ)狀態(tài)處理任意序列的數(shù)據(jù),例如時(shí)間序列。

遞歸神經(jīng)網(wǎng)絡(luò)經(jīng)常用于手寫識(shí)別、語(yǔ)音識(shí)別、日志分析、欺詐檢測(cè)和網(wǎng)絡(luò)安全。

遞歸神經(jīng)網(wǎng)絡(luò)是處理時(shí)間維度數(shù)據(jù)集的最好方法,它可以處理以下數(shù)據(jù):網(wǎng)絡(luò)日志和服務(wù)器活動(dòng)、硬件或者是醫(yī)療設(shè)備的傳感器數(shù)據(jù)、金融交易、電話記錄。想要追蹤數(shù)據(jù)在不同階段的依賴和關(guān)聯(lián)關(guān)系需要你了解當(dāng)前和之前的一些數(shù)據(jù)狀態(tài)。盡管我們通過(guò)前饋神經(jīng)網(wǎng)絡(luò)也可以獲取事件,隨著時(shí)間的推移移動(dòng)到另外一個(gè)事件,這將使我們限制在對(duì)事件的依賴中,所以這種方式很不靈活。

追蹤在時(shí)間維度上有長(zhǎng)期依賴的數(shù)據(jù)的更好方法是用內(nèi)存來(lái)儲(chǔ)存重要事件,以使近期事件能夠被理解和分類。遞歸神經(jīng)網(wǎng)絡(luò)最好的一點(diǎn)就是在它的隱藏層里面有“內(nèi)存”可以學(xué)習(xí)到時(shí)間依賴特征的重要性。

接下來(lái)我們將討論遞歸神經(jīng)網(wǎng)絡(luò)在字符生成器和網(wǎng)絡(luò)異常檢測(cè)中的應(yīng)用。遞歸神經(jīng)網(wǎng)絡(luò)可以檢測(cè)出不同時(shí)間段的依賴特征的能力使得它可以進(jìn)行時(shí)間序列數(shù)據(jù)的異常檢測(cè)。

遞歸神經(jīng)網(wǎng)絡(luò)的應(yīng)用

網(wǎng)絡(luò)上有很多使用RNNs生成文本的例子,遞歸神經(jīng)網(wǎng)絡(luò)經(jīng)過(guò)語(yǔ)料庫(kù)的訓(xùn)練之后,只要輸入一個(gè)字符,就可以預(yù)測(cè)下一個(gè)字符。下面讓我們通過(guò)一些實(shí)用例子發(fā)現(xiàn)更多RNNs的特征。

應(yīng)用一、RNNs用于字符生成

遞歸神經(jīng)網(wǎng)絡(luò)經(jīng)過(guò)訓(xùn)練之后可以把英文字符當(dāng)做成一系列的時(shí)間依賴事件。經(jīng)過(guò)訓(xùn)練后它會(huì)學(xué)習(xí)到一個(gè)字符經(jīng)常跟著另外一個(gè)字符(“e”經(jīng)常跟在“h”后面,像在“the、he、she”中)。由于它能預(yù)測(cè)下一個(gè)字符是什么,所以它能有效地減少文本的輸入錯(cuò)誤。

Java是個(gè)很有趣的例子,因?yàn)樗慕Y(jié)構(gòu)包括很多嵌套結(jié)構(gòu),有一個(gè)開的圓括號(hào)必然后面就會(huì)有一個(gè)閉的,花括號(hào)也是同理。他們之間的依賴關(guān)系并不會(huì)在位置上表現(xiàn)的很明顯,因?yàn)槎鄠€(gè)事件之間的關(guān)系不是靠所在位置的距離確定的。但是就算是不明確告訴遞歸神經(jīng)網(wǎng)絡(luò)Java中各個(gè)事件的依賴關(guān)系,它也能自己學(xué)習(xí)了解到。

在異常檢測(cè)當(dāng)中,我們要求神經(jīng)網(wǎng)絡(luò)能夠檢測(cè)出數(shù)據(jù)中相似、隱藏的或許是并不明顯的模式。就像是一個(gè)字符生成器在充分地了解數(shù)據(jù)的結(jié)構(gòu)后就會(huì)生成一個(gè)數(shù)據(jù)的擬像,遞歸神經(jīng)網(wǎng)絡(luò)的異常檢測(cè)就是在其充分了解數(shù)據(jù)結(jié)構(gòu)后來(lái)判斷輸入的數(shù)據(jù)是不是正常。

字符生成的例子表明遞歸神經(jīng)網(wǎng)絡(luò)有在不同時(shí)間范圍內(nèi)學(xué)習(xí)到時(shí)間依賴關(guān)系的能力,它的這種能力還可以用來(lái)檢測(cè)網(wǎng)絡(luò)活動(dòng)日志的異常。

異常檢測(cè)能夠使文本中的語(yǔ)法錯(cuò)誤浮出水面,這是因?yàn)槲覀兯鶎懙臇|西是由語(yǔ)法結(jié)構(gòu)所決定的。同理,網(wǎng)絡(luò)行為也是有結(jié)構(gòu)的,它也有一個(gè)能夠被學(xué)習(xí)的可預(yù)測(cè)模式。經(jīng)過(guò)在正常網(wǎng)絡(luò)活動(dòng)中訓(xùn)練的遞歸神經(jīng)網(wǎng)絡(luò)可以監(jiān)測(cè)到入侵行為,因?yàn)檫@些入侵行為的出現(xiàn)就像是一個(gè)句子沒(méi)有標(biāo)點(diǎn)符號(hào)一樣異常。

應(yīng)用二、一個(gè)網(wǎng)絡(luò)異常檢測(cè)項(xiàng)目的示例

假設(shè)我們想要了解的網(wǎng)絡(luò)異常檢測(cè)就是能夠得到硬件故障、應(yīng)用程序失敗、以及入侵的一些信息。

模型將會(huì)向我們展示什么呢?

隨著大量的網(wǎng)絡(luò)活動(dòng)日志被輸入到遞歸神經(jīng)網(wǎng)絡(luò)中去,神經(jīng)網(wǎng)絡(luò)就能學(xué)習(xí)到正常的網(wǎng)絡(luò)活動(dòng)應(yīng)該是什么樣子的。當(dāng)這個(gè)被訓(xùn)練的網(wǎng)絡(luò)被輸入新的數(shù)據(jù)時(shí),它就能偶判斷出哪些是正常的活動(dòng),哪些是被期待的,哪些是異常的。

訓(xùn)練一個(gè)神經(jīng)網(wǎng)絡(luò)來(lái)識(shí)別預(yù)期行為是有好處的,因?yàn)楫惓?shù)據(jù)不多,或者是不能夠準(zhǔn)確的將異常行為進(jìn)行分類。我們?cè)谡5臄?shù)據(jù)里進(jìn)行訓(xùn)練,它就能夠在未來(lái)的某個(gè)時(shí)間點(diǎn)提醒我們非正?;顒?dòng)的出現(xiàn)。

說(shuō)句題外話,訓(xùn)練的神經(jīng)網(wǎng)絡(luò)并不一定非得識(shí)別到特定事情發(fā)生的特定時(shí)間點(diǎn)(例如,它不知道那個(gè)特殊的日子就是周日),但是它一定會(huì)發(fā)現(xiàn)一些值得我們注意的一些更明顯的時(shí)間模式和一些可能并不明顯的事件之間的聯(lián)系。

我們將概述一下怎么用 Deeplearning4j(一個(gè)在JVM上被廣泛應(yīng)用的深度學(xué)習(xí)開源數(shù)據(jù)庫(kù))來(lái)解決這個(gè)問(wèn)題。Deeplearning4j在模型開發(fā)過(guò)程中提供了很多有用的工具:DataVec是一款為ETL(提取-轉(zhuǎn)化-加載)任務(wù)準(zhǔn)備模型訓(xùn)練數(shù)據(jù)的集成工具。正如Sqoop為Hadoop加載數(shù)據(jù),DataVec將數(shù)據(jù)進(jìn)行清洗、預(yù)處理、規(guī)范化與標(biāo)準(zhǔn)化之后將數(shù)據(jù)加載到神經(jīng)網(wǎng)絡(luò)。這跟Trifacta’s Wrangler也相似,只不過(guò)它更關(guān)注二進(jìn)制數(shù)據(jù)。

開始階段

第一階段包括典型的大數(shù)據(jù)任務(wù)和ETL:我們需要收集、移動(dòng)、儲(chǔ)存、準(zhǔn)備、規(guī)范化、矢量話日志。時(shí)間跨度的長(zhǎng)短是必須被規(guī)定好的。數(shù)據(jù)的轉(zhuǎn)化需要花費(fèi)一些功夫,這是由于JSON日志、文本日志、還有一些非連續(xù)標(biāo)注模式都必須被識(shí)別并且轉(zhuǎn)化為數(shù)值數(shù)組。DataVec能夠幫助進(jìn)行轉(zhuǎn)化和規(guī)范化數(shù)據(jù)。在開發(fā)機(jī)器學(xué)習(xí)訓(xùn)練模型時(shí),數(shù)據(jù)需要分為訓(xùn)練集和測(cè)試集。

訓(xùn)練神經(jīng)網(wǎng)絡(luò)

神經(jīng)網(wǎng)絡(luò)的初始訓(xùn)練需要在訓(xùn)練數(shù)據(jù)集中進(jìn)行。

在第一次訓(xùn)練的時(shí)候,你需要調(diào)整一些超參數(shù)以使模型能夠?qū)崿F(xiàn)在數(shù)據(jù)中學(xué)習(xí)。這個(gè)過(guò)程需要控制在合理的時(shí)間內(nèi)。關(guān)于超參數(shù)我們將在之后進(jìn)行討論。在模型訓(xùn)練的過(guò)程中,你應(yīng)該以降低錯(cuò)誤為目標(biāo)。

但是這可能會(huì)出現(xiàn)神經(jīng)網(wǎng)絡(luò)模型過(guò)度擬合的風(fēng)險(xiǎn)。有過(guò)度擬合現(xiàn)象出現(xiàn)的模型往往會(huì)在訓(xùn)練集中的很高的分?jǐn)?shù),但是在遇到新的數(shù)據(jù)時(shí)就會(huì)得出錯(cuò)誤結(jié)論。用機(jī)器學(xué)習(xí)的語(yǔ)言來(lái)說(shuō)就是它不夠通用化。Deeplearning4J提供正則化的工具和“過(guò)早停止”來(lái)避免訓(xùn)練過(guò)程中的過(guò)度擬合。

神經(jīng)網(wǎng)絡(luò)的訓(xùn)練是最花費(fèi)時(shí)間和耗費(fèi)硬件的一步。在GPUs上訓(xùn)練能夠有效的減少訓(xùn)練時(shí)間,尤其是做圖像識(shí)別的時(shí)候。但是額外的硬件設(shè)施就帶來(lái)多余的花銷,所以你的深度學(xué)習(xí)的框架必須能夠有效的利用硬件設(shè)施。Azure和亞馬遜等云服務(wù)提供了基于GPU的實(shí)例,神經(jīng)網(wǎng)絡(luò)還可以在異構(gòu)集群上進(jìn)行訓(xùn)練。

創(chuàng)建模型

Deeplearning4J提供ModelSerializer來(lái)保存訓(xùn)練模型。訓(xùn)練模型可以被保存或者是在之后的訓(xùn)練中被使用或更新。

在執(zhí)行異常檢測(cè)的過(guò)程中,日志文件的格式需要與訓(xùn)練模型一致,基于神經(jīng)網(wǎng)絡(luò)的輸出結(jié)果,你將會(huì)得到是否當(dāng)前的活動(dòng)符合正常網(wǎng)絡(luò)行為預(yù)期的結(jié)論。

代碼示例

遞歸神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)應(yīng)該是這樣子的:

MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder(

.seed(123)

.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT).iterations(1)

.weightInit(WeightInit.XAVIER)

.updater(Updater.NESTEROVS).momentum(0.9)

.learningRate(0.005)

.gradientNormalization(GradientNormalization.ClipElementWiseAbsoluteValue)

.gradientNormalizationThreshold(0.5)

.list()

.layer(0, new GravesLSTM.Builder().activation("tanh").nIn(1).nOut(10).build())

.layer(1, new RnnOutputLayer.Builder(LossFunctions.LossFunction.MCXENT)

.activation("softmax").nIn(10).nOut(numLabelClasses).build())

.pretrain(false).backprop(true).build();

MultiLayerNetwork net = new MultiLayerNetwork(conf);

net.init();

下面解釋一下幾行重要的代碼:

.seed(123)

隨機(jī)設(shè)置一個(gè)種子值對(duì)神經(jīng)網(wǎng)絡(luò)的權(quán)值進(jìn)行初始化,以此獲得一個(gè)有復(fù)驗(yàn)性的結(jié)果。系數(shù)通常都是被隨機(jī)的初始化的,以使我們?cè)谡{(diào)整其他超參數(shù)時(shí)仍獲得一致的結(jié)果。我們需要設(shè)定一個(gè)種子值,讓我們?cè)谡{(diào)整和測(cè)試的時(shí)候能夠用這個(gè)隨機(jī)的權(quán)值。

.optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT).iterations(1)

決定使用哪個(gè)最優(yōu)算法(在這個(gè)例子中是隨機(jī)梯度下降法)來(lái)調(diào)整權(quán)值以提高誤差分?jǐn)?shù)。你可能不需要對(duì)這個(gè)進(jìn)行修改。

.learningRate(0.005)

當(dāng)我們使用隨機(jī)梯度下降法的時(shí)候,誤差梯度就被計(jì)算出來(lái)了。在我們?cè)噲D將誤差值減到最小的過(guò)程中,權(quán)值也隨之變化。SGD給我們一個(gè)讓誤差更小的方向,這個(gè)學(xué)習(xí)效率就決定了我們?cè)撛谶@個(gè)方向上邁多大的梯度。如果學(xué)習(xí)效率太高,你可能是超過(guò)了誤差最小值;如果太低,你的訓(xùn)練可能將會(huì)永遠(yuǎn)進(jìn)行。這是一個(gè)你需要調(diào)整的超參數(shù)。

求教pytorch的LSTM網(wǎng)絡(luò)代碼問(wèn)題

input就是shape=(seq_length,batch_size,input_size)的張量

ht是shape=(num_layers*num_directions,batch_size,hidden_size)的張量,它包含了在當(dāng)前這個(gè)batch_size中每個(gè)句子的初始隱藏狀態(tài)。其中num_layers就是LSTM的層數(shù)。如果bidirectional=True,num_directions=2,否則就是1,表示只有一個(gè)方向。

ct和ht的形狀相同,它包含的是在當(dāng)前這個(gè)batch_size中的每個(gè)句子的初始細(xì)胞狀態(tài)。

ht,ct如果不提供,那么默認(rèn)是0。

至于為什么要定義ht和ct建議了解一下LSTM的網(wǎng)絡(luò)結(jié)構(gòu)和原理,會(huì)對(duì)你有很大的幫助。

LSTM神經(jīng)網(wǎng)絡(luò)輸入輸出究竟是怎樣的?

輸入輸出都是向量,或者說(shuō)是矩陣。LSTM用于分類的話,后面一般會(huì)接softmax層。個(gè)人淺薄理解,拿動(dòng)作識(shí)別分類舉例,每個(gè)動(dòng)作幀放入LSTM中訓(xùn)練,還是根據(jù)task來(lái)訓(xùn)練每個(gè)LSTM單元的Weights。所以LSTM的單元數(shù)量跟輸入和輸出都沒(méi)有關(guān)系,甚至還可以幾層LSTM疊加起來(lái)用。分類的話,一般用最后一個(gè)單元接上softmax層。LSTM結(jié)構(gòu)是傳統(tǒng)的RNN結(jié)構(gòu)擴(kuò)展,解決了傳統(tǒng)RNN梯度消失/爆炸的問(wèn)題,從而使得深層次的網(wǎng)絡(luò)更容易訓(xùn)練。從這個(gè)角度理解,可能會(huì)容易很多。今年的ResNet也是使傳統(tǒng)的CNN更容易訓(xùn)練weights??磥?lái)deeplearning越來(lái)越深是趨勢(shì)啊。如果說(shuō)訓(xùn)練,就一個(gè)關(guān)鍵,所謂LSTMUnroll,將RNN展開成一個(gè)靜態(tài)的“并行”網(wǎng)絡(luò),內(nèi)部有“側(cè)向連接”,實(shí)現(xiàn)長(zhǎng)的短時(shí)記憶功能(狀態(tài)“記憶”在LSTMCell里)。如果說(shuō)預(yù)測(cè),也就一個(gè)關(guān)鍵,要將Cell的h和C弄出來(lái),作為當(dāng)前狀態(tài)(也就是所謂“記憶”)作為init參數(shù)輸入,這樣,攜帶了當(dāng)前記憶狀態(tài)的網(wǎng)絡(luò),預(yù)測(cè)得到的就是下一個(gè)輸入了,所謂的recurrent了。那份代碼里還包含了一個(gè)使用cudnn的實(shí)現(xiàn)(built-inRNNoperator),這是一個(gè)高性能的版本,可以真正干活的。原來(lái)我也嘗試搞懂一些天書般的公式,很快發(fā)現(xiàn)從那里入手是個(gè)錯(cuò)誤。強(qiáng)烈推薦:理解LSTM網(wǎng)絡(luò)(翻譯自UnderstandingLSTMNetworks)只要有一點(diǎn)點(diǎn)CNN基礎(chǔ)+半個(gè)小時(shí),就可以通過(guò)這篇文章理解LSTM的基礎(chǔ)原理?;卮鹉愕膯?wèn)題:和神經(jīng)元個(gè)數(shù)無(wú)關(guān),不知道你是如何理解“神經(jīng)元”這個(gè)概念的,輸入輸出層保證tensor的維數(shù)和輸入輸出一致就可以了。

如何在Python中用LSTM網(wǎng)絡(luò)進(jìn)行時(shí)間序列預(yù)測(cè)

時(shí)間序列模型

時(shí)間序列預(yù)測(cè)分析就是利用過(guò)去一段時(shí)間內(nèi)某事件時(shí)間的特征來(lái)預(yù)測(cè)未來(lái)一段時(shí)間內(nèi)該事件的特征。這是一類相對(duì)比較復(fù)雜的預(yù)測(cè)建模問(wèn)題,和回歸分析模型的預(yù)測(cè)不同,時(shí)間序列模型是依賴于事件發(fā)生的先后順序的,同樣大小的值改變順序后輸入模型產(chǎn)生的結(jié)果是不同的。

舉個(gè)栗子:根據(jù)過(guò)去兩年某股票的每天的股價(jià)數(shù)據(jù)推測(cè)之后一周的股價(jià)變化;根據(jù)過(guò)去2年某店鋪每周想消費(fèi)人數(shù)預(yù)測(cè)下周來(lái)店消費(fèi)的人數(shù)等等

RNN 和 LSTM 模型

時(shí)間序列模型最常用最強(qiáng)大的的工具就是遞歸神經(jīng)網(wǎng)絡(luò)(recurrent neural network, RNN)。相比與普通神經(jīng)網(wǎng)絡(luò)的各計(jì)算結(jié)果之間相互獨(dú)立的特點(diǎn),RNN的每一次隱含層的計(jì)算結(jié)果都與當(dāng)前輸入以及上一次的隱含層結(jié)果相關(guān)。通過(guò)這種方法,RNN的計(jì)算結(jié)果便具備了記憶之前幾次結(jié)果的特點(diǎn)。

典型的RNN網(wǎng)路結(jié)構(gòu)如下:

右側(cè)為計(jì)算時(shí)便于理解記憶而產(chǎn)開的結(jié)構(gòu)。簡(jiǎn)單說(shuō),x為輸入層,o為輸出層,s為隱含層,而t指第幾次的計(jì)算;V,W,U為權(quán)重,其中計(jì)算第t次的隱含層狀態(tài)時(shí)為St = f(U*Xt + W*St-1),實(shí)現(xiàn)當(dāng)前輸入結(jié)果與之前的計(jì)算掛鉤的目的。對(duì)RNN想要更深入的了解可以戳這里。

RNN的局限:

由于RNN模型如果需要實(shí)現(xiàn)長(zhǎng)期記憶的話需要將當(dāng)前的隱含態(tài)的計(jì)算與前n次的計(jì)算掛鉤,即St = f(U*Xt + W1*St-1 + W2*St-2 + ... + Wn*St-n),那樣的話計(jì)算量會(huì)呈指數(shù)式增長(zhǎng),導(dǎo)致模型訓(xùn)練的時(shí)間大幅增加,因此RNN模型一般直接用來(lái)進(jìn)行長(zhǎng)期記憶計(jì)算。

LSTM模型

LSTM(Long Short-Term Memory)模型是一種RNN的變型,最早由Juergen Schmidhuber提出的。經(jīng)典的LSTM模型結(jié)構(gòu)如下:

LSTM的特點(diǎn)就是在RNN結(jié)構(gòu)以外添加了各層的閥門節(jié)點(diǎn)。閥門有3類:遺忘閥門(forget gate),輸入閥門(input gate)和輸出閥門(output gate)。這些閥門可以打開或關(guān)閉,用于將判斷模型網(wǎng)絡(luò)的記憶態(tài)(之前網(wǎng)絡(luò)的狀態(tài))在該層輸出的結(jié)果是否達(dá)到閾值從而加入到當(dāng)前該層的計(jì)算中。如圖中所示,閥門節(jié)點(diǎn)利用sigmoid函數(shù)將網(wǎng)絡(luò)的記憶態(tài)作為輸入計(jì)算;如果輸出結(jié)果達(dá)到閾值則將該閥門輸出與當(dāng)前層的的計(jì)算結(jié)果相乘作為下一層的輸入(PS:這里的相乘是在指矩陣中的逐元素相乘);如果沒(méi)有達(dá)到閾值則將該輸出結(jié)果遺忘掉。每一層包括閥門節(jié)點(diǎn)的權(quán)重都會(huì)在每一次模型反向傳播訓(xùn)練過(guò)程中更新。更具體的LSTM的判斷計(jì)算過(guò)程如下圖所示:

LSTM模型的記憶功能就是由這些閥門節(jié)點(diǎn)實(shí)現(xiàn)的。當(dāng)閥門打開的時(shí)候,前面模型的訓(xùn)練結(jié)果就會(huì)關(guān)聯(lián)到當(dāng)前的模型計(jì)算,而當(dāng)閥門關(guān)閉的時(shí)候之前的計(jì)算結(jié)果就不再影響當(dāng)前的計(jì)算。因此,通過(guò)調(diào)節(jié)閥門的開關(guān)我們就可以實(shí)現(xiàn)早期序列對(duì)最終結(jié)果的影響。而當(dāng)你不不希望之前結(jié)果對(duì)之后產(chǎn)生影響,比如自然語(yǔ)言處理中的開始分析新段落或新章節(jié),那么把閥門關(guān)掉即可。(對(duì)LSTM想要更具體的了解可以戳這里)

下圖具體演示了閥門是如何工作的:通過(guò)閥門控制使序列第1的輸入的變量影響到了序列第4,6的的變量計(jì)算結(jié)果。

黑色實(shí)心圓代表對(duì)該節(jié)點(diǎn)的計(jì)算結(jié)果輸出到下一層或下一次計(jì)算;空心圓則表示該節(jié)點(diǎn)的計(jì)算結(jié)果沒(méi)有輸入到網(wǎng)絡(luò)或者沒(méi)有從上一次收到信號(hào)。

Python中實(shí)現(xiàn)LSTM模型搭建

Python中有不少包可以直接調(diào)用來(lái)構(gòu)建LSTM模型,比如pybrain, kears, tensorflow, cikit-neuralnetwork等(更多戳這里)。這里我們選用keras。(PS:如果操作系統(tǒng)用的linux或者mac,強(qiáng)推Tensorflow?。。。?/p>

因?yàn)長(zhǎng)STM神經(jīng)網(wǎng)絡(luò)模型的訓(xùn)練可以通過(guò)調(diào)整很多參數(shù)來(lái)優(yōu)化,例如activation函數(shù),LSTM層數(shù),輸入輸出的變量維度等,調(diào)節(jié)過(guò)程相當(dāng)復(fù)雜。這里只舉一個(gè)最簡(jiǎn)單的應(yīng)用例子來(lái)描述LSTM的搭建過(guò)程。

應(yīng)用實(shí)例

基于某家店的某顧客的歷史消費(fèi)的時(shí)間推測(cè)該顧客前下次來(lái)店的時(shí)間。具體數(shù)據(jù)如下所示:

消費(fèi)時(shí)間

2015-05-15 14:03:512015-05-15 15:32:462015-06-28 18:00:172015-07-16 21:27:182015-07-16 22:04:512015-09-08 14:59:56..

..

具體操作:

1. 原始數(shù)據(jù)轉(zhuǎn)化

首先需要將時(shí)間點(diǎn)數(shù)據(jù)進(jìn)行數(shù)值化。將具體時(shí)間轉(zhuǎn)化為時(shí)間段用于表示該用戶相鄰兩次消費(fèi)的時(shí)間間隔,然后再導(dǎo)入模型進(jìn)行訓(xùn)練是比較常用的手段。轉(zhuǎn)化后的數(shù)據(jù)如下:

消費(fèi)間隔04418054..

..

2.生成模型訓(xùn)練數(shù)據(jù)集(確定訓(xùn)練集的窗口長(zhǎng)度)

這里的窗口指需要幾次消費(fèi)間隔用來(lái)預(yù)測(cè)下一次的消費(fèi)間隔。這里我們先采用窗口長(zhǎng)度為3, 即用t-2, t-1,t次的消費(fèi)間隔進(jìn)行模型訓(xùn)練,然后用t+1次間隔對(duì)結(jié)果進(jìn)行驗(yàn)證。數(shù)據(jù)集格式如下:X為訓(xùn)練數(shù)據(jù),Y為驗(yàn)證數(shù)據(jù)。

PS: 這里說(shuō)確定也不太合適,因?yàn)榇翱陂L(zhǎng)度需要根據(jù)模型驗(yàn)證結(jié)果進(jìn)行調(diào)整的。

X1 ? ?X2 ? ?X3 ? ?Y0 ? ?44 ? ?18 ? ?044 ? ?18 ? ?0 ? ?54..

.. ? ?

注:直接這樣預(yù)測(cè)一般精度會(huì)比較差,可以把預(yù)測(cè)值Y根據(jù)數(shù)值bin到幾類,然后用轉(zhuǎn)換成one-hot標(biāo)簽再來(lái)訓(xùn)練會(huì)比較好。比如如果把Y按數(shù)值范圍分到五類(1:0-20,2:20-40,3:40-60,4:60-80,5:80-100)上式可化為:

X1 ? ?X2 ? ?X3 ? ?Y0 ? ?44 ? ?18 ? ?044 ? ?18 ? ?0 ? ?4...

Y轉(zhuǎn)化成one-hot以后則是(關(guān)于one-hot編碼可以參考這里)

1 ? ?0 ? ?0 ? ?0 ? ?00 ? ?0 ? ?0 ? ?0 ? ?1...

3. 網(wǎng)絡(luò)模型結(jié)構(gòu)的確定和調(diào)整

這里我們使用python的keras庫(kù)。(用java的同學(xué)可以參考下deeplearning4j這個(gè)庫(kù))。網(wǎng)絡(luò)的訓(xùn)練過(guò)程設(shè)計(jì)到許多參數(shù)的調(diào)整:比如

需要確定LSTM模塊的激活函數(shù)(activation fucntion)(keras中默認(rèn)的是tanh);

確定接收LSTM輸出的完全連接人工神經(jīng)網(wǎng)絡(luò)(fully-connected artificial neural network)的激活函數(shù)(keras中默認(rèn)為linear);

確定每一層網(wǎng)絡(luò)節(jié)點(diǎn)的舍棄率(為了防止過(guò)度擬合(overfit)),這里我們默認(rèn)值設(shè)定為0.2;

確定誤差的計(jì)算方式,這里我們使用均方誤差(mean squared error);

確定權(quán)重參數(shù)的迭代更新方式,這里我們采用RMSprop算法,通常用于RNN網(wǎng)絡(luò)。

確定模型訓(xùn)練的epoch和batch size(關(guān)于模型的這兩個(gè)參數(shù)具體解釋戳這里)

一般來(lái)說(shuō)LSTM模塊的層數(shù)越多(一般不超過(guò)3層,再多訓(xùn)練的時(shí)候就比較難收斂),對(duì)高級(jí)別的時(shí)間表示的學(xué)習(xí)能力越強(qiáng);同時(shí),最后會(huì)加一層普通的神經(jīng)網(wǎng)路層用于輸出結(jié)果的降維。典型結(jié)構(gòu)如下:

如果需要將多個(gè)序列進(jìn)行同一個(gè)模型的訓(xùn)練,可以將序列分別輸入到獨(dú)立的LSTM模塊然后輸出結(jié)果合并后輸入到普通層。結(jié)構(gòu)如下:

4. 模型訓(xùn)練和結(jié)果預(yù)測(cè)

將上述數(shù)據(jù)集按4:1的比例隨機(jī)拆分為訓(xùn)練集和驗(yàn)證集,這是為了防止過(guò)度擬合。訓(xùn)練模型。然后將數(shù)據(jù)的X列作為參數(shù)導(dǎo)入模型便可得到預(yù)測(cè)值,與實(shí)際的Y值相比便可得到該模型的優(yōu)劣。

實(shí)現(xiàn)代碼

時(shí)間間隔序列格式化成所需的訓(xùn)練集格式

import pandas as pdimport numpy as npdef create_interval_dataset(dataset, look_back):

""" ? ?:param dataset: input array of time intervals ? ?:param look_back: each training set feature length ? ?:return: convert an array of values into a dataset matrix. ? ?"""

dataX, dataY = [], [] ? ?for i in range(len(dataset) - look_back):

?dataX.append(dataset[i:i+look_back])

?dataY.append(dataset[i+look_back]) ? ?return np.asarray(dataX), np.asarray(dataY)

df = pd.read_csv("path-to-your-time-interval-file") ? ?

dataset_init = np.asarray(df) ? ?# if only 1 columndataX, dataY = create_interval_dataset(dataset, lookback=3) ? ?# look back if the training set sequence length

這里的輸入數(shù)據(jù)來(lái)源是csv文件,如果輸入數(shù)據(jù)是來(lái)自數(shù)據(jù)庫(kù)的話可以參考這里

LSTM網(wǎng)絡(luò)結(jié)構(gòu)搭建

import pandas as pdimport numpy as npimport randomfrom keras.models import Sequential, model_from_jsonfrom keras.layers import Dense, LSTM, Dropoutclass NeuralNetwork():

def __init__(self, **kwargs):

?""" ? ? ? ?:param **kwargs: output_dim=4: output dimension of LSTM layer; activation_lstm='tanh': activation function for LSTM layers; activation_dense='relu': activation function for Dense layer; activation_last='sigmoid': activation function for last layer; drop_out=0.2: fraction of input units to drop; np_epoch=10, the number of epoches to train the model. epoch is one forward pass and one backward pass of all the training examples; batch_size=32: number of samples per gradient update. The higher the batch size, the more memory space you'll need; loss='mean_square_error': loss function; optimizer='rmsprop' ? ? ? ?"""

?self.output_dim = kwargs.get('output_dim', 8) ? ? ? ?self.activation_lstm = kwargs.get('activation_lstm', 'relu') ? ? ? ?self.activation_dense = kwargs.get('activation_dense', 'relu') ? ? ? ?self.activation_last = kwargs.get('activation_last', 'softmax') ? ?# softmax for multiple output

?self.dense_layer = kwargs.get('dense_layer', 2) ? ? # at least 2 layers

?self.lstm_layer = kwargs.get('lstm_layer', 2) ? ? ? ?self.drop_out = kwargs.get('drop_out', 0.2) ? ? ? ?self.nb_epoch = kwargs.get('nb_epoch', 10) ? ? ? ?self.batch_size = kwargs.get('batch_size', 100) ? ? ? ?self.loss = kwargs.get('loss', 'categorical_crossentropy') ? ? ? ?self.optimizer = kwargs.get('optimizer', 'rmsprop') ? ? ? ?def NN_model(self, trainX, trainY, testX, testY):

?""" ? ? ? ?:param trainX: training data set ? ? ? ?:param trainY: expect value of training data ? ? ? ?:param testX: test data set ? ? ? ?:param testY: epect value of test data ? ? ? ?:return: model after training ? ? ? ?"""

?print "Training model is LSTM network!"

?input_dim = trainX[1].shape[1]

?output_dim = trainY.shape[1] # one-hot label

?# print predefined parameters of current model:

?model = Sequential() ? ? ? ?# applying a LSTM layer with x dim output and y dim input. Use dropout parameter to avoid overfitting

?model.add(LSTM(output_dim=self.output_dim,

? ? ? ? ? ? ? ? input_dim=input_dim,

? ? ? ? ? ? ? ? activation=self.activation_lstm,

? ? ? ? ? ? ? ? dropout_U=self.drop_out,

? ? ? ? ? ? ? ? return_sequences=True)) ? ? ? ?for i in range(self.lstm_layer-2):

? ? ?model.add(LSTM(output_dim=self.output_dim,

? ? ? ? ? ? ? ? input_dim=self.output_dim,

? ? ? ? ? ? ? ? activation=self.activation_lstm,

? ? ? ? ? ? ? ? dropout_U=self.drop_out,

? ? ? ? ? ? ? ? return_sequences=True)) ? ? ? ?# argument return_sequences should be false in last lstm layer to avoid input dimension incompatibility with dense layer

?model.add(LSTM(output_dim=self.output_dim,

? ? ? ? ? ? ? ? input_dim=self.output_dim,

? ? ? ? ? ? ? ? activation=self.activation_lstm,

? ? ? ? ? ? ? ? dropout_U=self.drop_out)) ? ? ? ?for i in range(self.dense_layer-1):

? ? ?model.add(Dense(output_dim=self.output_dim,

? ? ? ? ? ? ? ? ?activation=self.activation_last))

?model.add(Dense(output_dim=output_dim,

? ? ? ? ? ? ? ? ?input_dim=self.output_dim,

? ? ? ? ? ? ? ? ?activation=self.activation_last)) ? ? ? ?# configure the learning process

?model.compile(loss=self.loss, optimizer=self.optimizer, metrics=['accuracy']) ? ? ? ?# train the model with fixed number of epoches

?model.fit(x=trainX, y=trainY, nb_epoch=self.nb_epoch, batch_size=self.batch_size, validation_data=(testX, testY)) ? ? ? ?# store model to json file

?model_json = model.to_json() ? ? ? ?with open(model_path, "w") as json_file:

? ? ?json_file.write(model_json) ? ? ? ?# store model weights to hdf5 file

?if model_weight_path: ? ? ? ? ? ?if os.path.exists(model_weight_path):

? ? ? ? ?os.remove(model_weight_path)

? ? ?model.save_weights(model_weight_path) # eg: model_weight.h5

?return model

這里寫的只涉及LSTM網(wǎng)絡(luò)的結(jié)構(gòu)搭建,至于如何把數(shù)據(jù)處理規(guī)范化成網(wǎng)絡(luò)所需的結(jié)構(gòu)以及把模型預(yù)測(cè)結(jié)果與實(shí)際值比較統(tǒng)計(jì)的可視化,就需要根據(jù)實(shí)際情況做調(diào)整了。

如何自定義LSTM的initial state

State 不是 Tuple 時(shí),代碼如下。一個(gè)epoch的最開始,我們要把一個(gè) 全零array,輸入到 initial_state 中,然后輸出 finial_state 覆蓋到 state 中,然后執(zhí)行下一個(gè)迭代。

但是當(dāng)LSTM設(shè)置為 state is tuple, TensorFlow是返回一個(gè)LSTMStateTuple的,是不可以通過(guò)eval() 來(lái)得到參數(shù)的,而且也不能被feed!!

網(wǎng)頁(yè)名稱:lstm代碼java lstm代碼keras
分享鏈接:http://muchs.cn/article14/doscpge.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營(yíng)銷型網(wǎng)站建設(shè)、App設(shè)計(jì)企業(yè)網(wǎng)站制作、商城網(wǎng)站、建站公司電子商務(wù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)