Feature Definitions
Torch-RecHub provides three core feature classes for different data types.

DenseFeature
Numeric features (e.g., age, income).
from torch_rechub.basic.features import DenseFeature
dense_feature = DenseFeature(name="age", embed_dim=1)Parameters: name, embed_dim (always 1).
SparseFeature
Categorical features (e.g., city, gender).
from torch_rechub.basic.features import SparseFeature
sparse_feature = SparseFeature(
name="city",
vocab_size=100,
embed_dim=16,
shared_with=None, # share embeddings with another feature if needed
)Parameters: name, vocab_size, embed_dim (auto if None), shared_with, padding_idx, initializer.
SequenceFeature
Sequence or multi-hot features (e.g., behavior history, tags).
from torch_rechub.basic.features import SequenceFeature
sequence_feature = SequenceFeature(
name="user_history",
vocab_size=10000,
embed_dim=32,
pooling="mean", # mean, sum, concat
)Parameters: name, vocab_size, embed_dim (auto if None), pooling (mean/sum/concat), shared_with, padding_idx, initializer.
Feature Instances and Embedding Ownership
Warning:
SparseFeatureandSequenceFeaturecache thenn.Embeddingcreated byget_embedding_layer(). If the same Feature instance is passed to multiple models, those models use the same embedding parameters. Training or loading weights into one model therefore changes the embedding observed by the others.
The two EmbeddingLayer instances below unintentionally share the city embedding:
from torch_rechub.basic.features import SparseFeature
from torch_rechub.basic.layers import EmbeddingLayer
features = [SparseFeature(name="city", vocab_size=100, embed_dim=16)]
embedding_a = EmbeddingLayer(features)
embedding_b = EmbeddingLayer(features)
assert embedding_a.embed_dict["city"] is embedding_b.embed_dict["city"]For independent model comparisons, cross-validation, or ensemble training, create new Feature instances for every model:
def build_features():
return [SparseFeature(name="city", vocab_size=100, embed_dim=16)]
embedding_a = EmbeddingLayer(build_features())
embedding_b = EmbeddingLayer(build_features())
assert embedding_a.embed_dict["city"] is not embedding_b.embed_dict["city"]Copying only the list does not help: features.copy() still contains the original Feature instances. This accidental cross-model sharing is different from explicitly using shared_with to share an embedding inside one model; the latter is intentional.
Usage Example
from torch_rechub.basic.features import DenseFeature, SparseFeature, SequenceFeature
dense_features = [
DenseFeature(name="age", embed_dim=1),
DenseFeature(name="income", embed_dim=1),
]
sparse_features = [
SparseFeature(name="city", vocab_size=100, embed_dim=16),
SparseFeature(name="gender", vocab_size=3, embed_dim=8),
]
sequence_features = [
SequenceFeature(name="user_history", vocab_size=10000, embed_dim=32, pooling="mean"),
]
all_features = dense_features + sparse_features + sequence_features