Advertisement
ERENARD63

RNN & LSTM forward propagation

May 24th, 2018
433
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 22.05 KB | None | 0 0
  1.  
  2. # coding: utf-8
  3.  
  4. # # Building your Recurrent Neural Network - Step by Step
  5. #
  6. # Welcome to Course 5's first assignment! In this assignment, you will implement your first Recurrent Neural Network in numpy.
  7. #
  8. # Recurrent Neural Networks (RNN) are very effective for Natural Language Processing and other sequence tasks because they have "memory". They can read inputs $x^{\langle t \rangle}$ (such as words) one at a time, and remember some information/context through the hidden layer activations that get passed from one time-step to the next. This allows a uni-directional RNN to take information from the past to process later inputs. A bidirection RNN can take context from both the past and the future.
  9. #
  10. # **Notation**:
  11. # - Superscript $[l]$ denotes an object associated with the $l^{th}$ layer.
  12. #     - Example: $a^{[4]}$ is the $4^{th}$ layer activation. $W^{[5]}$ and $b^{[5]}$ are the $5^{th}$ layer parameters.
  13. #
  14. # - Superscript $(i)$ denotes an object associated with the $i^{th}$ example.
  15. #     - Example: $x^{(i)}$ is the $i^{th}$ training example input.
  16. #
  17. # - Superscript $\langle t \rangle$ denotes an object at the $t^{th}$ time-step.
  18. #     - Example: $x^{\langle t \rangle}$ is the input x at the $t^{th}$ time-step. $x^{(i)\langle t \rangle}$ is the input at the $t^{th}$ timestep of example $i$.
  19. #    
  20. # - Lowerscript $i$ denotes the $i^{th}$ entry of a vector.
  21. #     - Example: $a^{[l]}_i$ denotes the $i^{th}$ entry of the activations in layer $l$.
  22. #
  23. # We assume that you are already familiar with `numpy` and/or have completed the previous courses of the specialization. Let's get started!
  24.  
  25. # Let's first import all the packages that you will need during this assignment.
  26.  
  27. # In[1]:
  28.  
  29. import numpy as np
  30. from rnn_utils import *
  31.  
  32.  
  33. # ## 1 - Forward propagation for the basic Recurrent Neural Network
  34. #
  35. # Later this week, you will generate music using an RNN. The basic RNN that you will implement has the structure below. In this example, $T_x = T_y$.
  36.  
  37. #**Figure 1**: Basic RNN model </center></caption>
  38.  
  39. # Here's how you can implement an RNN:
  40. #
  41. # **Steps**:
  42. # 1. Implement the calculations needed for one time-step of the RNN.
  43. # 2. Implement a loop over $T_x$ time-steps in order to process all the inputs, one at a time.
  44. #
  45. # Let's go!
  46. #
  47. # ## 1.1 - RNN cell
  48. #
  49. # A Recurrent neural network can be seen as the repetition of a single cell. You are first going to implement the computations for a single time-step. The following figure describes the operations for a single time-step of an RNN cell.
  50. #
  51. # **Exercise**: Implement the RNN-cell described in Figure (2).
  52. #
  53. # **Instructions**:
  54. # 1. Compute the hidden state with tanh activation: $a^{\langle t \rangle} = \tanh(W_{aa} a^{\langle t-1 \rangle} + W_{ax} x^{\langle t \rangle} + b_a)$.
  55. # 2. Using your new hidden state $a^{\langle t \rangle}$, compute the prediction $\hat{y}^{\langle t \rangle} = softmax(W_{ya} a^{\langle t \rangle} + b_y)$. We provided you a function: `softmax`.
  56. # 3. Store $(a^{\langle t \rangle}, a^{\langle t-1 \rangle}, x^{\langle t \rangle}, parameters)$ in cache
  57. # 4. Return $a^{\langle t \rangle}$ , $y^{\langle t \rangle}$ and cache
  58. #
  59. # We will vectorize over $m$ examples. Thus, $x^{\langle t \rangle}$ will have dimension $(n_x,m)$, and $a^{\langle t \rangle}$ will have dimension $(n_a,m)$.
  60.  
  61. # In[2]:
  62.  
  63. # GRADED FUNCTION: rnn_cell_forward
  64.  
  65. def rnn_cell_forward(xt, a_prev, parameters):
  66.     """
  67.   Implements a single forward step of the RNN-cell as described in Figure (2)
  68.  
  69.   Arguments:
  70.   xt -- your input data at timestep "t", numpy array of shape (n_x, m).
  71.   a_prev -- Hidden state at timestep "t-1", numpy array of shape (n_a, m)
  72.   parameters -- python dictionary containing:
  73.                       Wax -- Weight matrix multiplying the input, numpy array of shape (n_a, n_x)
  74.                       Waa -- Weight matrix multiplying the hidden state, numpy array of shape (n_a, n_a)
  75.                       Wya -- Weight matrix relating the hidden-state to the output, numpy array of shape (n_y, n_a)
  76.                       ba --  Bias, numpy array of shape (n_a, 1)
  77.                       by -- Bias relating the hidden-state to the output, numpy array of shape (n_y, 1)
  78.   Returns:
  79.   a_next -- next hidden state, of shape (n_a, m)
  80.   yt_pred -- prediction at timestep "t", numpy array of shape (n_y, m)
  81.   cache -- tuple of values needed for the backward pass, contains (a_next, a_prev, xt, parameters)
  82.   """
  83.    
  84.     # Retrieve parameters from "parameters"
  85.     Wax = parameters["Wax"]
  86.     Waa = parameters["Waa"]
  87.     Wya = parameters["Wya"]
  88.     ba = parameters["ba"]
  89.     by = parameters["by"]
  90.    
  91.     ### START CODE HERE ### (≈2 lines)
  92.     # compute next activation state using the formula given above
  93.     #print("a_prev",np.shape(a_prev))
  94.     #print("xt",np.shape(xt))
  95.     a_next = np.tanh(np.dot(Waa,a_prev)+np.dot(Wax,xt)+ba)
  96.     #np.multiply(Waa,a_prev)+
  97.     # compute output of the current cell using the formula given above
  98.     yt_pred = softmax(np.dot(Wya,a_next)+by)  
  99.     ### END CODE HERE ###
  100.    
  101.     # store values you need for backward propagation in cache
  102.     cache = (a_next, a_prev, xt, parameters)
  103.    
  104.     return a_next, yt_pred, cache
  105.  
  106.  
  107. # In[3]:
  108.  
  109. np.random.seed(1)
  110. xt = np.random.randn(3,10)
  111. a_prev = np.random.randn(5,10)
  112. Waa = np.random.randn(5,5)
  113. Wax = np.random.randn(5,3)
  114. Wya = np.random.randn(2,5)
  115. ba = np.random.randn(5,1)
  116. by = np.random.randn(2,1)
  117. parameters = {"Waa": Waa, "Wax": Wax, "Wya": Wya, "ba": ba, "by": by}
  118.  
  119. a_next, yt_pred, cache = rnn_cell_forward(xt, a_prev, parameters)
  120. print("a_next[4] = ", a_next[4])
  121. print("a_next.shape = ", a_next.shape)
  122. print("yt_pred[1] =", yt_pred[1])
  123. print("yt_pred.shape = ", yt_pred.shape)
  124.  
  125.  
  126.  
  127. # ## 1.2 - RNN forward pass
  128. #
  129. # You can see an RNN as the repetition of the cell you've just built. If your input sequence of data is carried over 10 time steps, then you will copy the RNN cell 10 times. Each cell takes as input the hidden state from the previous cell ($a^{\langle t-1 \rangle}$) and the current time-step's input data ($x^{\langle t \rangle}$). It outputs a hidden state ($a^{\langle t \rangle}$) and a prediction ($y^{\langle t \rangle}$) for this time-step.
  130. #
  131. #
  132. #
  133. # **Exercise**: Code the forward propagation of the RNN described in Figure (3).
  134. #
  135. # **Instructions**:
  136. # 1. Create a vector of zeros ($a$) that will store all the hidden states computed by the RNN.
  137. # 2. Initialize the "next" hidden state as $a_0$ (initial hidden state).
  138. # 3. Start looping over each time step, your incremental index is $t$ :
  139. #     - Update the "next" hidden state and the cache by running `rnn_cell_forward`
  140. #     - Store the "next" hidden state in $a$ ($t^{th}$ position)
  141. #     - Store the prediction in y
  142. #     - Add the cache to the list of caches
  143. # 4. Return $a$, $y$ and caches
  144.  
  145. # In[4]:
  146.  
  147. # GRADED FUNCTION: rnn_forward
  148.  
  149. def rnn_forward(x, a0, parameters):
  150.     """
  151.   Implement the forward propagation of the recurrent neural network described in Figure (3).
  152.  
  153.   Arguments:
  154.   x -- Input data for every time-step, of shape (n_x, m, T_x).
  155.   a0 -- Initial hidden state, of shape (n_a, m)
  156.   parameters -- python dictionary containing:
  157.                       Waa -- Weight matrix multiplying the hidden state, numpy array of shape (n_a, n_a)
  158.                       Wax -- Weight matrix multiplying the input, numpy array of shape (n_a, n_x)
  159.                       Wya -- Weight matrix relating the hidden-state to the output, numpy array of shape (n_y, n_a)
  160.                       ba --  Bias numpy array of shape (n_a, 1)
  161.                       by -- Bias relating the hidden-state to the output, numpy array of shape (n_y, 1)
  162.  
  163.   Returns:
  164.   a -- Hidden states for every time-step, numpy array of shape (n_a, m, T_x)
  165.   y_pred -- Predictions for every time-step, numpy array of shape (n_y, m, T_x)
  166.   caches -- tuple of values needed for the backward pass, contains (list of caches, x)
  167.   """
  168.    
  169.     # Initialize "caches" which will contain the list of all caches
  170.     caches = [a0,x]
  171.    
  172.     # Retrieve dimensions from shapes of x and parameters["Wya"]
  173.     n_x, m, T_x = x.shape
  174.     n_y, n_a = parameters["Wya"].shape
  175.    
  176.     ### START CODE HERE ###
  177.    
  178.     # initialize "a" and "y" with zeros (≈2 lines)
  179.     a = np.zeros((n_a, m,T_x))
  180.     y_pred = np.zeros((n_y, m, T_x))
  181.    
  182.     # Initialize a_next (≈1 line)
  183.     a_next = a0
  184.    
  185.     # loop over all time-steps
  186.    
  187.     for t in range(T_x):
  188.         # Update next hidden state, compute the prediction, get the cache (≈1 line)
  189.         #print("x", np.shape(x))
  190.         #print("a_next",a_next)
  191.         a_next, yt_pred, cache = rnn_cell_forward(x[:,:,t], a_next, parameters)
  192.         # Save the value of the new "next" hidden state in a (≈1 line)
  193.        
  194.         a[:,:,t] = a_next
  195.         # Save the value of the prediction in y (≈1 line)
  196.         y_pred[:,:,t] = yt_pred
  197.         # Append "cache" to "caches" (≈1 line)
  198.         caches=(caches,cache)
  199.        
  200.     ### END CODE HERE ###
  201.    
  202.     # store values needed for backward propagation in cache
  203.     caches = (caches, x)
  204.    
  205.     return a, y_pred, caches
  206.  
  207.  
  208. # In[5]:
  209.  
  210. np.random.seed(1)
  211. x = np.random.randn(3,10,4)
  212. a0 = np.random.randn(5,10)
  213. Waa = np.random.randn(5,5)
  214. Wax = np.random.randn(5,3)
  215. Wya = np.random.randn(2,5)
  216. ba = np.random.randn(5,1)
  217. by = np.random.randn(2,1)
  218. parameters = {"Waa": Waa, "Wax": Wax, "Wya": Wya, "ba": ba, "by": by}
  219.  
  220. a, y_pred, caches = rnn_forward(x, a0, parameters)
  221. print("a[4][1] = ", a[4][1])
  222. print("a.shape = ", a.shape)
  223. print("y_pred[1][3] =", y_pred[1][3])
  224. print("y_pred.shape = ", y_pred.shape)
  225. print("caches[1][1][3] =", caches[1][1][3])
  226. print("len(caches) = ", len(caches))
  227.  
  228.  
  229. # Congratulations! You've successfully built the forward propagation of a recurrent neural network from scratch. This will work well enough for some applications, but it suffers from vanishing gradient problems. So it works best when each output $y^{\langle t \rangle}$ can be estimated using mainly "local" context (meaning information from inputs $x^{\langle t' \rangle}$ where $t'$ is not too far from $t$).
  230. #
  231. # In the next part, you will build a more complex LSTM model, which is better at addressing vanishing gradients. The LSTM will be better able to remember a piece of information and keep it saved for many timesteps.
  232.  
  233. # ## 2 - Long Short-Term Memory (LSTM) network
  234. #
  235. # This following figure shows the operations of an LSTM-cell.
  236. #
  237. # Similar to the RNN example above, you will start by implementing the LSTM cell for a single time-step. Then you can iteratively call it from inside a for-loop to have it process an input with $T_x$ time-steps.
  238. #
  239. # ### About the gates
  240. #
  241. # #### - Forget gate
  242. #
  243. # For the sake of this illustration, lets assume we are reading words in a piece of text, and want use an LSTM to keep track of grammatical structures, such as whether the subject is singular or plural. If the subject changes from a singular word to a plural word, we need to find a way to get rid of our previously stored memory value of the singular/plural state. In an LSTM, the forget gate lets us do this:
  244. #
  245. # $$\Gamma_f^{\langle t \rangle} = \sigma(W_f[a^{\langle t-1 \rangle}, x^{\langle t \rangle}] + b_f)\tag{1} $$
  246. #
  247. # Here, $W_f$ are weights that govern the forget gate's behavior. We concatenate $[a^{\langle t-1 \rangle}, x^{\langle t \rangle}]$ and multiply by $W_f$. The equation above results in a vector $\Gamma_f^{\langle t \rangle}$ with values between 0 and 1. This forget gate vector will be multiplied element-wise by the previous cell state $c^{\langle t-1 \rangle}$. So if one of the values of $\Gamma_f^{\langle t \rangle}$ is 0 (or close to 0) then it means that the LSTM should remove that piece of information (e.g. the singular subject) in the corresponding component of $c^{\langle t-1 \rangle}$. If one of the values is 1, then it will keep the information.
  248. #
  249. # #### - Update gate
  250. #
  251. # Once we forget that the subject being discussed is singular, we need to find a way to update it to reflect that the new subject is now plural. Here is the formulat for the update gate:
  252. #
  253. # $$\Gamma_u^{\langle t \rangle} = \sigma(W_u[a^{\langle t-1 \rangle}, x^{\{t\}}] + b_u)\tag{2} $$
  254. #
  255. # Similar to the forget gate, here $\Gamma_u^{\langle t \rangle}$ is again a vector of values between 0 and 1. This will be multiplied element-wise with $\tilde{c}^{\langle t \rangle}$, in order to compute $c^{\langle t \rangle}$.
  256. #
  257. # #### - Updating the cell
  258. #
  259. # To update the new subject we need to create a new vector of numbers that we can add to our previous cell state. The equation we use is:
  260. #
  261. # $$ \tilde{c}^{\langle t \rangle} = \tanh(W_c[a^{\langle t-1 \rangle}, x^{\langle t \rangle}] + b_c)\tag{3} $$
  262. #
  263. # Finally, the new cell state is:
  264. #
  265. # $$ c^{\langle t \rangle} = \Gamma_f^{\langle t \rangle}* c^{\langle t-1 \rangle} + \Gamma_u^{\langle t \rangle} *\tilde{c}^{\langle t \rangle} \tag{4} $$
  266. #
  267. #
  268. # #### - Output gate
  269. #
  270. # To decide which outputs we will use, we will use the following two formulas:
  271. #
  272. # $$ \Gamma_o^{\langle t \rangle}=  \sigma(W_o[a^{\langle t-1 \rangle}, x^{\langle t \rangle}] + b_o)\tag{5}$$
  273. # $$ a^{\langle t \rangle} = \Gamma_o^{\langle t \rangle}* \tanh(c^{\langle t \rangle})\tag{6} $$
  274. #
  275. # Where in equation 5 you decide what to output using a sigmoid function and in equation 6 you multiply that by the $\tanh$ of the previous state.
  276.  
  277. # ### 2.1 - LSTM cell
  278. #
  279. # **Exercise**: Implement the LSTM cell described in the Figure (3).
  280. #
  281. # **Instructions**:
  282. # 1. Concatenate $a^{\langle t-1 \rangle}$ and $x^{\langle t \rangle}$ in a single matrix: $concat = \begin{bmatrix} a^{\langle t-1 \rangle} \\ x^{\langle t \rangle} \end{bmatrix}$
  283. # 2. Compute all the formulas 1-6. You can use `sigmoid()` (provided) and `np.tanh()`.
  284. # 3. Compute the prediction $y^{\langle t \rangle}$. You can use `softmax()` (provided).
  285.  
  286. # In[6]:
  287.  
  288. # GRADED FUNCTION: lstm_cell_forward
  289.  
  290. def lstm_cell_forward(xt, a_prev, c_prev, parameters):
  291.     """
  292.   Implement a single forward step of the LSTM-cell as described in Figure (4)
  293.  
  294.   Arguments:
  295.   xt -- your input data at timestep "t", numpy array of shape (n_x, m).
  296.   a_prev -- Hidden state at timestep "t-1", numpy array of shape (n_a, m)
  297.   c_prev -- Memory state at timestep "t-1", numpy array of shape (n_a, m)
  298.   parameters -- python dictionary containing:
  299.                       Wf -- Weight matrix of the forget gate, numpy array of shape (n_a, n_a + n_x)
  300.                       bf -- Bias of the forget gate, numpy array of shape (n_a, 1)
  301.                       Wi -- Weight matrix of the update gate, numpy array of shape (n_a, n_a + n_x)
  302.                       bi -- Bias of the update gate, numpy array of shape (n_a, 1)
  303.                       Wc -- Weight matrix of the first "tanh", numpy array of shape (n_a, n_a + n_x)
  304.                       bc --  Bias of the first "tanh", numpy array of shape (n_a, 1)
  305.                       Wo -- Weight matrix of the output gate, numpy array of shape (n_a, n_a + n_x)
  306.                       bo --  Bias of the output gate, numpy array of shape (n_a, 1)
  307.                       Wy -- Weight matrix relating the hidden-state to the output, numpy array of shape (n_y, n_a)
  308.                       by -- Bias relating the hidden-state to the output, numpy array of shape (n_y, 1)
  309.                      
  310.   Returns:
  311.   a_next -- next hidden state, of shape (n_a, m)
  312.   c_next -- next memory state, of shape (n_a, m)
  313.   yt_pred -- prediction at timestep "t", numpy array of shape (n_y, m)
  314.   cache -- tuple of values needed for the backward pass, contains (a_next, c_next, a_prev, c_prev, xt, parameters)
  315.  
  316.   Note: ft/it/ot stand for the forget/update/output gates, cct stands for the candidate value (c tilde),
  317.         c stands for the memory value
  318.   """
  319.  
  320.     # Retrieve parameters from "parameters"
  321.     Wf = parameters["Wf"]
  322.     bf = parameters["bf"]
  323.     Wi = parameters["Wi"]
  324.     bi = parameters["bi"]
  325.     Wc = parameters["Wc"]
  326.     bc = parameters["bc"]
  327.     Wo = parameters["Wo"]
  328.     bo = parameters["bo"]
  329.     Wy = parameters["Wy"]
  330.     by = parameters["by"]
  331.    
  332.     # Retrieve dimensions from shapes of xt and Wy
  333.     n_x, m = xt.shape
  334.     n_y, n_a = Wy.shape
  335.  
  336.     ### START CODE HERE ###
  337.     # Concatenate a_prev and xt (≈3 lines)
  338.     concat = np.zeros((n_x+n_a,m))
  339.     concat[: n_a, :] = a_prev
  340.     concat[n_a :, :] = xt
  341.  
  342.     # Compute values for ft, it, cct, c_next, ot, a_next using the formulas given figure (4) (≈6 lines)
  343.     ft = sigmoid(np.dot(Wf,concat)+bf)
  344.     it = sigmoid(np.dot(Wi,concat)+bi)
  345.     cct = np.tanh(np.dot(Wc,concat)+bc)
  346.     c_next = ft*c_prev+it*cct
  347.     ot = sigmoid(np.dot(Wo,concat)+bo)
  348.     a_next = ot*np.tanh(c_next)
  349.    
  350.     # Compute prediction of the LSTM cell (≈1 line)
  351.     yt_pred = softmax(np.dot(Wy,a_next)+by)
  352.     ### END CODE HERE ###
  353.  
  354.     # store values needed for backward propagation in cache
  355.     cache = (a_next, c_next, a_prev, c_prev, ft, it, cct, ot, xt, parameters)
  356.  
  357.     return a_next, c_next, yt_pred, cache
  358.  
  359.  
  360. # In[7]:
  361.  
  362. np.random.seed(1)
  363. xt = np.random.randn(3,10)
  364. a_prev = np.random.randn(5,10)
  365. c_prev = np.random.randn(5,10)
  366. Wf = np.random.randn(5, 5+3)
  367. bf = np.random.randn(5,1)
  368. Wi = np.random.randn(5, 5+3)
  369. bi = np.random.randn(5,1)
  370. Wo = np.random.randn(5, 5+3)
  371. bo = np.random.randn(5,1)
  372. Wc = np.random.randn(5, 5+3)
  373. bc = np.random.randn(5,1)
  374. Wy = np.random.randn(2,5)
  375. by = np.random.randn(2,1)
  376.  
  377. parameters = {"Wf": Wf, "Wi": Wi, "Wo": Wo, "Wc": Wc, "Wy": Wy, "bf": bf, "bi": bi, "bo": bo, "bc": bc, "by": by}
  378.  
  379. a_next, c_next, yt, cache = lstm_cell_forward(xt, a_prev, c_prev, parameters)
  380. print("a_next[4] = ", a_next[4])
  381. print("a_next.shape = ", c_next.shape)
  382. print("c_next[2] = ", c_next[2])
  383. print("c_next.shape = ", c_next.shape)
  384. print("yt[1] =", yt[1])
  385. print("yt.shape = ", yt.shape)
  386. print("cache[1][3] =", cache[1][3])
  387. print("len(cache) = ", len(cache))
  388.  
  389.  
  390.  
  391. # ### 2.2 - Forward pass for LSTM
  392. #
  393. # Now that you have implemented one step of an LSTM, you can now iterate this over this using a for-loop to process a sequence of $T_x$ inputs.
  394. #
  395. # **Exercise:** Implement `lstm_forward()` to run an LSTM over $T_x$ time-steps.
  396. #
  397. # **Note**: $c^{\langle 0 \rangle}$ is initialized with zeros.
  398.  
  399. # In[8]:
  400.  
  401. # GRADED FUNCTION: lstm_forward
  402.  
  403. def lstm_forward(x, a0, parameters):
  404.     """
  405.   Implement the forward propagation of the recurrent neural network using an LSTM-cell described in Figure (3).
  406.  
  407.   Arguments:
  408.   x -- Input data for every time-step, of shape (n_x, m, T_x).
  409.   a0 -- Initial hidden state, of shape (n_a, m)
  410.   parameters -- python dictionary containing:
  411.                       Wf -- Weight matrix of the forget gate, numpy array of shape (n_a, n_a + n_x)
  412.                       bf -- Bias of the forget gate, numpy array of shape (n_a, 1)
  413.                       Wi -- Weight matrix of the update gate, numpy array of shape (n_a, n_a + n_x)
  414.                       bi -- Bias of the update gate, numpy array of shape (n_a, 1)
  415.                       Wc -- Weight matrix of the first "tanh", numpy array of shape (n_a, n_a + n_x)
  416.                       bc -- Bias of the first "tanh", numpy array of shape (n_a, 1)
  417.                       Wo -- Weight matrix of the output gate, numpy array of shape (n_a, n_a + n_x)
  418.                       bo -- Bias of the output gate, numpy array of shape (n_a, 1)
  419.                       Wy -- Weight matrix relating the hidden-state to the output, numpy array of shape (n_y, n_a)
  420.                       by -- Bias relating the hidden-state to the output, numpy array of shape (n_y, 1)
  421.                      
  422.   Returns:
  423.   a -- Hidden states for every time-step, numpy array of shape (n_a, m, T_x)
  424.   y -- Predictions for every time-step, numpy array of shape (n_y, m, T_x)
  425.   caches -- tuple of values needed for the backward pass, contains (list of all the caches, x)
  426.   """
  427.  
  428.     # Initialize "caches", which will track the list of all the caches
  429.     caches = []
  430.    
  431.     ### START CODE HERE ###
  432.     # Retrieve dimensions from shapes of x and parameters['Wy'] (≈2 lines)
  433.     n_x, m, T_x = x.shape
  434.     n_y, n_a = parameters["Wy"].shape
  435.    
  436.     # initialize "a", "c" and "y" with zeros (≈3 lines)
  437.     a = np.zeros((n_a,m,T_x))
  438.     c = np.zeros((n_a,m,T_x))
  439.     y = np.zeros((n_y,m,T_x))
  440.    
  441.     # Initialize a_next and c_next (≈2 lines)
  442.     a_next = a0
  443.     c_next = np.zeros((n_a,m))
  444.    
  445.     # loop over all time-steps
  446.     for t in range(T_x):
  447.         # Update next hidden state, next memory state, compute the prediction, get the cache (≈1 line)
  448.         a_next, c_next, yt, cache = lstm_cell_forward(x[:,:,t], a_next, c_next, parameters)
  449.         # Save the value of the new "next" hidden state in a (≈1 line)
  450.         a[:,:,t] = a_next
  451.         # Save the value of the prediction in y (≈1 line)
  452.         y[:,:,t] = yt
  453.         # Save the value of the next cell state (≈1 line)
  454.         c[:,:,t]  = c_next
  455.         # Append the cache into caches (≈1 line)
  456.         caches.append(cache)
  457.        
  458.     ### END CODE HERE ###
  459.    
  460.     # store values needed for backward propagation in cache
  461.     caches = (caches, x)
  462.  
  463.     return a, y, c, caches
  464.  
  465.  
  466. # In[9]:
  467.  
  468. np.random.seed(1)
  469. x = np.random.randn(3,10,7)
  470. a0 = np.random.randn(5,10)
  471. Wf = np.random.randn(5, 5+3)
  472. bf = np.random.randn(5,1)
  473. Wi = np.random.randn(5, 5+3)
  474. bi = np.random.randn(5,1)
  475. Wo = np.random.randn(5, 5+3)
  476. bo = np.random.randn(5,1)
  477. Wc = np.random.randn(5, 5+3)
  478. bc = np.random.randn(5,1)
  479. Wy = np.random.randn(2,5)
  480. by = np.random.randn(2,1)
  481.  
  482. parameters = {"Wf": Wf, "Wi": Wi, "Wo": Wo, "Wc": Wc, "Wy": Wy, "bf": bf, "bi": bi, "bo": bo, "bc": bc, "by": by}
  483.  
  484. a, y, c, caches = lstm_forward(x, a0, parameters)
  485. print("a[4][3][6] = ", a[4][3][6])
  486. print("a.shape = ", a.shape)
  487. print("y[1][4][3] =", y[1][4][3])
  488. print("y.shape = ", y.shape)
  489. print("caches[1][1[1]] =", caches[1][1][1])
  490. print("c[1][2][1]", c[1][2][1])
  491. print("len(caches) = ", len(caches))
  492.  
  493.  
  494.  
  495. # Congratulations! You have now implemented the forward passes for the basic RNN and the LSTM. When using a deep learning framework, implementing the forward pass is sufficient to build systems that achieve great performance.
  496. #
  497. # The rest of this notebook is optional, and will not be graded.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement