用純Python實現循環神經網絡RNN向前傳播過程(吳恩達DeepLearning.ai作業)

用純Python實現循環神經網絡RNN向前傳播過程(吳恩達DeepLearning.ai作業)
Google TensorFlow程序員點讚的文章!

 

前言

目錄:

  • 向量表示以及它的維度
  • rnn cell
  • rnn 向前傳播

重點關注:

  • 如何把數據向量化的,它們的維度是怎麼來的
  • 一共其實就是兩步: 單個單元的rnn計算,拉通來的rnn計算

在看本文前,可以先看看這篇文章回憶一下:

吳恩達deepLearning.ai循環神經網絡RNN學習筆記(理論篇)

我們將實現以下結構的RNN,在這個例子中 Tx = Ty。

向量表示以及它的維度

Input with  nx  number of units
對單個輸入樣本,x(i) 是一維輸入向量。
用語言來舉個例子,將具有5k個單詞詞彙量的語言用one-hot編碼成具有5k個單位的向量,所以 x(i) 的維度是(5000,)。
我們將用符號 nx 表示單個訓練樣本的單位數。
Batches of size m
如果我們取小批量(mini-batches),每個批次有20個訓練樣本。
爲了受益於向量化,我們將20個樣本 x(i) 變成一個2維數組(矩陣)。
比如一個維度是(5000,20)的向量。
我們用m來表示訓練樣本的數量。
所以小批量訓練數據的維度是 (nx, m)。
Time steps of size Tx
循環神經網絡有多個時間步驟,我們用t來表示。
我們將看到訓練樣本 x(i) 將經歷多個時間步驟 Tx, 比如如果有10個時間步驟,那麼 Tx = 10。
3D Tensor of shape (nx, m, Tx)
輸入x就是用維度是 (nx, m, Tx) 的三維張量來表示。
Taking a 2D slice for each time step:

每一個時間步驟,我們用小批量訓練樣本(不是單個的訓練樣本)。
所以針對每個時間步驟t,我們用維度是 (nx, m)的2維切片。
我們把它表示成xt。
隱藏狀態a的維度
a的定義: 從一個時間步驟到另一個時間步驟的激活值 at, 我們把它叫做隱藏狀態。
同輸入張量 x 一樣,對於單個訓練樣本的隱藏狀態,它的向量長度是na。
如果我們是包含了m個訓練樣本的小批量數據,那麼小批量維度是 (na, m)。
如果我們把時間步加進去,那麼隱藏狀態的維度就是 (na, m, Tx)。
我們將用索引t來遍歷時間步,每次操作是從3維張量切片成的2維向量。
我們用at來表示2維的切片,它的維度是 (na, m)。
預測值y^的維度
同輸入x和隱藏狀態一樣,y^是一個維度是 (ny, m, Ty) 的3維張量。
ny: 代表預測值的單位數。
m: 小批次訓練的樣本數量。
Ty: 預測的時間數。
比如單個時間步 t,2維的切片 y^ 的維度是 (ny, m)。
 

RNN cell

 

我們的第一個任務就是執行單個時間步驟的計算,計算如下圖。

輸入是a^, xt,輸出是at, yt^。以下的代碼其實就是把上面的公式代碼化,總的步驟分成4步:

取出參數。
計算at。
計算yt^。
返回輸出的at, yt^,還要存儲一些值緩存起來。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
​import numpy as np

def rnn_cell_forward(xt, a_prev, parameters):
    """
    Implements a single forward step of the RNN-cell as described in Figure (2)

    Arguments:
    xt -- your input data at timestep "t", numpy array of shape (n_x, m).
    a_prev -- Hidden state at timestep "t-1", numpy array of shape (n_a, m)
    parameters -- python dictionary containing:
                        Wax -- Weight matrix multiplying the input, numpy array of shape (n_a, n_x)                        Waa -- Weight matrix multiplying the hidden state, numpy array of shape (n_a, n_a)
                        Wya -- Weight matrix relating the hidden-state to the output, numpy array of shape (n_y, n_a)
                        ba --  Bias, numpy array of shape (n_a, 1)
                        by -- Bias relating the hidden-state to the output, numpy array of shape (n_y, 1)
    Returns:
    a_next -- next hidden state, of shape (n_a, m)
    yt_pred -- prediction at timestep "t", numpy array of shape (n_y, m)
    cache -- tuple of values needed for the backward pass, contains (a_next, a_prev, xt, parameters)
    """
    # 取計算的參數
    Wax = parameters["Wax"]
    Waa = parameters["Waa"]
    Wya = parameters["Wya"]
    ba = parameters["ba"]
    by = parameters["by"]

    # 用公式計算下一個單元的激活值
    a_next = np.tanh(np.dot(Waa, a_prev) + np.dot(Wax, xt) + ba)
    # 計算當前cell的輸出
    yt_pred = softmax(np.dot(Wya, a_next) + by)
    
    # 用於向後傳播的緩存值
    cache = (a_next, a_prev, xt, parameters)

    return a_next, yt_pred, cache

RNN向前傳播

一個循環神經網絡就是不斷的重複你上面創建的rnn 單元。
如果你的輸入數據序列是10個時間步,那麼你就要重複你的rnn cell 10次。
在每個時間步中,每個單元將用2個輸入:
a: 前一個單元的隱藏狀態。
xt: 當前時間步的輸入數據。
每個時間步有兩個輸出:
一個隱藏狀態at
一個測值y^⟨t⟩
權重和偏差 (Waa,ba,Wax,bx) 將在每個時間步中循環使用,它們保存在"parameters"的變量中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def rnn_forward(x, a0, parameters):
    """
    Implement the forward propagation of the recurrent neural network described in Figure (3).

    Arguments:
    x -- Input data for every time-step, of shape (n_x, m, T_x).
    a0 -- Initial hidden state, of shape (n_a, m)
    parameters -- python dictionary containing:
                        Waa -- Weight matrix multiplying the hidden state, numpy array of shape (n_a, n_a)
                        Wax -- Weight matrix multiplying the input, numpy array of shape (n_a, n_x)
                        Wya -- Weight matrix relating the hidden-state to the output, numpy array of shape (n_y, n_a)
                        ba --  Bias numpy array of shape (n_a, 1)
                        by -- Bias relating the hidden-state to the output, numpy array of shape (n_y, 1)

    Returns:
    a -- Hidden states for every time-step, numpy array of shape (n_a, m, T_x)
    y_pred -- Predictions for every time-step, numpy array of shape (n_y, m, T_x)
    caches -- tuple of values needed for the backward pass, contains (list of caches, x)
    """

    # 用於存儲所有cache的列表,初始化它
    caches = []

    # 取一些緯度值,用於後面初始化變量
    n_x, m, T_x = x.shape
    n_y, n_a = parameters["Wya"].shape


    # 初始化 a 和 y_pred
    a = np.zeros((n_a, m, T_x))
    y_pred = np.zeros((n_y, m, T_x))

    # 初始化 a_next
    a_next = a0

    # loop over all time-steps of the input 'x'
    for t in range(T_x):
        # Update next hidden state, compute the prediction, get the cache
        xt = x[:,:,t] # 通過切片的方式從輸入變量x中取出當前t時間步的輸入xt
        a_next, yt_pred, cache = rnn_cell_forward(xt, a_next, parameters)
        # 保存當前單元計算的a_next值

        a[:,:,t] = a_next
        # 保存當前單元的預測值y

        y_pred[:,:,t] = yt_pred
        # 添加每個單元的緩存值
        caches.append(cache)


    # store values needed for backward propagation in cache
    caches = (caches, x)

    return a, y_pred, caches

恭喜你(^▽^),到這裏你已經能夠從0到1的構建循環神經網絡的向前傳播過程。

在現代深度學習框架中,您僅需實現前向傳遞,而框架將處理後向傳遞,因此大多數深度學習工程師無需理會後向傳遞的細節。我就不寫向後傳播了。

原文地址https://www.cnblogs.com/siguamatrix/p/12523600.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章