RNN總結


RNN總結

循環神經網絡(Recurrent Neural Network,RNN)是一種用於處理序列數據的神經網絡。相比一般的神經網絡來說,他能夠處理序列變化的數據。比如某個單詞的意思會因為上文提到的內容不同而有不同的含義,RNN 就能夠很好地解決這類問題。

RNN基本結構

這里:

x為當前狀態下數據的輸入, h表示接收到的上一個節點的輸入。

y為當前節點狀態下的輸出,而 h`為傳遞到下一個節點的輸出。

通過上圖的公式可以看到,輸出 h' 與 x 和 h 的值都相關。而 y 則常常使用 h' 投入到一個線性層(主要是進行維度映射)然后使用softmax進行分類得到需要的數據,一般情況下不適用y。

RNN的缺點

使用Rnn會出現長文本處理時候效果很差,是因為Rnn只能記憶最近的序列,記性太差,而且會出現梯度消失、梯度爆炸的情況。

這篇文章已經總結的挺好。

https://www.cnblogs.com/jiangxinyang/p/9362922.html

RNN的分類

  1. sequence-to-sequence:輸入輸出都是一個序列。例如股票預測中的RNN,輸入是前N天價格,輸出明天的股市價格。

  1. sequence-to-vector:輸入是一個序列,輸出單一向量。

  例如,輸入一個電影評價序列,輸出一個分數表示情感趨勢(喜歡還是討厭)。

  1. vector-to-sequence:輸入單一向量,輸出一個序列。

4.Encoder-Decoder:輸入sequence-to-vector,稱作encoder,輸出vector-to-sequence,稱作decoder。

這是一個delay模型,經過一段延遲,即把所有輸入都讀取后,在decoder中獲取輸入並輸出一個序列。這個模型在機器翻譯中使用較廣泛,源語言輸在入放入encoder,濃縮在狀態信息中,生成目標語言時,可以生成一個不長度的目標語言序列。

Pytorch實現RNN

class torch.nn.RNN(args,*kwargs)[source]

注意:

batch_first這個參數為True時候,輸入Tensor的shape是[batch_size,seq_length,feature],關於這個shape問題是,初學者可能對[batch_size,time_step,feature]更為理解,但是在處理序列的時候,應該是[seq_length,batch_size,feature],因為在訓練時候是x0,x1,x2,x3....這樣輸入的,如果是按照[seq_length,batch_size,feature]這種形式,就可以根據序列長度,每次送入batch_size個字符。

rnn的輸入

其中,h_0如果初始值為0,那么可以直接省略

rnn的輸出

rnn的模型參數

使用rnn實現正弦函數預測

import torch
import numpy as np
from torch import nn
import matplotlib.pyplot as plt
num_time_steps=50
input_size=1
hidden_size=16
output_size=1
lr=0.001

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()

        self.model=nn.RNN(
            input_size=input_size,
            hidden_size=hidden_size,
            num_layers=1,
            batch_first=True
        )
        # 這里對參數進行初始化
        for p in self.model.parameters():
            nn.init.normal_(p,mean=0.0,std=0.001)

        self.linear=nn.Linear(hidden_size,output_size)

    def forward(self,x,hidden_prev):
        out,hidden_prev = self.model(x,hidden_prev)

        out=out.view(-1,hidden_size)

        out=self.linear(out)

        out=out.unsqueeze(dim=0)

        return out,hidden_prev


model=Net()

criterion=nn.MSELoss()
optimizer=torch.optim.Adam(model.parameters(),lr)

# h0的初始值
hidden_prev = torch.zeros(1,1,hidden_size)

for iter in range(10000):
    start = np.random.randint(3, size=1)[0]
    time_steps = np.linspace(start, start + 10, num_time_steps)
    data = np.sin(time_steps)
    data = data.reshape(num_time_steps, 1)
    x = torch.tensor(data[:-1]).float().reshape(1, num_time_steps - 1, 1)
    y = torch.tensor(data[1:]).float().reshape(1, num_time_steps - 1, 1)

    output,hidden_prev=model(x,hidden_prev)
    # 這一句是干啥的?
    hidden_prev=hidden_prev.detach()

    loss=criterion(output,y)
    # 這里的 語句和 optimizer.zero_grad()有什么區別
    model.zero_grad()
    loss.backward()

    optimizer.step()

    if iter % 100 ==0:
        print("Iteration: {} loss {}".format(iter,loss.item()))

start = np.random.randint(6,10, size=1)[0]
time_steps = np.linspace(start, start + 10, num_time_steps)
data = np.sin(time_steps)
data = data.reshape(num_time_steps, 1)
x = torch.tensor(data[:-1]).float().reshape(1, num_time_steps - 1, 1)
y = torch.tensor(data[1:]).float().reshape(1, num_time_steps - 1, 1)

prdictions=[]

input=x[:,0,:]

for _ in range(x.shape[1]):
    input=input.view(1,1,1)
    # 這里看不懂
    (pred,hidden_prev) =model(input,hidden_prev)
    input=pred
    prdictions.append(pred.detach().numpy().ravel()[0])
x =x.data.numpy().ravel()
y=y.data.numpy()

plt.scatter(time_steps[:-1],x.ravel(),s=90)
plt.plot(time_steps[:-1],x.ravel())

plt.scatter(time_steps[1:],prdictions)
plt.show()



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM