Implementation:Recommenders team Recommenders Time Aware LSTM Cells
| Knowledge Sources | |
|---|---|
| Domains | Sequential Recommendation, Deep Learning, Recurrent Neural Networks |
| Last Updated | 2026-02-10 00:00 GMT |
Overview
This module implements custom time-aware LSTM cells (Time4LSTMCell and Time4ALSTMCell) that incorporate temporal information about time gaps between user actions into the LSTM gating mechanism for sequential recommendation.
Description
The module provides two custom RNN cell implementations that extend TensorFlow's RNNCell to make the standard LSTM architecture time-aware, along with a helper _Linear class for efficient batched linear transformations.
Time4LSTMCell modifies the standard LSTM by introducing two time gates that modulate the forget and input gates. The cell expects input tensors with time_now_score and time_last_score appended as the last two features. These time scores are transformed through learnable parameters: first through element-wise scaling and bias with tanh activation (time_now_input, time_last_input), then through a linear combination of the input features and the time features to produce time_now_state and time_last_state. The cell state update becomes: c = sigmoid(f + forget_bias) * sigmoid(time_last_state) * c_prev + sigmoid(i) * sigmoid(time_now_state) * tanh(j). The time features also influence the output gate through additional learned kernel matrices (_o_kernel_t1, _o_kernel_t2). Optional peephole connections and projection layers are supported.
Time4ALSTMCell extends Time4LSTMCell by adding an attention score as a third appended feature in the input. This attention score modulates the final cell state and hidden state outputs via: c = att_score * c + (1 - att_score) * c and m = att_score * m + (1 - att_score) * m. The attention-based cell is designed for models that compute attention weights externally and pass them into the cell.
_Linear is a helper class that implements the batched linear map sum_i(args[i] * W[i]) used for the core LSTM matrix multiplications. It pre-computes the weight matrix during construction and efficiently handles both single-tensor and list-of-tensor inputs.
Usage
Use Time4LSTMCell as a drop-in replacement for standard LSTM cells when temporal gaps between sequential user actions carry meaningful information for recommendation. Use Time4ALSTMCell when an external attention mechanism provides per-step attention scores that should modulate the cell's output. These cells are essential components of the SLI_REC (Adaptive User Modeling with Long and Short-Term Preferences for Personalized Recommendation) model.
Code Reference
Source Location
- Repository: Recommenders
- File: recommenders/models/deeprec/models/sequential/rnn_cell_implement.py
- Lines: 1-660
Signature
class Time4LSTMCell(RNNCell):
def __init__(
self, num_units, use_peepholes=False, cell_clip=None,
initializer=None, num_proj=None, proj_clip=None,
num_unit_shards=None, num_proj_shards=None,
forget_bias=1.0, state_is_tuple=True, activation=None, reuse=None
):
"""Initialize Time4LSTMCell."""
def call(self, inputs, state):
"""Run one step of the Time4LSTMCell.
Args:
inputs: 2D Tensor [batch_size, input_size] with time scores appended.
state: 2D Tensor [batch_size, state_size].
Returns:
Tuple of (output, new_state).
"""
class Time4ALSTMCell(RNNCell):
def __init__(
self, num_units, use_peepholes=False, cell_clip=None,
initializer=None, num_proj=None, proj_clip=None,
num_unit_shards=None, num_proj_shards=None,
forget_bias=1.0, state_is_tuple=True, activation=None, reuse=None
):
"""Initialize Time4ALSTMCell with attention support."""
def call(self, inputs, state):
"""Run one step of the Time4ALSTMCell.
Args:
inputs: 2D Tensor [batch_size, input_size] with time scores and attention score appended.
state: 2D Tensor [batch_size, state_size].
Returns:
Tuple of (output, new_state).
"""
class _Linear(object):
def __init__(self, args, output_size, build_bias,
bias_initializer=None, kernel_initializer=None):
"""Linear map: sum_i(args[i] * W[i])."""
def __call__(self, args):
"""Apply the linear transformation."""
Import
from recommenders.models.deeprec.models.sequential.rnn_cell_implement import (
Time4LSTMCell,
Time4ALSTMCell,
)
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| num_units | int | Yes | Number of units in the LSTM cell (hidden size) |
| use_peepholes | bool | No | Whether to use peephole connections (default: False) |
| cell_clip | float | No | Optional value to clip cell state; None disables clipping |
| initializer | object | No | Initializer for weight variables |
| num_proj | int | No | Optional number of projection units; None means no projection |
| proj_clip | float | No | Optional value to clip projection output |
| forget_bias | float | No | Bias added to forget gate (default: 1.0) |
| state_is_tuple | bool | No | If True, state is LSTMStateTuple (default: True) |
| activation | callable | No | Activation function; defaults to tanh |
| inputs (call) | tf.Tensor | Yes | For Time4LSTMCell: [batch_size, features + 2] with time_now_score and time_last_score appended. For Time4ALSTMCell: [batch_size, features + 3] with time_last_score, time_now_score, and att_score appended. |
| state (call) | tf.Tensor/LSTMStateTuple | Yes | Previous cell state of shape [batch_size, state_size] |
Outputs
| Name | Type | Description |
|---|---|---|
| output | tf.Tensor | Hidden state output of shape [batch_size, num_proj] if projection is used, otherwise [batch_size, num_units] |
| new_state | LSTMStateTuple or tf.Tensor | Updated cell state containing both cell state c and hidden state m |
Usage Examples
Basic Usage
import tensorflow as tf
from recommenders.models.deeprec.models.sequential.rnn_cell_implement import (
Time4LSTMCell,
Time4ALSTMCell,
)
# Create a time-aware LSTM cell
cell = Time4LSTMCell(
num_units=128,
forget_bias=1.0,
state_is_tuple=True,
)
# Input tensor: [batch_size, embedding_dim + 2]
# Last two features are time_now_score and time_last_score
inputs = tf.placeholder(tf.float32, [None, 66]) # 64 features + 2 time scores
# Use with tf.nn.dynamic_rnn
initial_state = cell.zero_state(batch_size, tf.float32)
outputs, final_state = tf.nn.dynamic_rnn(
cell, inputs_sequence, initial_state=initial_state, dtype=tf.float32
)
# For attention-aware variant (used with SLI_REC)
att_cell = Time4ALSTMCell(
num_units=128,
forget_bias=1.0,
)
# Input includes time_last_score, time_now_score, and att_score (3 extra features)