RNN概述 深度學習 神經網路

2022-09-02 07:30:16 字數 4906 閱讀 5539

一 rnn概述

前面我們敘述了bp演算法, cnn演算法, 那麼為什麼還會有rnn呢?? 什麼是rnn, 它到底有什麼不同之處? rnn的主要應用領域有哪些呢?這些都是要討論的問題.

1) bp演算法,cnn之後, 為什麼還有rnn?

2) 什麼是rnn?

rnn是一種特殊的神經網路結構, 它是根據"人的認知是基於過往的經驗和記憶"這一觀點提出的. 它與dnn,cnn不同的是: 它不僅考慮前一時刻的輸入,而且賦予了網路對前面的內容的一種'記憶'功能.

rnn之所以稱為迴圈神經網路,即乙個序列當前的輸出與前面的輸出也有關。具體的表現形式為網路會對前面的資訊進行記憶並應用於當前輸出的計算中,即隱藏層之間的節點不再無連線而是有連線的,並且隱藏層的輸入不僅包括輸入層的輸出還包括上一時刻隱藏層的輸出。

3) rnn的主要應用領域有哪些呢?

rnn的應用領域有很多, 可以說只要考慮時間先後順序的問題都可以使用rnn來解決.這裡主要說一下幾個常見的應用領域:

② 機器翻譯, 機器寫**

③ 語音識別

④ 影象描述生成

⑤ 文字相似度計算

二 rnn(迴圈神經網路)

1) rnn模型結構

前面我們說了rnn具有時間"記憶"的功能, 那麼它是怎麼實現所謂的"記憶"的呢?

圖1 rnn結構圖 

如圖1所示, 我們可以看到rnn層級結構較之於cnn來說比較簡單, 它主要有輸入層,hidden layer, 輸出層組成.

並且會發現在hidden layer 有乙個箭頭表示資料的迴圈更新, 這個就是實現時間記憶功能的方法.

如果到這裡你還是沒有搞懂rnn到底是什麼意思,那麼請繼續往下看!

圖2 hidden layer的層級展開圖

如圖2所示為hidden layer的層級展開圖. t-1, t, t+1表示時間序列. x表示輸入的樣本. st表示樣本在時間t處的的記憶,st = f(w*st-1 +u*xt). w表示輸入的權重, u表示此刻輸入的樣本的權重, v表示輸出的樣本權重.

在t =1時刻, 一般初始化輸入s0=0, 隨機初始化w,u,v, 進行下面的公式計算:

其中,f和g均為啟用函式. 其中f可以是tanh,relu,sigmoid等啟用函式,g通常是softmax也可以是其他。

時間就向前推進,此時的狀態s1作為時刻1的記憶狀態將參與下乙個時刻的**活動,也就是:

以此類推, 可以得到最終的輸出值為:

注意: 1. 這裡的w,u,v在每個時刻都是相等的(權重共享).

2. 隱藏狀態可以理解為:  s=f(現有的輸入+過去記憶總結) 

2) rnn的反向傳播

前面我們介紹了rnn的前向傳播的方式, 那麼rnn的權重引數w,u,v都是怎麼更新的呢?

每一次的輸出值ot都會產生乙個誤差值et, 則總的誤差可以表示為:.

則損失函式可以使用交叉熵損失函式也可以使用平方誤差損失函式.

由於每一步的輸出不僅僅依賴當前步的網路,並且還需要前若干步網路的狀態,那麼這種bp改版的演算法叫做backpropagation through time(bptt) , 也就是將輸出端的誤差值反向傳遞,運用梯度下降法進行更新.(不熟悉bp的可以參考這裡)

也就是要求引數的梯度:

首先我們求解w的更新方法, 由前面的w的更新可以看出它是每個時刻的偏差的偏導數之和. 

在這裡我們以 t = 3時刻為例, 根據鏈式求導法則可以得到t = 3時刻的偏導數為:

此時, 根據公式我們會發現, s3除了和w有關之外, 還和前一時刻s2有關.

對於s3直接展開得到下面的式子:

對於s2直接展開得到下面的式子:

對於s1直接展開得到下面的式子:

將上述三個式子合併得到:

這樣就得到了公式:

這裡要說明的是:表示的是s3對w直接求導, 不考慮s2的影響.(也就是例如y = f(x)*g(x)對x求導一樣)

其次是對u的更新方法. 由於引數u求解和w求解類似,這裡就不在贅述了,最終得到的具體的公式如下:

最後,給出v的更新公式(v只和輸出o有關):

三 rnn的一些改進演算法

前面我們介紹了rnn的演算法, 它處理時間序列的問題的效果很好, 但是仍然存在著一些問題, 其中較為嚴重的是容易出現梯度消失或者梯度**的問題(bp演算法和長時間依賴造成的). 注意: 這裡的梯度消失和bp的不一樣,這裡主要指由於時間過長而造成記憶值較小的現象.

因此, 就出現了一系列的改進的演算法, 這裡介紹主要的兩種演算法: lstm 和 gru.

lstm 和 gru對於梯度消失或者梯度**的問題處理方法主要是:

對於梯度消失: 由於它們都有特殊的方式儲存」記憶」,那麼以前梯度比較大的」記憶」不會像簡單的rnn一樣馬上被抹除,因此可以一定程度上克服梯度消失問題。

對於梯度**:用來克服梯度**的問題就是gradient clipping,也就是當你計算的梯度超過閾值c或者小於閾值-c的時候,便把此時的梯度設定成c或-c。 

1) lstm演算法(long short term memory, 長短期記憶網路 ) --- 重要的目前使用最多的時間序列演算法

圖3 lstm演算法結構圖

如圖3為lstm演算法的結構圖. 

和rnn不同的是: rnn中,就是個簡單的線性求和的過程. 而lstm可以通過「門」結構來去除或者增加「細胞狀態」的資訊,實現了對重要內容的保留和對不重要內容的去除. 通過sigmoid層輸出乙個0到1之間的概率值,描述每個部分有多少量可以通過,0表示「不允許任務變數通過」,1表示「執行所有變數通過 」.

用於遺忘的門叫做"遺忘門", 用於資訊增加的叫做"資訊增加門",最後是用於輸出的"輸出門". 這裡就不展開介紹了.

此外,lstm演算法的還有一些變種.

如圖4所示, 它增加「peephole connections」層 , 讓門層也接受細胞狀態的輸入.

圖4 lstm演算法的乙個變種

如圖5所示為lstm的另外一種變種演算法.它是通過耦合忘記門和更新輸入門(第乙個和第二個門);也就是不再單獨的考慮忘記什麼、增加什麼資訊,而是一起進行考慮。

圖5 lstm演算法的乙個變種

2) gru演算法

gru是2023年提出的一種lstm改進演算法. 它將忘記門和輸入門合併成為乙個單一的更新門, 同時合併了資料單元狀態和隱藏狀態, 使得模型結構比之於lstm更為簡單.

其各個部分滿足關係式如下:

四 基於tensorflow的基本操作和總結

使用tensorflow的基本操作如下:

# _*_coding:utf-8_*_

import tensorflow as tf

import numpy as np

'''tensorflow中的rnn的api主要包括以下兩個路徑:

1) tf.nn.rnn_cell(主要定義rnn的幾種常見的cell)

2) tf.nn(rnn中的輔助操作)

'''# 一 rnn中的cell

# 基類(最頂級的父類): tf.nn.rnn_cell.rnncell()

# 最基礎的rnn的實現: tf.nn.rnn_cell.basicrnncell()

# 簡單的lstm cell實現: tf.nn.rnn_cell.basiclstmcell()

# 最常用的lstm實現: tf.nn.rnn_cell.lstmcell()

# rgu cell實現: tf.nn.rnn_cell.grucell()

# 多層rnn結構網路的實現: tf.nn.rnn_cell.multirnncell()

# 建立cell

# cell = tf.nn.rnn_cell.basicrnncell(num_units=128)

# print(cell.state_size)

# print(cell.output_size)

# shape=[4, 64]表示每次輸入4個樣本, 每個樣本有64個特徵

# inputs = tf.placeholder(dtype=tf.float32, shape=[4, 64])

# 給定rnn的初始狀態

# s0 = cell.zero_state(4, tf.float32)

# print(s0.get_shape())

# 對於t=1時刻傳入輸入和state0,獲取結果值

# output, s1 = cell.call(inputs, s0)

# print(output.get_shape())

# print(s1.get_shape())

# 定義lstm cell

lstm_cell = tf.nn.rnn_cell.lstmcell(num_units=128)

# shape=[4, 64]表示每次輸入4個樣本, 每個樣本有64個特徵

inputs = tf.placeholder(tf.float32, shape=[4, 48])

# 給定初始狀態

s0 = lstm_cell.zero_state(4, tf.float32)

# 對於t=1時刻傳入輸入和state0,獲取結果值

output, s1 = lstm_cell.call(inputs, s0)

print(output.get_shape())

print(s1.h.get_shape())

print(s1.c.get_shape())

當然, 你可能會發現使用cell.call()每次只能呼叫乙個得到乙個狀態, 如有多個狀態需要多次重複呼叫較為麻煩, 那麼我們怎麼解決的呢? 可以參照後面的基於rnn的手寫數字識別和單詞**的例項查詢解決方法.

本文主要介紹了一種時間序列的rnn神經網路及其基礎上衍生出來的變種演算法lstm和gru演算法, 也對rnn演算法的使用場景作了介紹. 

當然, 由於篇幅限制, 這裡對於雙向rnns和多層的rnns沒有介紹. 另外, 對於lstm的引數更新演算法在這裡也沒有介紹, 後續補上吧!

最後, 如果你發現了任何問題, 歡迎一起**, 共同進步!!

---------------------

深度學習 迴圈神經網路(RNN)

迴圈神經網路 rnn 目錄 情感分類 正面,負面 前向傳播和反向傳播 1 前向傳播 2 反向傳播 gru lstm 一 gru gated recurrent unit 二 lstm long short term memory 零基礎入門深度學習 6 長短時記憶網路 lstm word2vec數學...

深度學習與神經網路(八) 迴圈神經網路RNN

首先看乙個簡單案例,在某寶的好評 差評檢測中,系統要能夠分析使用者的評價是好評還是差評,那怎樣處理這樣的評價資料呢,例如有一條評價 i hate this boring movie 機器怎樣解決這樣的問題呢 首先我們在之前的時間序列表示中已經知道了怎樣對乙個單詞進行表示。如果使用glove的話,整句...

機器學習,深度學習,神經網路,深度神經網路

先來說一下這幾者之間的關係 人工智慧包含機器學習,機器學習包含深度學習 是其中比較重要的分支 深度學習源自於人工神經網路的研究,但是並不完全等於傳統神經網路。所以深度學習可以說是在傳統神經網路基礎上的公升級。神經網路一般有輸入層 隱藏層 輸出層,一般來說隱藏層大於2的神經網路就叫做深度神經網路,深度...