import tensorflow as tf
from tensorflow.keras.layers import Input, Embedding, LSTM, Dense, Dropout, Concatenate
from tensorflow.keras.models import Model
from tensorflow.keras.callbacks import EarlyStopping
# Toy dataset setup (for demonstration, normally you load real data)
# Assume X_text is tokenized sequences, X_label is category labels (0 or 1), y is target sequences
vocab_size = 1000
embedding_dim = 16
max_seq_len = 10
num_classes = 2
# Model inputs
text_input = Input(shape=(max_seq_len,), name='text_input')
label_input = Input(shape=(1,), name='label_input')
# Embedding for text
text_emb = Embedding(input_dim=vocab_size, output_dim=embedding_dim, input_length=max_seq_len)(text_input)
# Embedding for label (category)
label_emb = Embedding(input_dim=num_classes, output_dim=embedding_dim)(label_input)
label_emb = tf.keras.layers.Flatten()(label_emb)
label_emb = tf.keras.layers.RepeatVector(max_seq_len)(label_emb)
# Combine text and label embeddings
combined = Concatenate()([text_emb, label_emb])
# LSTM with dropout
x = LSTM(64, return_sequences=True)(combined)
x = Dropout(0.3)(x)
x = LSTM(32)(x)
x = Dropout(0.3)(x)
# Output layer
output = Dense(vocab_size, activation='softmax')(x)
model = Model(inputs=[text_input, label_input], outputs=output)
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
# Early stopping callback
early_stop = EarlyStopping(monitor='val_loss', patience=3, restore_best_weights=True)
# Dummy data for demonstration (random integers)
import numpy as np
X_text = np.random.randint(1, vocab_size, size=(1000, max_seq_len))
X_label = np.random.randint(0, num_classes, size=(1000, 1))
y = np.random.randint(1, vocab_size, size=(1000, 1))
# Train model
history = model.fit(
{'text_input': X_text, 'label_input': X_label},
y,
epochs=30,
batch_size=32,
validation_split=0.2,
callbacks=[early_stop]
)