1. 程式人生 > >【機器學習筆記24】神經網路(LSTM)

【機器學習筆記24】神經網路(LSTM)

梯度消失原因

TBD

模型定義

LSTM 長短期記憶網路是一種特殊的RNN,為解決梯度爆炸和梯度消失的問題,LSTM將RNN中普通的神經元替換成了擁有少量記憶的LSTM單元。 在這裡插入圖片描述

第一步: 決定丟棄資訊 在這裡插入圖片描述

第二步: 確定更新資訊 在這裡插入圖片描述

第三步: 更新狀態

在這裡插入圖片描述

第四步: 確定輸出 在這裡插入圖片描述

備註:σ\sigma代表sigmoid函式

LSTM程式碼例子(keras)
# -*- coding: utf-8 -*-

"""
說明:

LSTM分類程式碼DEMO,對應的筆記《神經網路(LSTM)》

作者:fredric

日期:2018-9-23

"""

from keras.layers import Dense,Activation
from keras.layers.recurrent import LSTM
from keras.models import Sequential
from keras.optimizers import Adam
import numpy as np
 
### 載入資料
### Test.java是隨便Java專案裡找的一批程式碼合併到一個檔案裡
fin=open('./data/Test.java','rb')
lines=[]
for line in fin:
    line=line.strip().lower()
    line=line.decode('ascii','ignore')
    if len(line)==0:
        continue
    lines.append(line)
fin.close()
text=' '.join(lines)
 
"""
對樣本Test.java中的所有字元生成字典索引,包括:
char2index: '}': 0, 't': 1, 'k': 2 等
index2char: 0: '}', 1: 't', 2: 'k' 等
"""
chars=set([c for c in text])
nb_chars=len(chars)
char2index=dict((c,i) for i,c in enumerate(chars))
index2char=dict((i,c) for i,c in enumerate(chars))
 
SEQLEN=10
STEP=1
 
input_chars=[]
label_chars=[]
 

"""
不段以SEQLEN為長度,STEP為偏移生成input_chars和label_chars
舉例:
以原檔案程式碼package com.fredric為例子,生成

input_chars[0]: package co    label_chars[0]: m 
label_chars[1]: ackage com    label_chars[0]: . 

"""
for i in range(0,len(text)-SEQLEN,STEP):
    input_chars.append(text[i:i+SEQLEN])
    label_chars.append(text[i+SEQLEN])



"""
這裡將輸入向量利用char2index做了一個變換,例如:

第一個輸入的label輸出m,則對應字典中的 9: 'm',因此此時的y值為:
[False False False False False False False False False  True False False
 False False False False False False False False False False False False
 False False False False False False False False False False False False
 False False False False False False False False False False False False
 False]

同理x的值也被做了上述的變換,重要: 相當於所有的輸入被做了統一的編碼

"""

X=np.zeros((len(input_chars),SEQLEN,nb_chars),dtype=np.bool)
y=np.zeros((len(input_chars),nb_chars),dtype=np.bool)    
for i,input_char in enumerate(input_chars):
    for j,ch in enumerate(input_char):
        X[i,j,char2index[ch]]=1
    y[i,char2index[label_chars[i]]]=1


### 建立RNN網路
HIDDEN_SIZE = 128
BATCH_SIZE  = 128
TRAIN_STEP  = 50

model=Sequential()
model.add(LSTM(nb_chars))
model.add(Dense(nb_chars,activation='softmax'))
model.compile(loss='categorical_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])


### 進行訓練
for step in range(TRAIN_STEP):
    print("current step is #: %d"%(step))
    model.fit(X,y, batch_size=BATCH_SIZE, epochs=1)

### 對輸入字串進行預測 
_test_input = 'public cla'
_test_chars=set([t for t in _test_input])
_test=np.zeros((1, SEQLEN, nb_chars))

for i,ch in enumerate(_test_chars):
    _test[0,i,char2index[ch]]=1

pred=model.predict(_test,verbose=0)[0]
ypred=index2char[np.argmax(pred)]

print("the test input %s get prediction %s"%(_test_input, ypred)) ##輸出結果為the test input public cla get prediction s