import tensorflow as tf
from tensorflow.keras.layers import Input, Dense, Dropout, LayerNormalization, Embedding
from tensorflow.keras.models import Model
import numpy as np
class SimpleTransformerBlock(tf.keras.layers.Layer):
def __init__(self, embed_dim, num_heads, ff_dim, rate=0.1):
super(SimpleTransformerBlock, self).__init__()
self.att = tf.keras.layers.MultiHeadAttention(num_heads=num_heads, key_dim=embed_dim)
self.ffn = tf.keras.Sequential([
Dense(ff_dim, activation='relu'),
Dense(embed_dim),
])
self.layernorm1 = LayerNormalization(epsilon=1e-6)
self.layernorm2 = LayerNormalization(epsilon=1e-6)
self.dropout1 = Dropout(rate)
self.dropout2 = Dropout(rate)
def call(self, inputs, training=None):
attn_output = self.att(inputs, inputs)
attn_output = self.dropout1(attn_output, training=training)
out1 = self.layernorm1(inputs + attn_output)
ffn_output = self.ffn(out1)
ffn_output = self.dropout2(ffn_output, training=training)
return self.layernorm2(out1 + ffn_output)
# Parameters
vocab_size = 1000
maxlen = 20
embed_dim = 32 # Reduced embedding size
num_heads = 2 # Reduced number of heads
ff_dim = 64
num_classes = 2
def create_model():
inputs = Input(shape=(maxlen,))
embedding_layer = Embedding(vocab_size, embed_dim)(inputs)
transformer_block = SimpleTransformerBlock(embed_dim, num_heads, ff_dim, rate=0.2)(embedding_layer)
x = tf.keras.layers.GlobalAveragePooling1D()(transformer_block)
x = Dropout(0.3)(x)
x = Dense(20, activation='relu')(x)
x = Dropout(0.3)(x)
outputs = Dense(num_classes, activation='softmax')(x)
model = Model(inputs=inputs, outputs=outputs)
return model
model = create_model()
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
# Dummy data for demonstration
X_train = np.random.randint(0, vocab_size, size=(1000, maxlen))
Y_train = np.random.randint(0, num_classes, size=(1000,))
X_val = np.random.randint(0, vocab_size, size=(200, maxlen))
Y_val = np.random.randint(0, num_classes, size=(200,))
# Early stopping callback
early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3, restore_best_weights=True)
history = model.fit(
X_train, Y_train,
validation_data=(X_val, Y_val),
epochs=30,
batch_size=32,
callbacks=[early_stopping]
)
# Print final metrics
train_acc = history.history['accuracy'][-1] * 100
val_acc = history.history['val_accuracy'][-1] * 100
train_loss = history.history['loss'][-1]
val_loss = history.history['val_loss'][-1]
print(f"Training accuracy: {train_acc:.2f}%, Validation accuracy: {val_acc:.2f}%")
print(f"Training loss: {train_loss:.4f}, Validation loss: {val_loss:.4f}")