Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
41 views

Deep Learning Lab Practicals

Uploaded by

Gaurav Sharma
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
41 views

Deep Learning Lab Practicals

Uploaded by

Gaurav Sharma
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 24

DEEP LEARNING LAB PRACTICALS

January 3, 2025

1 Practical 1: Implement a simple Perceptron


To implement a simple Perceptron, we can follow these steps:
1. Initialize the weights and bias.
2. Define the activation function (usually a step function for the Perceptron).
3. Implement the training process where weights are updated based on the error between the
predicted output and the actual label.
4. Test the model after training.

[5]: import numpy as np

# Step 1: Define the Perceptron class


class Perceptron:
def __init__(self, input_size, learning_rate=0.01, epochs=1000):
self.input_size = input_size
self.learning_rate = learning_rate
self.epochs = epochs
self.weights = np.zeros(input_size) # Initialize weights to zeros
self.bias = 0 # Initialize bias to zero

# Step 2: Define the activation function (Step function)


def activation(self, x):
return 1 if x >= 0 else 0 # Step function: outputs 1 if x >= 0, else 0

# Step 3: Define the training function


def train(self, X, y):
for epoch in range(self.epochs):
for i in range(len(X)):
linear_output = np.dot(X[i], self.weights) + self.bias
prediction = self.activation(linear_output)
error = y[i] - prediction
# Update weights and bias based on the error
self.weights += self.learning_rate * error * X[i]
self.bias += self.learning_rate * error

# Step 4: Define the prediction function

1
def predict(self, X):
predictions = []
for i in range(len(X)):
linear_output = np.dot(X[i], self.weights) + self.bias
prediction = self.activation(linear_output)
predictions.append(prediction)
return predictions

# Step 5: Example usage


if __name__ == "__main__":
# Example OR gate data (input, expected output)
# Input data (X) and labels (y)
X = np.array([[0, 0],
[0, 1],
[1, 0],
[1, 1]])
y = np.array([0, 1, 1, 1]) # OR gate outputs

# Step 6: Create a Perceptron instance


perceptron = Perceptron(input_size=2, learning_rate=0.1, epochs=10)

# Train the model


perceptron.train(X, y)

# Test the trained model


predictions = perceptron.predict(X)
print("Predictions:", predictions)

# Check the learned weights and bias


print("Weights:", perceptron.weights)
print("Bias:", perceptron.bias)

Predictions: [0, 1, 1, 1]
Weights: [0.1 0.1]
Bias: -0.1

2 Practical 2: Implement Digit Classification: Neural network to


classify MNIST dataset
To implement a neural network for classifying the MNIST dataset (handwritten digits), we can
use Python libraries like Keras (which is part of TensorFlow). This will simplify the process of
building and training the model. Here’s an implementation using a neural network with a simple
architecture to classify MNIST digits.

2
2.0.1 Steps for Implementation:
1. Load the MNIST dataset.
2. Preprocess the data (normalize, reshape, etc.).
3. Build the neural network model.
4. Compile the model with an optimizer, loss function, and metrics.
5. Train the model on the MNIST dataset.
6. Evaluate the model on the test set.
7. Make predictions on new data.
Install Required Libraries
!pip install tensorflow

[1]: import tensorflow as tf


from tensorflow.keras import layers, models
from tensorflow.keras.datasets import mnist
from tensorflow.keras.utils import to_categorical

# Step 1: Load the MNIST dataset


(x_train, y_train), (x_test, y_test) = mnist.load_data()

# Step 2: Preprocess the data


# Normalize the images to a [0, 1] range
x_train = x_train / 255.0
x_test = x_test / 255.0

# Flatten the images from 28x28 to 784-dimensional vectors


x_train = x_train.reshape(-1, 28*28)
x_test = x_test.reshape(-1, 28*28)

# One-hot encode the labels (convert to a binary matrix)


y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)

# Step 3: Build the Neural Network model


model = models.Sequential([
layers.Dense(128, activation='relu', input_shape=(28*28,)), # Hidden layer␣
↪with 128 neurons and ReLU activation

layers.Dropout(0.2), # Dropout layer to prevent overfitting


layers.Dense(10, activation='softmax') # Output layer with 10 neurons (one␣
↪for each digit)

])

# Step 4: Compile the model


model.compile(optimizer='adam', # Adam optimizer

3
loss='categorical_crossentropy', # Loss function for multi-class␣
↪classification
metrics=['accuracy']) # Metric to track

# Step 5: Train the model


model.fit(x_train, y_train, epochs=5, batch_size=32, validation_data=(x_test,␣
↪y_test))

# Step 6: Evaluate the model on the test set


test_loss, test_acc = model.evaluate(x_test, y_test)
print(f"Test accuracy: {test_acc}")

# Step 7: Make predictions


predictions = model.predict(x_test)

# Let's print the first prediction


import numpy as np
print(f"First prediction: {np.argmax(predictions[0])}")
print(f"True label: {np.argmax(y_test[0])}")

Epoch 1/5
1875/1875 [==============================] - 6s 3ms/step - loss: 0.3030 -
accuracy: 0.9121 - val_loss: 0.1391 - val_accuracy: 0.9576
Epoch 2/5
1875/1875 [==============================] - 4s 2ms/step - loss: 0.1467 -
accuracy: 0.9569 - val_loss: 0.0991 - val_accuracy: 0.9700
Epoch 3/5
1875/1875 [==============================] - 4s 2ms/step - loss: 0.1088 -
accuracy: 0.9672 - val_loss: 0.0861 - val_accuracy: 0.9737
Epoch 4/5
1875/1875 [==============================] - 4s 2ms/step - loss: 0.0908 -
accuracy: 0.9724 - val_loss: 0.0780 - val_accuracy: 0.9766
Epoch 5/5
1875/1875 [==============================] - 4s 2ms/step - loss: 0.0751 -
accuracy: 0.9768 - val_loss: 0.0765 - val_accuracy: 0.9756
313/313 [==============================] - 0s 1ms/step - loss: 0.0765 -
accuracy: 0.9756
Test accuracy: 0.975600004196167
313/313 [==============================] - 0s 1ms/step
First prediction: 7
True label: 7

4
3 Practical 3: Implement a simple CNN starting from filtering,
Convolution and pooling operations and arithmetic of these with
Visualization in PyTorch and Tensorflow
Implementing a simple Convolutional Neural Network (CNN) that demonstrates the filtering, con-
volution, and pooling operations, along with the arithmetic involved, in both PyTorch and Tensor-
Flow, is a great way to understand how CNNs work. Below is a step-by-step approach to building
this in both frameworks.

3.0.1 Step-by-Step Plan:


1. Creating Input Image: Start by creating a simple image (e.g., a small 5x5 image with one
channel).
2. Applying Convolution: Use a convolutional filter to perform convolution on the image.
3. Pooling: Apply a pooling operation (e.g., Max Pooling).
4. Visualizing: Visualize the input, output after convolution, and output after pooling for both
frameworks.

[4]: import torch


import torch.nn as nn
import torch.nn.functional as F
import matplotlib.pyplot as plt

# Step 1: Create a simple 5x5 image (one channel)


image = torch.tensor([[0., 0., 0., 0., 0.],
[0., 1., 1., 1., 0.],
[0., 1., 1., 1., 0.],
[0., 1., 1., 1., 0.],
[0., 0., 0., 0., 0.]])
image = image.unsqueeze(0).unsqueeze(0) # Add batch and channel dimensions

# Step 2: Define a simple filter (3x3 filter, one channel)


kernel = torch.tensor([[[[0., 1., 0.],
[1., -4., 1.],
[0., 1., 0.]]]])

# Step 3: Convolution operation (valid padding)


conv = F.conv2d(image, kernel, stride=1, padding=0)

# Step 4: Apply Max Pooling (2x2)


pooled = F.max_pool2d(conv, kernel_size=2, stride=2)

# Step 5: Visualize the input, convolution output, and pooled output


fig, ax = plt.subplots(1, 3, figsize=(15, 5))

# Convert tensor to numpy for visualization


ax[0].imshow(image.squeeze().numpy(), cmap='gray')

5
ax[0].set_title('Input Image')
ax[0].axis('off')

ax[1].imshow(conv.squeeze().detach().numpy(), cmap='gray')
ax[1].set_title('After Convolution')
ax[1].axis('off')

# Ensure the pooled output retains 2D shape for visualization


pooled_image = pooled.squeeze(0).squeeze(0) # Remove batch and channel␣
↪dimensions

ax[2].imshow(pooled_image.detach().numpy(), cmap='gray')
ax[2].set_title('After Max Pooling')
ax[2].axis('off')

plt.show()

4 Practical 4: Implement Text processing, Language Modeling


using RNN
Implementing text processing and language modeling using a Recurrent Neural Network (RNN)
involves the following steps:
1. Text Preprocessing: Clean and tokenize the text data to prepare it for training.
2. Building the RNN Model: Define an RNN-based model for language modeling, which predicts
the next word given the previous words in a sequence.
3. Training the Model: Train the model on the processed data.
4. Evaluating the Model: Check how well the model generates or predicts text sequences.

[10]: import torch


import torch.nn as nn

6
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
import numpy as np

# Step 1: Prepare the Text Data and Tokenize


text = """
Python is an interpreted high-level general-purpose programming language.␣
↪Python's design philosophy emphasizes code readability with its notable use␣

↪of significant indentation. Its syntax allows programmers to express␣

↪concepts in fewer lines of code than would be possible in languages such as␣

↪C++ or Java.

Python is dynamically typed and garbage-collected. It supports multiple␣


↪programming paradigms, including structured (particularly procedural),␣

↪object-oriented, and functional programming.

"""

# Create a set of unique characters from the text


chars = sorted(set(text))
vocab_size = len(chars)

# Create mappings from characters to indices and vice versa


char_to_idx = {ch: idx for idx, ch in enumerate(chars)}
idx_to_char = {idx: ch for idx, ch in enumerate(chars)}

# Convert the text into a list of indices


text_as_int = [char_to_idx[ch] for ch in text]

# Step 2: Create Dataset for Sequence Prediction


class TextDataset(Dataset):
def __init__(self, text_as_int, seq_length):
self.text_as_int = text_as_int
self.seq_length = seq_length

def __len__(self):
return len(self.text_as_int) - self.seq_length

def __getitem__(self, idx):


# Create input-output pairs
input_seq = torch.tensor(self.text_as_int[idx:idx + self.seq_length])
target_seq = torch.tensor(self.text_as_int[idx + 1:idx + self.
↪seq_length + 1])

return input_seq, target_seq

seq_length = 30
dataset = TextDataset(text_as_int, seq_length)
dataloader = DataLoader(dataset, batch_size=64, shuffle=True)

7
# Step 3: Define the RNN Language Model
class RNNLanguageModel(nn.Module):
def __init__(self, vocab_size, embedding_dim, hidden_dim, seq_length):
super(RNNLanguageModel, self).__init__()

self.embedding = nn.Embedding(vocab_size, embedding_dim)


self.rnn = nn.RNN(embedding_dim, hidden_dim, batch_first=True)
self.fc = nn.Linear(hidden_dim, vocab_size)

def forward(self, x):


# Embedding lookup for the input
x = self.embedding(x)

# RNN layer
out, _ = self.rnn(x)

# Output layer
out = self.fc(out)
return out

# Step 4: Initialize the Model, Loss, and Optimizer


embedding_dim = 128
hidden_dim = 256
model = RNNLanguageModel(vocab_size, embedding_dim, hidden_dim, seq_length)

criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Step 5: Training the Model


def train_model(model, dataloader, criterion, optimizer, epochs=5):
model.train()
for epoch in range(epochs):
total_loss = 0
for input_seq, target_seq in dataloader:
optimizer.zero_grad()
output = model(input_seq)

# Flatten the outputs and targets


output = output.view(-1, vocab_size)
target_seq = target_seq.view(-1)

loss = criterion(output, target_seq)


loss.backward()
optimizer.step()

total_loss += loss.item()

8
print(f"Epoch [{epoch+1}/{epochs}], Loss: {total_loss/len(dataloader)}")

# Train the model


train_model(model, dataloader, criterion, optimizer, epochs=10)

# Step 6: Evaluating the Model (Generate Text with Temperature Sampling)


def generate_text_with_temperature(model, start_text, length=200, temperature=1.
↪0):

model.eval()

input_seq = [char_to_idx[ch] for ch in start_text]


input_seq = torch.tensor(input_seq).unsqueeze(0) # Add batch dimension

generated_text = start_text
with torch.no_grad():
for _ in range(length):
output = model(input_seq)
output = output.squeeze(0) # Remove batch dimension

# Apply temperature scaling to logits


output = output / temperature

# Softmax to get probabilities


prob = torch.nn.functional.softmax(output[-1], dim=0)

# Sample a character index based on the probability distribution


predicted_idx = torch.multinomial(prob, 1).item()

# Add predicted character to the generated text


predicted_char = idx_to_char[predicted_idx]
generated_text += predicted_char

# Update input sequence with predicted character


input_seq = torch.cat((input_seq[:, 1:], torch.
↪tensor([[predicted_idx]])), dim=1)

return generated_text

# Example usage with temperature setting


start_text = "Python is"
generated = generate_text_with_temperature(model, start_text, length=300,␣
↪temperature=0.7)

print("\nGenerated Text:\n")
print(generated)

Epoch [1/10], Loss: 3.186570882797241


Epoch [2/10], Loss: 2.4967474043369293

9
Epoch [3/10], Loss: 2.1279394328594208
Epoch [4/10], Loss: 1.8134359568357468
Epoch [5/10], Loss: 1.537606194615364
Epoch [6/10], Loss: 1.2762676626443863
Epoch [7/10], Loss: 1.0253751650452614
Epoch [8/10], Loss: 0.8073843643069267
Epoch [9/10], Loss: 0.6257664263248444
Epoch [10/10], Loss: 0.49387771263718605

Generated Text:

Python is dynamically typed halizes of code than portaben le er lines ouage-


collected. It supports muledphigh-level general-purpose programming languages
such as C++ or Java.
Python is digh-lont indentation. Its such lewprograligns gunctitntedural), obje
ts in fevel geseduraliyntepress concepts in fecertein

5 Practical 5: Implement Time Series Prediction using RNN


To implement time series prediction using a Recurrent Neural Network (RNN) in PyTorch, we can
follow these steps:
1. Data Preparation: Load and preprocess the time series data, including normalization and
sequence generation.
2. Model Architecture: Define the RNN-based model for prediction.
3. Training: Train the model using the training dataset.
4. Evaluation: Use the model to predict future time steps.
5. Visualization: Plot the predicted values vs. actual values.

[12]: import torch


import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler

# Step 1: Generate and Preprocess the Time Series Data


# Generate a sine wave as a time series
time = np.linspace(0, 100, 1000)
data = np.sin(time)

# Normalize the data to the range [0, 1] using MinMaxScaler


scaler = MinMaxScaler(feature_range=(0, 1))
data_normalized = scaler.fit_transform(data.reshape(-1, 1)).reshape(-1)

10
# Convert data to a PyTorch tensor
data_tensor = torch.tensor(data_normalized, dtype=torch.float32)

# Create input-output sequences for training


def create_sequences(data, seq_length):
input_seq = []
output_seq = []
for i in range(len(data) - seq_length):
input_seq.append(data[i:i + seq_length])
output_seq.append(data[i + seq_length])
return torch.stack(input_seq), torch.stack(output_seq)

# Sequence length for RNN input


seq_length = 50

# Create training sequences


X, y = create_sequences(data_tensor, seq_length)

# Split into train and test sets


train_size = int(len(X) * 0.8)
X_train, X_test = X[:train_size], X[train_size:]
y_train, y_test = y[:train_size], y[train_size:]

# Step 2: Define the RNN Model


class RNNTimeSeriesModel(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(RNNTimeSeriesModel, self).__init__()
self.rnn = nn.RNN(input_size, hidden_size, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)

def forward(self, x):


out, _ = self.rnn(x)
out = self.fc(out[:, -1, :]) # Only use the last hidden state
return out

# Model parameters
input_size = 1 # One feature (sine wave value)
hidden_size = 64
output_size = 1 # Predicting one value
learning_rate = 0.001

# Instantiate the model, loss function, and optimizer


model = RNNTimeSeriesModel(input_size, hidden_size, output_size)
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)

11
# Step 3: Training the Model
def train_model(model, X_train, y_train, criterion, optimizer, epochs=100):
model.train()
for epoch in range(epochs):
optimizer.zero_grad()
output = model(X_train.unsqueeze(-1)) # Add feature dimension
loss = criterion(output, y_train.unsqueeze(-1))
loss.backward()
optimizer.step()

if (epoch + 1) % 10 == 0:
print(f"Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}")

# Train the model


train_model(model, X_train, y_train, criterion, optimizer, epochs=100)

# Step 4: Evaluating the Model (Prediction)


model.eval()
with torch.no_grad():
# Predict on test data
predictions = model(X_test.unsqueeze(-1))

# Inverse transform the predictions and actual values back to original scale
predictions = scaler.inverse_transform(predictions.numpy())
y_test_original = scaler.inverse_transform(y_test.numpy().reshape(-1, 1))

# Step 5: Visualization
plt.figure(figsize=(10, 6))
plt.plot(time[train_size + seq_length:], y_test_original, label="Actual")
plt.plot(time[train_size + seq_length:], predictions, label="Predicted",␣
↪linestyle='--')

plt.title('Time Series Prediction using RNN')


plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.show()

Epoch [10/100], Loss: 0.0694


Epoch [20/100], Loss: 0.0469
Epoch [30/100], Loss: 0.0205
Epoch [40/100], Loss: 0.0118
Epoch [50/100], Loss: 0.0042
Epoch [60/100], Loss: 0.0024
Epoch [70/100], Loss: 0.0010
Epoch [80/100], Loss: 0.0004
Epoch [90/100], Loss: 0.0002
Epoch [100/100], Loss: 0.0002

12
6 Practical 6: Implement Sentiment Analysis using LSTM
Implementing sentiment analysis using an LSTM (Long Short-Term Memory) model in PyTorch
involves the following steps:
1. Data Preprocessing: Tokenizing the text and converting it to numerical representations (like
word embeddings).
2. Model Building: Defining the architecture using LSTM layers for sequential processing.
3. Training the Model: Training the model with the dataset and monitoring its performance.
4. Evaluation: Evaluating the model on unseen test data.
5. Prediction: Using the trained model to predict the sentiment of new text inputs.

[23]: import torch


import torch.nn as nn
import torch.optim as optim
import numpy as np
from torch.utils.data import DataLoader, Dataset
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import re
import nltk

13
from nltk.tokenize import word_tokenize
from collections import Counter
from torch.nn.utils.rnn import pad_sequence

# Download punkt for tokenization


nltk.download('punkt')

# Step 1: Load and Preprocess the Data (IMDB Dataset)


# For simplicity, we'll use a small subset of the dataset. In real␣
↪applications, use the full dataset.

def preprocess_text(text):
text = text.lower()
text = re.sub(r'\W', ' ', text) # Remove non-alphabetical characters
text = re.sub(r'\s+', ' ', text) # Remove multiple spaces
return text

# Example dataset (simplified for demonstration)


positive_reviews = [
"I loved this movie, it was fantastic!",
"This is one of the best movies I've ever seen.",
"Amazing performance by the lead actor. Great movie.",
"Great direction and screenplay. Really enjoyed it!"
]

negative_reviews = [
"The movie was boring and predictable.",
"Waste of time. Terrible plot and bad acting.",
"Not worth watching, I fell asleep halfway through.",
"This movie is awful. Don't waste your time."
]

# Create labels
positive_labels = [1] * len(positive_reviews) # Positive reviews labeled as 1
negative_labels = [0] * len(negative_reviews) # Negative reviews labeled as 0

# Combine the reviews and labels


reviews = positive_reviews + negative_reviews
labels = positive_labels + negative_labels

# Step 2: Tokenize the text and create vocabulary


def tokenize_text(reviews):
return [word_tokenize(preprocess_text(review)) for review in reviews]

tokenized_reviews = tokenize_text(reviews)

# Create vocabulary (mapping words to integers)

14
word_counter = Counter([word for review in tokenized_reviews for word in␣
↪review])

vocab = {word: idx + 1 for idx, (word, _) in enumerate(word_counter.


↪most_common())} # Start indices from 1 (0 is reserved for padding)

# Step 3: Convert text data to numerical data (using the vocabulary)


def text_to_sequence(text, vocab):
return [vocab.get(word, 0) for word in text] # 0 for words not in␣
↪vocabulary

sequences = [text_to_sequence(review, vocab) for review in tokenized_reviews]

# Step 4: Padding sequences to ensure uniform input size


def pad_sequences(sequences):
return pad_sequence([torch.tensor(seq) for seq in sequences],␣
↪batch_first=True, padding_value=0)

# Padding the sequences


padded_sequences = pad_sequences(sequences)

# Step 5: Create a custom dataset for PyTorch


class SentimentDataset(Dataset):
def __init__(self, padded_sequences, labels):
self.data = padded_sequences
self.labels = torch.tensor(labels, dtype=torch.long)

def __len__(self):
return len(self.data)

def __getitem__(self, idx):


return self.data[idx], self.labels[idx]

# Create a DataLoader
dataset = SentimentDataset(padded_sequences, labels)
train_data, test_data = train_test_split(dataset, test_size=0.2,␣
↪random_state=42)

train_loader = DataLoader(train_data, batch_size=2, shuffle=True)


test_loader = DataLoader(test_data, batch_size=2, shuffle=False)

# Step 6: Build the LSTM Model


class SentimentLSTM(nn.Module):
def __init__(self, vocab_size, embedding_dim, hidden_dim, output_dim):
super(SentimentLSTM, self).__init__()
self.embedding = nn.Embedding(vocab_size, embedding_dim)
self.lstm = nn.LSTM(embedding_dim, hidden_dim, batch_first=True)
self.fc = nn.Linear(hidden_dim, output_dim)
self.softmax = nn.Softmax(dim=1)

15
def forward(self, x):
embedded = self.embedding(x)
lstm_out, (hidden, cell) = self.lstm(embedded)
output = self.fc(hidden[-1]) # Use the last hidden state
return self.softmax(output)

# Hyperparameters
vocab_size = len(vocab) + 1 # Add 1 for padding token
embedding_dim = 100
hidden_dim = 128
output_dim = 2 # Positive (1) or Negative (0)
learning_rate = 0.001

# Initialize model, loss function, and optimizer


model = SentimentLSTM(vocab_size, embedding_dim, hidden_dim, output_dim)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)

# Step 7: Train the Model


def train(model, train_loader, criterion, optimizer, epochs=5):
model.train()
for epoch in range(epochs):
epoch_loss = 0
epoch_accuracy = 0
for data, labels in train_loader:
optimizer.zero_grad()
output = model(data)
loss = criterion(output, labels)
loss.backward()
optimizer.step()

epoch_loss += loss.item()
preds = torch.argmax(output, dim=1)
epoch_accuracy += accuracy_score(labels.numpy(), preds.numpy())

print(f'Epoch [{epoch+1}/{epochs}], Loss: {epoch_loss/len(train_loader):


↪.4f}, Accuracy: {epoch_accuracy/len(train_loader):.4f}')

# Train the model


train(model, train_loader, criterion, optimizer, epochs=5)

# Step 8: Evaluate the Model


def evaluate(model, test_loader):
model.eval()
predictions = []
labels = []

16
with torch.no_grad():
for data, target in test_loader:
output = model(data)
preds = torch.argmax(output, dim=1)
predictions.extend(preds.numpy())
labels.extend(target.numpy())

accuracy = accuracy_score(labels, predictions)


print(f'Test Accuracy: {accuracy:.4f}')

evaluate(model, test_loader)

# Step 9: Make Predictions


def predict_sentiment(model, text, vocab):
tokenized = word_tokenize(preprocess_text(text))
sequence = torch.tensor(text_to_sequence(tokenized, vocab)).unsqueeze(0)
prediction = model(sequence)
sentiment = torch.argmax(prediction, dim=1).item()
return "Positive" if sentiment == 1 else "Negative"

# Test the prediction function


new_review = "This movie was awesome, I really enjoyed it!"
print(f"Predicted Sentiment: {predict_sentiment(model, new_review, vocab)}")

new_review = "This movie is awful. Don't waste your time for this."
print(f"Predicted Sentiment: {predict_sentiment(model, new_review, vocab)}")

Epoch [1/5], Loss: 0.6984, Accuracy: 0.5000


Epoch [2/5], Loss: 0.6780, Accuracy: 0.6667
Epoch [3/5], Loss: 0.6894, Accuracy: 0.5000
Epoch [4/5], Loss: 0.6574, Accuracy: 0.5000
Epoch [5/5], Loss: 0.6356, Accuracy: 0.8333
Test Accuracy: 0.5000
Predicted Sentiment: Positive
Predicted Sentiment: Negative
[nltk_data] Downloading package punkt to
[nltk_data] C:\Users\ramak\AppData\Roaming\nltk_data…
[nltk_data] Package punkt is already up-to-date!

7 Practical 7: Implement an image generation model using GAN


Implementing an image generation model using a Generative Adversarial Network (GAN) involves
training two networks: a Generator and a Discriminator. The Generator tries to generate realistic
images from random noise, while the Discriminator tries to distinguish between real and fake
images. The two networks are trained together, with the Generator improving to create more

17
realistic images over time.

7.0.1 Steps:
1. Define the Generator Network: This network takes random noise as input and outputs an
image.
2. Define the Discriminator Network: This network takes an image as input and outputs a
probability of whether the image is real or fake.
3. Train the GAN: The Generator and Discriminator are trained together. The Generator tries
to fool the Discriminator, while the Discriminator tries to correctly classify real and fake
images.

[24]: import torch


import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt

# Hyperparameters
batch_size = 64
latent_dim = 100
epochs = 50
lr = 0.0002
beta1 = 0.5

# Step 1: Prepare the dataset (MNIST in this case)


transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize([0.5], [0.5]) # Normalize to range [-1, 1]
])

# Load the MNIST dataset


dataset = datasets.MNIST(root='./data', train=True, download=True,␣
↪transform=transform)

dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)

# Step 2: Define the Generator Network


class Generator(nn.Module):
def __init__(self):
super(Generator, self).__init__()
self.fc = nn.Sequential(
nn.Linear(latent_dim, 256),
nn.ReLU(True),
nn.Linear(256, 512),
nn.ReLU(True),
nn.Linear(512, 1024),
nn.ReLU(True),

18
nn.Linear(1024, 28*28),
nn.Tanh() # Output the image in the range [-1, 1]
)

def forward(self, z):


return self.fc(z).view(-1, 1, 28, 28)

# Step 3: Define the Discriminator Network


class Discriminator(nn.Module):
def __init__(self):
super(Discriminator, self).__init__()
self.fc = nn.Sequential(
nn.Linear(28*28, 1024),
nn.LeakyReLU(0.2, inplace=True),
nn.Linear(1024, 512),
nn.LeakyReLU(0.2, inplace=True),
nn.Linear(512, 256),
nn.LeakyReLU(0.2, inplace=True),
nn.Linear(256, 1),
nn.Sigmoid() # Output probability between 0 and 1
)

def forward(self, img):


return self.fc(img.view(-1, 28*28))

# Step 4: Initialize the networks and optimizers


generator = Generator()
discriminator = Discriminator()

# Use binary cross-entropy loss


criterion = nn.BCELoss()

# Optimizers
optimizer_G = optim.Adam(generator.parameters(), lr=lr, betas=(beta1, 0.999))
optimizer_D = optim.Adam(discriminator.parameters(), lr=lr, betas=(beta1, 0.
↪999))

# Step 5: Training the GAN


real_labels = torch.ones(batch_size, 1)
fake_labels = torch.zeros(batch_size, 1)

# Function to save generated images during training


def save_generated_images(epoch, generator):
z = torch.randn(16, latent_dim) # Random noise
generated_images = generator(z)
generated_images = generated_images.detach().cpu().numpy()

19
fig, axes = plt.subplots(4, 4, figsize=(4, 4))
for i in range(4):
for j in range(4):
axes[i, j].imshow(generated_images[i*4 + j, 0], cmap='gray')
axes[i, j].axis('off')
plt.tight_layout()
plt.savefig(f'gan_generated_images_epoch_{epoch}.png')

# Training loop
for epoch in range(epochs):
for i, (imgs, _) in enumerate(dataloader):
# Train the Discriminator
real_imgs = imgs
batch_size = real_imgs.size(0)

# Real images
optimizer_D.zero_grad()
outputs = discriminator(real_imgs)
d_loss_real = criterion(outputs, real_labels[:batch_size])
d_loss_real.backward()

# Fake images
z = torch.randn(batch_size, latent_dim)
fake_imgs = generator(z)
outputs = discriminator(fake_imgs.detach()) # Detach to avoid updating␣
↪generator

d_loss_fake = criterion(outputs, fake_labels[:batch_size])


d_loss_fake.backward()

optimizer_D.step()

# Train the Generator


optimizer_G.zero_grad()
outputs = discriminator(fake_imgs)
g_loss = criterion(outputs, real_labels[:batch_size]) # We want to␣
↪fool the discriminator

g_loss.backward()

optimizer_G.step()

print(f"Epoch [{epoch+1}/{epochs}], D Loss: {d_loss_real.item() +␣


↪d_loss_fake.item()}, G Loss: {g_loss.item()}")

# Save generated images every few epochs


if (epoch + 1) % 10 == 0:
save_generated_images(epoch + 1, generator)

20
# Save final generator model
torch.save(generator.state_dict(), "generator.pth")

Epoch [1/50], D Loss: 0.5450341179966927, G Loss: 2.878868579864502


Epoch [2/50], D Loss: 0.18310445547103882, G Loss: 3.3271563053131104
Epoch [3/50], D Loss: 0.1819976568222046, G Loss: 3.868860960006714
Epoch [4/50], D Loss: 0.14792035520076752, G Loss: 3.6470236778259277
Epoch [5/50], D Loss: 0.13293325155973434, G Loss: 2.605674982070923
Epoch [6/50], D Loss: 0.00015677801945912506, G Loss: 8.693428039550781
Epoch [7/50], D Loss: 0.07591450400650501, G Loss: 5.403898239135742
Epoch [8/50], D Loss: 7.522566738771275e-05, G Loss: 9.57593059539795
Epoch [9/50], D Loss: 2.565526847320143e-05, G Loss: 10.601685523986816
Epoch [10/50], D Loss: 3.4475977370791895e-16, G Loss: 35.60368347167969
Epoch [11/50], D Loss: 3.6619301599590296e-16, G Loss: 35.543373107910156
Epoch [12/50], D Loss: 3.9381221930702393e-16, G Loss: 35.47065734863281
Epoch [13/50], D Loss: 4.2006105565838545e-16, G Loss: 35.40613555908203
Epoch [14/50], D Loss: 4.561077603386539e-16, G Loss: 35.32380294799805
Epoch [15/50], D Loss: 5.067992941000347e-16, G Loss: 35.218414306640625
Epoch [16/50], D Loss: 5.61294429311061e-16, G Loss: 35.11628723144531
Epoch [17/50], D Loss: 6.65764243712295e-16, G Loss: 34.945594787597656
Epoch [18/50], D Loss: 8.940543931343467e-16, G Loss: 34.65076446533203
Epoch [19/50], D Loss: 9.824003530494439e-16, G Loss: 34.55653381347656
Epoch [20/50], D Loss: 1.2399244152778792e-15, G Loss: 34.323726654052734
Epoch [21/50], D Loss: 0.0538494810461998, G Loss: 4.157371520996094
Epoch [22/50], D Loss: 0.0004930826885924944, G Loss: 7.643937110900879
Epoch [23/50], D Loss: 0.0015491027170355665, G Loss: 6.584824085235596
Epoch [24/50], D Loss: 4.7994718443078455e-05, G Loss: 10.041024208068848
Epoch [25/50], D Loss: 1.3537006453123723e-05, G Loss: 11.204964637756348
Epoch [26/50], D Loss: 4.6131285675876654e-06, G Loss: 12.293279647827148
Epoch [27/50], D Loss: 6.4334122598097565e-06, G Loss: 11.94644546508789
Epoch [28/50], D Loss: 1.108562344143138e-06, G Loss: 13.774178504943848
Epoch [29/50], D Loss: 0.0003794255171669647, G Loss: 9.251630783081055
Epoch [30/50], D Loss: 3.0258550850703614e-05, G Loss: 10.58187484741211
Epoch [31/50], D Loss: 8.560067499274737e-06, G Loss: 11.817144393920898
Epoch [32/50], D Loss: 4.574557664227541e-06, G Loss: 12.355972290039062
Epoch [33/50], D Loss: 2.409948578474541e-06, G Loss: 13.040305137634277
Epoch [34/50], D Loss: 4.589434560386962e-06, G Loss: 12.355203628540039
Epoch [35/50], D Loss: 3.1998293508195275e-06, G Loss: 12.74063777923584
Epoch [36/50], D Loss: 3.7595689228453466e-07, G Loss: 14.87509822845459
Epoch [37/50], D Loss: 100.0, G Loss: 0.0
Epoch [38/50], D Loss: 100.0, G Loss: 0.0
Epoch [39/50], D Loss: 100.0, G Loss: 0.0
Epoch [40/50], D Loss: 100.0, G Loss: 0.0
Epoch [41/50], D Loss: 100.0, G Loss: 0.0
Epoch [42/50], D Loss: 100.0, G Loss: 0.0
Epoch [43/50], D Loss: 100.0, G Loss: 0.0
Epoch [44/50], D Loss: 100.0, G Loss: 0.0
Epoch [45/50], D Loss: 100.0, G Loss: 0.0

21
Epoch [46/50], D Loss: 100.0, G Loss: 0.0
Epoch [47/50], D Loss: 100.0, G Loss: 0.0
Epoch [48/50], D Loss: 100.0, G Loss: 0.0
Epoch [49/50], D Loss: 100.0, G Loss: 0.0
Epoch [50/50], D Loss: 100.0, G Loss: 0.0

22
23
24

You might also like