import tensorflow as tf
from tensorflow.keras import layers, models, callbacks
# Define the model architecture (CNN + RNN for text recognition)
inputs = layers.Input(shape=(128, 32, 1)) # Example input size: width=128, height=32, grayscale
# CNN layers
x = layers.Conv2D(64, (3,3), activation='relu', padding='same')(inputs)
x = layers.MaxPooling2D((2,2))(x)
x = layers.Dropout(0.25)(x) # Added dropout
x = layers.Conv2D(128, (3,3), activation='relu', padding='same')(x)
x = layers.MaxPooling2D((2,2))(x)
x = layers.Dropout(0.25)(x) # Added dropout
# Prepare for RNN
shape = x.shape
x = layers.Reshape((shape[1], shape[2]*shape[3]))(x)
# RNN layers
x = layers.Bidirectional(layers.LSTM(128, return_sequences=True))(x)
x = layers.Bidirectional(layers.LSTM(64, return_sequences=True))(x)
# Output layer
outputs = layers.Dense(80, activation='softmax')(x) # 80 possible characters
model = models.Model(inputs, outputs)
# Compile with lower learning rate
optimizer = tf.keras.optimizers.Adam(learning_rate=0.0005)
model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])
# Early stopping callback
early_stop = callbacks.EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)
# Assume X_train, y_train, X_val, y_val are prepared
# model.fit(X_train, y_train, epochs=50, batch_size=32, validation_data=(X_val, y_val), callbacks=[early_stop])
# Note: Data augmentation can be added before training if desired.