Many-to-One Output Selector
Problem Statement
Select the final relevant output from a batch of variable-length sequences.
Background
In "Many-to-One" architectures (e.g., sentiment analysis), sequences in a batch often have different lengths. We pad shorter sequences but need to extract the hidden state at the last valid timestep for each sequence.
Your Task
Write a function get_final_states(hidden_states, sequence_lengths) that extracts the final hidden state for each sequence in the batch.
Input Format
- hidden_states: numpy array of shape (batch_size, max_seq_len, hidden_dim)
- sequence_lengths: list of integers, length of each sequence in the batch
Output Format
Return a numpy array of shape (batch_size, hidden_dim) containing the last valid hidden state for each sequence.
Example
hidden_states shape (2, 3, 4), sequence_lengths = [2, 3]
Shape (2, 4) with hidden_states[0,1,:] and hidden_states[1,2,:]
hidden_statesis a block: 2 sequences, 3 timestep slots each, and a 4-number hidden vector in every slot. Filled with to in order, sequence 0 holds , , and sequence 1 holds , , .sequence_lengths=[2, 3]says how many slots are real. Sequence 0 has only 2 real timesteps, so its third slot is padding.- A sequence of length occupies timesteps (counting from zero), so its last real step is : for sequence 0 and for sequence 1.
- That picks from sequence 0 and from sequence 1.
- The result is a array: one row per sequence, one column per hidden unit. The time axis disappears because each sequence keeps exactly one timestep.
- Notice that always taking the final slot would return the padding vector for sequence 0, which is exactly the mistake this selector avoids.
Constraints
- 1 <= batch_size <= 64
- 1 <= max_seq_len <= 512
- 1 <= hidden_dim <= 512
- sequence_lengths[i] >= 1 for all i