PROGRAM
# ============================================
# MACHINE TRANSLATION USING ENCODER-DECODER
# AD3511 - Deep Learning Lab | Experiment 7
# Google Colab Compatible
# ============================================
# ----------------------------------------------------
# Step 1. Import Libraries
# ----------------------------------------------------
import numpy as np
import pandas as pd
import tensorflow as tf
from [Link] import Model
from [Link] import Input, LSTM, Embedding, Dense
from [Link] import Tokenizer
from [Link] import pad_sequences
import re
import string
import [Link]
import zipfile
import os
import [Link] as plt
# ----------------------------------------------------
# Step 2. Download & Extract English-French Dataset
# ----------------------------------------------------
!wget -O [Link] [Link]
!unzip -o [Link] -d fra-eng-data
# ----------------------------------------------------
# Step 3. Load and Prepare Data
# ----------------------------------------------------
lines = open("fra-eng-data/[Link]", encoding="utf-8").read().strip().split('\n')
print("Total sentence pairs available:", len(lines))
# Use first 10,000 pairs for faster training
num_samples = 10000
eng_sentences = []
fra_sentences = []
for line in lines[:num_samples]:
eng, fra = [Link]('\t')[:2]
fra = "start " + fra + " end"
eng_sentences.append(eng)
fra_sentences.append(fra)
print("Example pair:\n", eng_sentences[0], " -> ", fra_sentences[0])
# ----------------------------------------------------
# Step 4. Text Preprocessing
# ----------------------------------------------------
def clean_text(text):
text = [Link]()
text = [Link](f"[{[Link]}]", "", text)
text = [Link](r"\d+", "", text)
text = [Link]()
return text
eng_sentences = [clean_text(txt) for txt in eng_sentences]
fra_sentences = [clean_text(txt) for txt in fra_sentences]
# ----------------------------------------------------
# Step 5. Tokenization and Padding
# ----------------------------------------------------
eng_tokenizer = Tokenizer()
eng_tokenizer.fit_on_texts(eng_sentences)
eng_seq = eng_tokenizer.texts_to_sequences(eng_sentences)
fra_tokenizer = Tokenizer()
fra_tokenizer.fit_on_texts(fra_sentences)
fra_seq = fra_tokenizer.texts_to_sequences(fra_sentences)
max_eng_len = max([len(seq) for seq in eng_seq])
max_fra_len = max([len(seq) for seq in fra_seq])
eng_vocab_size = len(eng_tokenizer.word_index) + 1
fra_vocab_size = len(fra_tokenizer.word_index) + 1
encoder_input_data = pad_sequences(eng_seq, maxlen=max_eng_len, padding='post')
decoder_input_data = pad_sequences(fra_seq, maxlen=max_fra_len, padding='post')
# Prepare decoder output (shifted sequence)
decoder_output_data = np.zeros_like(decoder_input_data)
decoder_output_data[:, :-1] = decoder_input_data[:, 1:]
print(f"Vocabulary sizes — English: {eng_vocab_size} , French: {fra_vocab_size}")
# ----------------------------------------------------
# Step 6. Build Encoder-Decoder Model
# ----------------------------------------------------
latent_dim = 256
# Encoder
encoder_inputs = Input(shape=(None,))
enc_emb = Embedding(eng_vocab_size, latent_dim)(encoder_inputs)
encoder_lstm = LSTM(latent_dim, return_state=True)
_, state_h, state_c = encoder_lstm(enc_emb)
encoder_states = [state_h, state_c]
# Decoder
decoder_inputs = Input(shape=(None,))
dec_emb_layer = Embedding(fra_vocab_size, latent_dim)
dec_emb = dec_emb_layer(decoder_inputs)
decoder_lstm = LSTM(latent_dim, return_sequences=True, return_state=True)
decoder_outputs, _, _ = decoder_lstm(dec_emb, initial_state=encoder_states)
decoder_dense = Dense(fra_vocab_size, activation='softmax')
decoder_outputs = decoder_dense(decoder_outputs)
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
[Link]()
# ----------------------------------------------------
# Step 7. Compile and Train
# ----------------------------------------------------
[Link](optimizer='adam', loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
history = [Link](
[encoder_input_data, decoder_input_data],
np.expand_dims(decoder_output_data, -1),
batch_size=64,
epochs=20,
validation_split=0.2,
verbose=1
)
# ----------------------------------------------------
# Step 8. Display Training Accuracy & Loss
# ----------------------------------------------------
train_acc = [Link]['accuracy'][-1] * 100
val_acc = [Link]['val_accuracy'][-1] * 100
train_loss = [Link]['loss'][-1]
val_loss = [Link]['val_loss'][-1]
print("\n=================== FINAL MODEL PERFORMANCE
===================")
print(f"✅ Training Accuracy : {train_acc:.2f}%")
print(f"✅ Validation Accuracy : {val_acc:.2f}%")
print(f"❌ Training Loss : {train_loss:.4f}")
print(f"❌ Validation Loss : {val_loss:.4f}")
print("===============================================================")
# Optional: Plot Accuracy & Loss Curves
[Link](figsize=(10,4))
[Link](1,2,1)
[Link]([Link]['accuracy'], label='Train Acc')
[Link]([Link]['val_accuracy'], label='Val Acc')
[Link]('Accuracy')
[Link]()
[Link](1,2,2)
[Link]([Link]['loss'], label='Train Loss')
[Link]([Link]['val_loss'], label='Val Loss')
[Link]('Loss')
[Link]()
[Link]()
# ----------------------------------------------------
# Step 9. Define Inference Models
# ----------------------------------------------------
encoder_model = Model(encoder_inputs, encoder_states)
decoder_state_input_h = Input(shape=(latent_dim,))
decoder_state_input_c = Input(shape=(latent_dim,))
dec_states_inputs = [decoder_state_input_h, decoder_state_input_c]
dec_emb2 = dec_emb_layer(decoder_inputs)
decoder_outputs2, state_h2, state_c2 = decoder_lstm(dec_emb2,
initial_state=dec_states_inputs)
decoder_states2 = [state_h2, state_c2]
decoder_outputs2 = decoder_dense(decoder_outputs2)
decoder_model = Model([decoder_inputs] + dec_states_inputs, [decoder_outputs2] +
decoder_states2)
# ----------------------------------------------------
# Step 10. Translation Function
# ----------------------------------------------------
reverse_eng_index = {i: w for w, i in eng_tokenizer.word_index.items()}
reverse_fra_index = {i: w for w, i in fra_tokenizer.word_index.items()}
fra_index = fra_tokenizer.word_index
def translate_sequence(input_seq):
states_value = encoder_model.predict(input_seq)
target_seq = [Link]((1,1))
target_seq[0,0] = fra_index['start']
decoded_sentence = ''
for _ in range(max_fra_len):
output_tokens, h, c = decoder_model.predict([target_seq] + states_value)
sampled_token_index = [Link](output_tokens[0, -1, :])
sampled_word = reverse_fra_index.get(sampled_token_index, '')
if sampled_word == 'end' or sampled_word == '':
break
decoded_sentence += ' ' + sampled_word
target_seq = [Link]((1,1))
target_seq[0,0] = sampled_token_index
states_value = [h, c]
return decoded_sentence.strip()
# ----------------------------------------------------
# Step 11. Test Translation
# ----------------------------------------------------
def test_translation(sentence):
sentence = clean_text(sentence)
seq = eng_tokenizer.texts_to_sequences([sentence])
seq = pad_sequences(seq, maxlen=max_eng_len, padding='post')
translated = translate_sequence(seq)
print(f"\nEnglish: {sentence}")
print(f"Predicted French: {translated}")
# Try different sentences
test_translation("go")
test_translation("how are you")
test_translation("i love you")
test_translation("good morning")
test_translation("where are you going")
OUTPUT
--2025-10-06 08:26:33-- [Link]
Resolving [Link] ([Link])... [Link]
Connecting to [Link] ([Link])|[Link]|:80...
connected.
HTTP request sent, awaiting response... 200 OK
Length: 8186368 (7.8M) [application/zip]
Saving to: ‘[Link]’
[Link] 100%[===================>] 7.81M 3.86MB/s in 2.0s
2025-10-06 08:26:35 (3.86 MB/s) - ‘[Link]’ saved [8186368/8186368]
Archive: [Link]
inflating: fra-eng-data/_about.txt
inflating: fra-eng-data/[Link]
Total sentence pairs available: 239189
Example pair:
Go. -> start Va ! end
Vocabulary sizes — English: 2013 , French: 4670
Model: "functional_9"
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃ Connected to ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ input_layer_12 │ (None, None) │ 0 │ - │
│ (InputLayer) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ input_layer_13 │ (None, None) │ 0 │ - │
│ (InputLayer) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ embedding_6 │ (None, None, 256) │ 515,328 │ input_layer_12[0… │
│ (Embedding) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ embedding_7 │ (None, None, 256) │ 1,195,520 │ input_layer_13[0… │
│ (Embedding) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ lstm_6 (LSTM) │ [(None, 256), │ 525,312 │ embedding_6[0][0] │
│ │ (None, 256), │ │ │
│ │ (None, 256)] │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ lstm_7 (LSTM) │ [(None, None, │ 525,312 │ embedding_7[0][0… │
│ │ 256), (None, │ │ lstm_6[0][1], │
│ │ 256), (None, │ │ lstm_6[0][2] │
│ │ 256)] │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense_3 (Dense) │ (None, None, │ 1,200,190 │ lstm_7[0][0] │
│ │ 4670) │ │ │
└─────────────────────┴───────────────────┴────────────┴───────────────────┘
Total params: 3,961,662 (15.11 MB)
Trainable params: 3,961,662 (15.11 MB)
Non-trainable params: 0 (0.00 B)
Epoch 1/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 5s 27ms/step - accuracy: 0.6580 - loss: 3.8571 -
val_accuracy: 0.7345 - val_loss: 1.9331
Epoch 2/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 3s 24ms/step - accuracy: 0.7763 - loss: 1.5725 -
val_accuracy: 0.7431 - val_loss: 1.7834
Epoch 3/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 3s 24ms/step - accuracy: 0.7814 - loss: 1.4341 -
val_accuracy: 0.7644 - val_loss: 1.6865
Epoch 4/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 3s 23ms/step - accuracy: 0.7983 - loss: 1.2924 -
val_accuracy: 0.7732 - val_loss: 1.6213
Epoch 5/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 4s 28ms/step - accuracy: 0.8055 - loss: 1.2127 -
val_accuracy: 0.7795 - val_loss: 1.5787
Epoch 6/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 3s 24ms/step - accuracy: 0.8156 - loss: 1.1139 -
val_accuracy: 0.7885 - val_loss: 1.5276
Epoch 7/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 3s 25ms/step - accuracy: 0.8224 - loss: 1.0369 -
val_accuracy: 0.7933 - val_loss: 1.5065
Epoch 8/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 3s 23ms/step - accuracy: 0.8290 - loss: 0.9621 -
val_accuracy: 0.7993 - val_loss: 1.4787
Epoch 9/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 3s 23ms/step - accuracy: 0.8368 - loss: 0.8855 -
val_accuracy: 0.8013 - val_loss: 1.4687
Epoch 10/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 3s 23ms/step - accuracy: 0.8447 - loss: 0.8195 -
val_accuracy: 0.8055 - val_loss: 1.4568
Epoch 11/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 3s 25ms/step - accuracy: 0.8501 - loss: 0.7562 -
val_accuracy: 0.8067 - val_loss: 1.4504
Epoch 12/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 5s 24ms/step - accuracy: 0.8569 - loss: 0.6960 -
val_accuracy: 0.8093 - val_loss: 1.4418
Epoch 13/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 3s 24ms/step - accuracy: 0.8637 - loss: 0.6403 -
val_accuracy: 0.8130 - val_loss: 1.4292
Epoch 14/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 3s 25ms/step - accuracy: 0.8700 - loss: 0.5863 -
val_accuracy: 0.8150 - val_loss: 1.4354
Epoch 15/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 3s 23ms/step - accuracy: 0.8769 - loss: 0.5358 -
val_accuracy: 0.8153 - val_loss: 1.4315
Epoch 16/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 3s 23ms/step - accuracy: 0.8857 - loss: 0.4842 -
val_accuracy: 0.8170 - val_loss: 1.4343
Epoch 17/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 3s 23ms/step - accuracy: 0.8902 - loss: 0.4550 -
val_accuracy: 0.8167 - val_loss: 1.4393
Epoch 18/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 3s 25ms/step - accuracy: 0.8981 - loss: 0.4154 -
val_accuracy: 0.8167 - val_loss: 1.4294
Epoch 19/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 5s 24ms/step - accuracy: 0.9038 - loss: 0.3805 -
val_accuracy: 0.8170 - val_loss: 1.4372
Epoch 20/20
125/125 ━━━━━━━━━━━━━━━━━━━━ 3s 23ms/step - accuracy: 0.9105 - loss: 0.3486 -
val_accuracy: 0.8185 - val_loss: 1.4467
=================== FINAL MODEL PERFORMANCE ===================
✅ Training Accuracy : 90.53%
✅ Validation Accuracy : 81.85%
❌ Training Loss : 0.3621
❌ Validation Loss : 1.4467
===============================================================
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 108ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 110ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step
English: go
Predicted French: en route
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 26ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step
English: how are you
Predicted French: comment va
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 28ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 33ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step
English: i love you
Predicted French: je taime
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step
English: good morning
Predicted French: bonjour
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 27ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 37ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 29ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 31ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 30ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 46ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 38ms/step
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 61ms/step
English: where are you going
Predicted French: estce que je que je que je soit y aller