RNN Single Step Forward
Problem Statement
Compute the hidden state for a single timestep in a standard RNN.
Background
The update rule for a vanilla RNN is:
Where:
- is the new hidden state
- is the previous hidden state
- is the input at timestep
- is the hidden-to-hidden weight matrix
- is the input-to-hidden weight matrix
- is the bias vector
Your Task
Write a function rnn_step(prev_hidden, input_vec, W_aa, W_ax, b_a) that computes and returns the new hidden state using np.tanh.
Input Format
- prev_hidden: numpy array of shape (hidden_dim,)
- input_vec: numpy array of shape (input_dim,)
- W_aa: numpy array of shape (hidden_dim, hidden_dim)
- W_ax: numpy array of shape (hidden_dim, input_dim)
- b_a: numpy array of shape (hidden_dim,)
Output Format
Return a numpy array of shape (hidden_dim,) representing the new hidden state.
Example
prev_hidden=[0,0], input_vec=[1,2], W_aa=[[0.1,0.2],[0.3,0.4]], W_ax=[[0.5,0.6],[0.7,0.8]], b_a=[0,0]
[0.9354, 0.9801] (approximately)
- Inputs: the previous hidden state (2 hidden units), the current input (2 features), two weight matrices and a zero bias. Each row of a weight matrix belongs to one hidden unit.
- Recurrent term: multiplies every weight by , so it is . At the first timestep there is no memory yet.
- Input term: row 1 of gives ; row 2 gives .
- Pre-activation: add the two terms and to get .
- Squash: applying to each entry turns into and into , giving
[0.9354, 0.9801], a vector with one value per hidden unit. - Notice that both values sit close to : maps any real number into and saturates for large inputs, so the second unit's larger pre-activation gains only a little.
Constraints
- All inputs are valid numpy arrays with compatible dimensions
- hidden_dim and input_dim are between 1 and 512