目錄
1、rnn是什么
2、原理說明
2.1 rnn 和全連接神經網略的區別
2.2 RNN 簡單圖解釋
2.3 RNN展開圖解釋
2.4 RNN的一些點
3、rnn的偽代碼表示
4、來個小例子
5、rnn存在的問題
6、總結
最近寫了一些基礎的東西,總是理解性的,沒有看到實體,今天就講一個基礎的網路結構RNN,然后寫個實體,體驗下深度神經網路的牛逼,這次學習下rnn神經網路,雖然看起來好高深,不過不用慌,沒有理論,全是大白話,大家都可以懂的,
注:閱讀的時候希望先看下目錄,知道我在說什么,也可以快速的閱讀到自己想get的點,這樣閱讀能更快的理解,
1、rnn是什么
RNN 是回圈神經網路的簡稱,他的英語是 Rerrent Neural Network = RNN,從命名中可以看到核心點是回圈的神經網路,所以我們要理解回圈的是什么?為什么要回圈,這個會慢慢解釋,不用著急,
RNN對具有序列特性的資料非常有效,它能挖掘資料中的時序資訊以及語意資訊,用人話解釋就是RNN具有語境資訊,可以理解背景關系,在你進行分析的時候可以對全域進行考慮,可以用來挖掘資料之間的關系,
舉個例子:我不喜歡美女,對文字進行拆分,我,不,喜歡,美女,在普通的全連接的神經網路中會每個詞是鼓勵的,沒有關系的,通過大量的函式去擬合資料,這個時候機器可能理解的就是喜歡美女,沒有考慮到前面的“不”帶來的語境資訊,
RNN 可以解決這個問題,RNN 會記錄整個句子出現的資訊,然后進行綜合評判,最后才得出結論,
總結下:RNN神經網路善于發現資料之間的關系,
2、原理說明
2.1 rnn 和全連接神經網略的區別
普通的全連接的神經網路像下面這樣,每個屬性是獨立的,然后通過大量的函式引數進行擬合,然后進行處理,得出自己的結論,就像上篇入門的時候對函式的擬合,可以看出每個資料之間并沒有什么關聯
![]()

再看看我們今天說的RNN,回圈的神經網路,注:這張圖來自百度,我為什么要展示這張圖吶?雖然我想用最直白的話給描述RNN,但是以后你可能會查閱資料,會頻繁的看到這張圖,所以我貼進來,以免下次遇到的時候沒辦法理解,因為這個圖理解起來還是不那么好理解,當然如果你理解了RNN可能會明白,但是對于入門的我們來說還是有點費勁的,

2.2 RNN 簡單圖解釋
左邊的部分是沒展開的RNN的見圖,到這里可以看到回圈神經網路的回圈在哪里了
x是一個向量,它表示輸入層的值
U是輸入層到隱藏層的權重矩陣
s是一個向量,它表示隱藏層的值
V是隱藏層到輸出層的權重矩陣,
o也是一個向量,它表示輸出層的值
用函式表示 :

用代碼簡單的理解下
def getHidenS(x,w,prevS):
return x * u + prevS*w
def getOutput(s):
return s * v
2.3 RNN展開圖解釋
右邊的圖看起來很簡單,但是下面的 x 增加了時間序列,這里的x 表示時間上的輸入單詞,舉個例子:
比如:我愛中國,這個詞序列,t-1 就是我 這個詞的向量表示,愛 就是 t 這個詞的向量表示,t+1 就是中國這個詞的向量表示
o就是在輸入每個單詞時神經網路的輸出,也就是說每次輸入一個詞向量的時候都會有一個輸出,最后得出結論可以使用其中一個,或者綜合考慮都可以,根據自己的需求
2.4 RNN的一些點
公用引數:RNN的時間序列公用引數,也就是說整個RNN公用一組引數,不同的時間點的輸入的時候,神經網路的權重引數都是一組,也就是說只有一組W引數,
具有記憶功能:記憶功能的實作是基于隱藏層的輸出值實作的,因為隱藏層會將上一次的資訊進行保存
3、rnn的偽代碼表示
對”我愛中國“進行編碼,我= 1 愛 = 2 中國=3
輸入 x = [1,2,3]
w = 1 # 權重矩陣
u = 1 # 輸入層到隱藏層的矩陣
v = 2 # 隱藏層到輸出層的矩陣
prevS = 1 # 隱藏層的輸出值
def getHidenS(x, w, prevS):
return x * u + prevS * w
def getOutput(s,v):
return s * v
sentance = [1,2,3]
for x in sentance:
prevS = getHidenS(x,u,prevS)
o = getOutput(prevS,v)
print('隱藏層的值:'+ str(prevS))
print('輸出層的值 :'+str(o))
print('----------------------')
prevS 保存了之前的記憶,每一次的輸出都可以用來判斷

4、來個小例子
import torch
from torch import nn
import numpy as np
import matplotlib.pyplot as plt
# https://www.cnblogs.com/lokvahkoor/p/12263953.html
# torch.manual_seed(1) # reproducible
# 超引數定義
TIME_STEP = 10 # rnn time step
INPUT_SIZE = 1 # rnn input size
LR = 0.02 # 學習率
HIDDEN_SIZE = 32# 隱藏層神經元個數
EPOCH = 100
# 橫向坐標,產出100個float點
steps = np.linspace(0, np.pi * 2, 100, dtype=np.float32) # float32 for converting torch FloatTensor
x_np = np.sin(steps)
y_np = np.cos(steps)
# 輸入的引數是sin的序列,輸出是余弦序列
plt.plot(steps, y_np, 'r-', label='target (cos)')
plt.plot(steps, x_np, 'b-', label='input (sin)')
plt.legend(loc='best')
plt.show()
input("請回車:")
class RNN(nn.Module):
def __init__(self):
super(RNN, self).__init__()
self.rnn = nn.RNN(
input_size=INPUT_SIZE,
hidden_size=HIDDEN_SIZE, # 隱藏神經元的數量
num_layers=1, # 一層rnn
batch_first=True, # input & output will has batch size as 1s dimension. e.g. (batch, time_step, input_size)
)
self.out = nn.Linear(HIDDEN_SIZE, 1)
def forward(self, x, h_state):
# x = (batch, time_step, input_size)
# h_state = (n_layers, batch, hidden_size)
# r_out = (batch, time_step, hidden_size)
out, h_state = self.rnn(x, h_state)
out = out.view(-1, HIDDEN_SIZE) #(10,32)
out = self.out(out) #(10,1)
out = out.unsqueeze(dim=0) # (1,10,1) -> (n_layers, batch, hidden_size)
return out, h_state
rnn = RNN()
print(rnn)
optimizer = torch.optim.Adam(rnn.parameters(), lr=LR) # 優化器
loss_func = nn.MSELoss() # 損失函式
h_state = None # 隱藏層的輸出值
plt.figure(1, figsize=(12, 5))
plt.ion() # continuously plot
for step in range(EPOCH):
# 每次生成新的資料,整體的趨勢是擬合成cos函式曲線
start, end = step * np.pi, (step + 1) * np.pi # time range
# use sin predicts cos
steps = np.linspace(start, end, TIME_STEP, dtype=np.float32,
endpoint=False) # float32 for converting torch FloatTensor
x_np = np.sin(steps)
y_np = np.cos(steps)
# np.newaxis的功能:插入新維度,(1,10,1)
# shape (batch, time_step, input_size)
# 表示每一批送進去一個
x = torch.from_numpy(x_np[np.newaxis, :, np.newaxis])
y = torch.from_numpy(y_np[np.newaxis, :, np.newaxis])
prediction, h_state = rnn(x, h_state) # 計算輸出
# 將上一步的隱藏層的結果進行保存,在下次輸入
h_state = h_state.data # repack the hidden state, break the connection from last iteration
loss = loss_func(prediction, y) # 計算誤差
optimizer.zero_grad() # 清除之前的梯度
loss.backward() # 反向傳播
optimizer.step() # 優化引數
# 開始畫圖
plt.plot(steps, y_np.flatten(), 'r-')
plt.plot(steps, prediction.data.numpy().flatten(), 'b-')
plt.draw()
plt.pause(0.05)
plt.ioff()
plt.show()
看一下最后的擬合結果:
![]()

5、rnn存在的問題
對于梯度消失: 由于它們都有特殊的方式存盤”記憶”,那么以前梯度比較大的”記憶”不會像簡單的RNN一樣馬上被抹除,因此可以一定程度上克服梯度消失問題,
對于梯度爆炸:用來克服梯度爆炸的問題就是gradient clipping,也就是當你計算的梯度超過閾值c或者小于閾值-c的時候,便把此時的梯度設定成c或-c,
6、總結
RNN的關鍵點是記憶功能,也就是保存了語境資訊,但是也存在一些問題,后面我們會分析怎么解決這個問題,
原創不容易,求點贊支持,為愛發電,
推薦閱讀 點擊標題可跳轉
1、再不入坑就晚了,從零學pytorch,一步一步環境搭建
2、再不入坑就晚了,深度神經網路概念大整理,最簡單的神經網路是什么樣子?
3、深度學習基礎之三分鐘輕松搞明白tensor到底是個啥

書分為 11章,涵蓋的主要內容有神經網路概述,神經網路基礎知識,計算機程式的特點,神經網路優化演算法,搭 建Python環境,Python基礎知識,深度學習框架PyTorch基礎知識,NumPy簡介與使用,OpenCV簡介與使用,OS遍歷檔案夾,Python中Matplotlib可視化繪圖,Lenet-5、AlexNet、VGG16網路模型,回歸問題和分類問題,貓狗識別程式開發,驗證碼識別程式開發,過擬合問題與解決方法,梯度消失與爆炸,加速神經網路訓練的方法,人工智能的未來發展趨勢等,
京東自營購買鏈接:
《Python神經網路入門與實戰》(王凱)【摘要 書評 試讀】- 京東圖書
當當自營購買鏈接:
《Python神經網路入門與實戰》(王凱)【簡介_書評_在線閱讀】 - 當當圖書
大家點贊關注,三天后在留言的同學中抽取送一本書
注:如果中獎了沒關注則放棄
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/300408.html
標籤:AI
上一篇:?機器學習?交替方向乘數法(Alternating Direction Method of Multipliers,ADMM)
