Practical 1:
Write a python program to implement perceptron for understanding single layer neural
networks.
import numpy as np
class Perceptron:
def __init__(self, learning_rate=0.1, epochs=10):
self.learning_rate = learning_rate
self.epochs = epochs
self.weights = None
self.bias = None
def activation_function(self, x):
# Step activation function
return np.where(x >= 0, 1, 0)
def fit(self, X, y):
# Initialize weights and bias
num_features = X.shape[1]
self.weights = np.zeros(num_features)
self.bias = 0
for epoch in range(self.epochs):
total_error = 0
for inputs, target in zip(X, y):
# Linear combination
linear_output = np.dot(inputs, self.weights) + self.bias
prediction = self.activation_function(linear_output)
# Calculate the update (error)
error = target - prediction
total_error += abs(error)
# Update rule
self.weights += self.learning_rate * error * inputs
self.bias += self.learning_rate * error
print(f"Epoch {epoch+1}/{self.epochs}, Total Error: {total_error}")
def predict(self, X):
linear_output = np.dot(X, self.weights) + self.bias
return self.activation_function(linear_output)
# Example usage: Implementing AND gate
if __name__ == "__main__":
# Input features for AND gate
X = np.array([[0, 0],
[0, 1],
[1, 0],
[1, 1]])
# AND gate labels
y = np.array([0, 0, 0, 1])
# Create Perceptron instance
perceptron = Perceptron(learning_rate=0.1, epochs=10)
perceptron.fit(X, y)
# Test predictions
print("Predictions:")
for input_data in X:
print(f"Input: {input_data}, Output: {perceptron.predict(input_data)}")
Output :
Practical 2:
Write a program to Visualize Activation Functions (Sigmoid, ReLU, Tanh).
import numpy as np
import matplotlib.pyplot as plt
# Define activation functions
x = np.linspace(-10, 10, 400)
sigmoid = 1 / (1 + np.exp(-x))
relu = np.maximum(0, x)
tanh = np.tanh(x)
# Plot Sigmoid
plt.figure()
plt.plot(x, sigmoid)
plt.title("Sigmoid Activation Function")
plt.xlabel("Input")
plt.ylabel("Output")
plt.grid(True)
plt.show()
# Plot ReLU
plt.figure()
plt.plot(x, relu)
plt.title("ReLU Activation Function")
plt.xlabel("Input")
plt.ylabel("Output")
plt.grid(True)
plt.show()
# Plot Tanh
plt.figure()
plt.plot(x, tanh)
plt.title("Tanh Activation Function")
plt.xlabel("Input")
plt.ylabel("Output")
plt.grid(True)
plt.show()
Output :
Practical 3:
Write a program to Build a Simple Feedforward Neural Network.
import numpy as np
def sigmoid(x): # Activation functions and derivatives
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(x):
return sigmoid(x) * (1 - sigmoid(x))
def relu(x):
return np.maximum(0, x)
def relu_derivative(x):
return np.where(x > 0, 1, 0)
# Neural Network Class
class SimpleNeuralNetwork:
def __init__(self, input_size, hidden_size, output_size, learning_rate=0.01):
self.learning_rate = learning_rate
# Initialize weights
self.W1 = np.random.randn(input_size, hidden_size) * 0.01
self.b1 = np.zeros((1, hidden_size))
self.W2 = np.random.randn(hidden_size, output_size) * 0.01
self.b2 = np.zeros((1, output_size))
def forward(self, X):
self.Z1 = np.dot(X, self.W1) + self.b1
self.A1 = relu(self.Z1)
self.Z2 = np.dot(self.A1, self.W2) + self.b2
self.A2 = sigmoid(self.Z2)
return self.A2
def compute_loss(self, y_true, y_pred):
m = y_true.shape[0]
loss = -1/m * np.sum(y_true * np.log(y_pred + 1e-8) + (1 - y_true) * np.log(1 - y_pred + 1e-8))
return loss
def backward(self, X, y_true):
m = y_true.shape[0]
dZ2 = self.A2 - y_true
dW2 = (1/m) * np.dot(self.A1.T, dZ2)
db2 = (1/m) * np.sum(dZ2, axis=0, keepdims=True)
dA1 = np.dot(dZ2, self.W2.T)
dZ1 = dA1 * relu_derivative(self.Z1)
dW1 = (1/m) * np.dot(X.T, dZ1)
db1 = (1/m) * np.sum(dZ1, axis=0, keepdims=True)
# Update weights
self.W1 -= self.learning_rate * dW1
self.b1 -= self.learning_rate * db1
self.W2 -= self.learning_rate * dW2
self.b2 -= self.learning_rate * db2
def train(self, X, y, epochs=1000):
for epoch in range(epochs):
y_pred = self.forward(X)
loss = self.compute_loss(y, y_pred)
self.backward(X, y)
if epoch % 100 == 0:
print(f"Epoch {epoch}, Loss: {loss:.4f}")
def predict(self, X):
y_pred = self.forward(X)
return np.where(y_pred > 0.5, 1, 0)
# Example Usage
if __name__ == "__main__":
# Simple XOR dataset (not linearly separable, good for testing hidden layers)
X = np.array([
[0, 0],
[0, 1],
[1, 0],
[1, 1] ])
y = np.array([[0], [1], [1], [0]]) # XOR target output
# Hyperparameters
input_size = 2
hidden_size = 4
output_size = 1
learning_rate = 0.1
epochs = 2000
# Initialize and train the network
nn = SimpleNeuralNetwork(input_size, hidden_size, output_size, learning_rate)
nn.train(X, y, epochs)
# Test the network
print("\nPredictions:")
predictions = nn.predict(X)
for inp, pred in zip(X, predictions):
print(f"Input: {inp}, Predicted Output: {pred}")
Output :
Practical 4:
Write a program to MNIST Digit Classification using Keras.
import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras.utils import to_categorical
import matplotlib.pyplot as plt
import numpy as np
# Step 1: Load the MNIST dataset
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# Step 2: Preprocess the data
# Normalize images to range [0,1]
x_train = x_train / 255.0
x_test = x_test / 255.0
# One-hot encode labels
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)
# Step 3: Build the Neural Network model
model = Sequential([
Flatten(input_shape=(28, 28)), # Flatten 28x28 images into 784 vector
Dense(128, activation='relu'), # Hidden layer with 128 neurons
Dense(64, activation='relu'), # Hidden layer with 64 neurons
Dense(10, activation='softmax') # Output layer for 10 classes])
# Step 4: Compile the model
model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
# Step 5: Train the model
print("Training the model...")
model.fit(x_train, y_train, epochs=5, batch_size=32, validation_split=0.1)
# Step 6: Evaluate the model
print("Evaluating the model...")
loss, accuracy = model.evaluate(x_test, y_test)
print(f"Test Accuracy: {accuracy:.4f}")
# Step 7: Make Predictions for First 5 Test Images
predictions = model.predict(x_test[:5])
predicted_classes = np.argmax(predictions, axis=1)
true_classes = np.argmax(y_test[:5], axis=1)
print("\nSample Predictions:")
for i in range(5):
print(f"Image {i+1} - True Label: {true_classes[i]}, Predicted: {predicted_classes[i]}")
# Step 8: Display the Images with Predictions
plt.figure(figsize=(10, 5))
for i in range(5):
plt.subplot(1, 5, i + 1)
plt.imshow(x_test[i], cmap='gray')
plt.title(f"T: {true_classes[i]}\nP: {predicted_classes[i]}")
plt.axis('off')
plt.suptitle("True (T) vs Predicted (P) Labels")
plt.show()
Output :
Practical 5:
Write a program to Create and Visualize CNN Layers.
import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.datasets import mnist
import matplotlib.pyplot as plt
import numpy as np
# Step 1: Load and Preprocess MNIST Dataset
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# Normalize pixel values and add channel dimension
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0
x_train = x_train.reshape(-1, 28, 28, 1)
x_test = x_test.reshape(-1, 28, 28, 1)
# Step 2: Build CNN Model (Functional API)
input_img = layers.Input(shape=(28, 28, 1), name='InputLayer')
x = layers.Conv2D(32, (3, 3), activation='relu', name='Conv1')(input_img)
x = layers.MaxPooling2D((2, 2), name='Pool1')(x)
x = layers.Conv2D(64, (3, 3), activation='relu', name='Conv2')(x)
x = layers.MaxPooling2D((2, 2), name='Pool2')(x)
x = layers.Flatten(name='Flatten')(x)
x = layers.Dense(64, activation='relu', name='Dense1')(x)
output = layers.Dense(10, activation='softmax', name='Output')(x)
model = models.Model(inputs=input_img, outputs=output)
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.summary()
# Step 3: Train the CNN
print("\nTraining the model (1 epoch for demonstration)...")
model.fit(x_train, y_train, epochs=1, batch_size=64)
# Step 4: Visualize Learned Convolutional Kernels
# Get weights of first Conv layer
filters, biases = model.get_layer('Conv1').get_weights()
print(f"Conv1 weights shape: {filters.shape}") # (3, 3, 1, 32)
num_filters = filters.shape[-1]
plt.figure(figsize=(15, 5))
for i in range(num_filters):
f = filters[:, :, 0, i] # first channel of ith filter
plt.subplot(4, 8, i + 1) # grid 4x8 for 32 filters
plt.imshow(f, cmap='gray')
plt.axis('off')
plt.title(f"Filter {i+1}")
plt.suptitle("Learned Filters of Conv1 Layer")
plt.show()
Output :
Practical 6:
Write a program to CIFAR-10 Image Classification for understanding Multiclass image
classification using CNN.
import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.datasets import cifar10
import matplotlib.pyplot as plt
import numpy as np
# Step 1: Load and Preprocess CIFAR-10 Dataset
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
# Normalize pixel values to [0,1]
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0
class_names = ['airplane','automobile','bird','cat','deer',
'dog','frog','horse','ship','truck']
# Step 2: Visualize some sample images
plt.figure(figsize=(10,5))
for i in range(10):
plt.subplot(2,5,i+1)
plt.imshow(x_train[i])
plt.title(class_names[y_train[i][0]])
plt.axis('off')
plt.suptitle("Sample CIFAR-10 Images")
plt.show()
# Step 3: Build CNN Model
model = models.Sequential([
layers.Conv2D(32, (3,3), activation='relu', padding='same', input_shape=(32,32,3)),
layers.MaxPooling2D((2,2)),
layers.Conv2D(64, (3,3), activation='relu', padding='same'),
layers.MaxPooling2D((2,2)),
layers.Conv2D(128, (3,3), activation='relu', padding='same'),
layers.MaxPooling2D((2,2)),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dense(10, activation='softmax')
])
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
model.summary()
# Step 4: Train the CNN
print("\nTraining the model...")
history = model.fit(x_train, y_train, epochs=10, batch_size=64,
validation_split=0.1)
# Step 5: Evaluate the Model
test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2)
print(f"\nTest Accuracy: {test_acc*100:.2f}%")
# Step 6: Plot Training History
plt.figure(figsize=(12,4))
# Accuracy plot
plt.subplot(1,2,1)
plt.plot(history.history['accuracy'], label='Train Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.title('Model Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
# Loss plot
plt.subplot(1,2,2)
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Model Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()
# Step 7: Make Predictions on Test Images
predictions = model.predict(x_test)
# Display first 10 predictions
plt.figure(figsize=(15,5))
for i in range(10):
plt.subplot(2,5,i+1)
plt.imshow(x_test[i])
plt.title(f"Pred: {class_names[np.argmax(predictions[i])]}\nTrue: {class_names[y_test[i][0]]}")
plt.axis('off')
plt.suptitle("CIFAR-10 Predictions")
plt.show()
Output :
Practical 7:
Write a program to implement Image Augmentation Techniques for application of
preprocessing & transformation.
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.datasets import cifar10
import matplotlib.pyplot as plt
import numpy as np
# Load CIFAR-10 Dataset
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
# Normalize images
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0
# Class names
class_names = ['airplane','automobile','bird','cat','deer', 'dog','frog','horse','ship','truck']
#Visualize Original Images
plt.figure(figsize=(10,5))
for i in range(10):
plt.subplot(2,5,i+1)
plt.imshow(x_train[i])
plt.title(class_names[y_train[i][0]])
plt.axis('off')
plt.suptitle("Original CIFAR-10 Images")
plt.show()
# ImageDataGenerator for Augmentation
datagen = ImageDataGenerator(
rotation_range=20, # Random rotation in degrees
width_shift_range=0.2, # Horizontal shift
height_shift_range=0.2, # Vertical shift
shear_range=0.15, # Shear transformation
zoom_range=0.2, # Zoom in/out
horizontal_flip=True, # Flip images horizontally
fill_mode='nearest' # Fill pixels after transformation
)
#Generate Augmented Images
sample_image = x_train[0].reshape((1,32,32,3)) # Take first image
plt.figure(figsize=(12,6))
i=0
for batch in datagen.flow(sample_image, batch_size=1):
plt.subplot(2,5,i+1)
plt.imshow(batch[0])
plt.axis('off')
plt.title(f"Aug {i+1}")
i += 1
if i >= 10:
break
plt.suptitle("Augmented Versions of Sample Image")
plt.show()
#Using tf.keras preprocessing layers (alternative method)
from tensorflow.keras import layers
augmentation_layers = tf.keras.Sequential([
layers.RandomFlip("horizontal"),
layers.RandomRotation(0.2),
layers.RandomZoom(0.2),
layers.RandomTranslation(0.1, 0.1)
])
augmented_image = augmentation_layers(sample_image)
plt.figure(figsize=(12,6))
for i in range(10):
img = augmentation_layers(sample_image)[0].numpy()
plt.subplot(2,5,i+1)
plt.imshow(img)
plt.axis('off')
plt.title(f"Aug {i+1}")
plt.suptitle("Augmented Images Using tf.keras Layers")
plt.show()
Output:
Practical 8 :
Write a program for use of dropout for regularization to improve model generalization.
import tensorflow as tf
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Flatten
from tensorflow.keras.utils import to_categorical
# Load Dataset
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# Normalize input data
x_train = x_train / 255.0
x_test = x_test / 255.0
y_train = to_categorical(y_train, 10)
y_test = to_categorical(y_test, 10)
# Build Model with Dropout Layers
model = Sequential([
Flatten(input_shape=(28, 28)),
Dense(512, activation='relu'),
Dropout(0.5), # Drop 50% of neurons
Dense(256, activation='relu'),
Dropout(0.5), # Drop another 50%
Dense(10, activation='softmax')
])
# Compile Model
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.summary() # Display Model Summary
#Train Model
history = model.fit(
x_train, y_train,
epochs=10,
batch_size=128,
validation_split=0.2
# Step 5: Evaluate Model
test_loss, test_accuracy = model.evaluate(x_test, y_test)
print(f"\nTest Accuracy: {test_accuracy * 100:.2f}%")
# Extract history
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = range(1, len(acc) + 1)
# Plot Accuracy
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.plot(epochs, acc, 'bo-', label='Training Accuracy')
plt.plot(epochs, val_acc, 'ro-', label='Validation Accuracy')
plt.title('Training vs Validation Accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
# Plot Loss
plt.subplot(1, 2, 2)
plt.plot(epochs, loss, 'bo-', label='Training Loss')
plt.plot(epochs, val_loss, 'ro-', label='Validation Loss')
plt.title('Training vs Validation Loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.tight_layout()
plt.show()
Output :
Practical 9:
Write a program to build model using pytorch.
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
# Device Configuration
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f"Using device: {device}")
# Load and Preprocess Data
transform = transforms.Compose([
transforms.ToTensor(), # Convert images to tensors
transforms.Normalize((0.5,), (0.5,)) # Normalize to [-1, 1]
])
train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
test_dataset = datasets.MNIST(root='./data', train=False, transform=transform, download=True)
train_loader = DataLoader(dataset=train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(dataset=test_dataset, batch_size=64, shuffle=False)
# Build the Model
class NeuralNet(nn.Module):
def __init__(self):
super(NeuralNet, self).__init__()
self.flatten = nn.Flatten()
self.fc1 = nn.Linear(28*28, 512)
self.relu1 = nn.ReLU()
self.fc2 = nn.Linear(512, 256)
self.relu2 = nn.ReLU()
self.fc3 = nn.Linear(256, 10)
def forward(self, x):
x = self.flatten(x)
x = self.relu1(self.fc1(x))
x = self.relu2(self.fc2(x))
x = self.fc3(x)
return x
model = NeuralNet().to(device)
print(model)
# Loss Function & Optimizer
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# Training Loop
def train_model(num_epochs=5):
model.train()
for epoch in range(num_epochs):
total_loss = 0
for images, labels in train_loader:
images, labels = images.to(device), labels.to(device)
# Forward pass
outputs = model(images)
loss = criterion(outputs, labels)
# Backward pass and optimization
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss += loss.item()
print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {total_loss/len(train_loader):.4f}")
# Evaluation
def evaluate_model():
model.eval()
correct = 0
total = 0
with torch.no_grad():
for images, labels in test_loader:
images, labels = images.to(device), labels.to(device)
outputs = model(images)
_, predictions = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predictions == labels).sum().item()
print(f"Test Accuracy: {100 * correct / total:.2f}%")
# Run Training & Testing
if __name__ == "__main__":
train_model(num_epochs=5)
evaluate_model()
Output:
Practical 10:
Write a program to compare training with and without batch normalization for
analyzing performance and convergence.
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
# Device setup
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f"Using device: {device}")
# Hyperparameters
batch_size = 64
learning_rate = 0.001
epochs = 5
# Data loading & normalization
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
test_dataset = datasets.MNIST(root='./data', train=False, transform=transform, download=True)
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
# Models: With and Without Batch Normalization
class BaselineNN(nn.Module):
def __init__(self):
super(BaselineNN, self).__init__()
self.flatten = nn.Flatten()
self.fc1 = nn.Linear(28*28, 512)
self.relu1 = nn.ReLU()
self.fc2 = nn.Linear(512, 256)
self.relu2 = nn.ReLU()
self.fc3 = nn.Linear(256, 10)
def forward(self, x):
x = self.flatten(x)
x = self.relu1(self.fc1(x))
x = self.relu2(self.fc2(x))
x = self.fc3(x)
return x
class BatchNormNN(nn.Module):
def __init__(self):
super(BatchNormNN, self).__init__()
self.flatten = nn.Flatten()
self.fc1 = nn.Linear(28*28, 512)
self.bn1 = nn.BatchNorm1d(512)
self.relu1 = nn.ReLU()
self.fc2 = nn.Linear(512, 256)
self.bn2 = nn.BatchNorm1d(256)
self.relu2 = nn.ReLU()
self.fc3 = nn.Linear(256, 10)
def forward(self, x):
x = self.flatten(x)
x = self.relu1(self.bn1(self.fc1(x)))
x = self.relu2(self.bn2(self.fc2(x)))
x = self.fc3(x)
return x
# Training & Evaluation Functions
def train_model(model, optimizer, criterion, loader):
model.train()
total_loss, correct, count = 0, 0, 0
for images, labels in loader:
images, labels = images.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
total_loss += loss.item()
_, predictions = torch.max(outputs, 1)
correct += (predictions == labels).sum().item()
count += labels.size(0)
return total_loss / len(loader), 100 * correct / count
def evaluate_model(model, loader):
model.eval()
correct, count = 0, 0
with torch.no_grad():
for images, labels in loader:
images, labels = images.to(device), labels.to(device)
outputs = model(images)
_, predictions = torch.max(outputs, 1)
correct += (predictions == labels).sum().item()
count += labels.size(0)
return 100 * correct / count
# Initialize models, optimizers, and loss function
baseline_model = BaselineNN().to(device)
batchnorm_model = BatchNormNN().to(device)
criterion = nn.CrossEntropyLoss()
optimizer_baseline = optim.Adam(baseline_model.parameters(), lr=learning_rate)
optimizer_batchnorm = optim.Adam(batchnorm_model.parameters(), lr=learning_rate)
# Track performance
history = {
'baseline_loss': [], 'batchnorm_loss': [],
'baseline_acc': [], 'batchnorm_acc': []
# Training Loop
for epoch in range(epochs):
# Train baseline model
loss_b, acc_b = train_model(baseline_model, optimizer_baseline, criterion, train_loader)
# Train batchnorm model
loss_bn, acc_bn = train_model(batchnorm_model, optimizer_batchnorm, criterion, train_loader)
# Record
history['baseline_loss'].append(loss_b)
history['batchnorm_loss'].append(loss_bn)
history['baseline_acc'].append(acc_b)
history['batchnorm_acc'].append(acc_bn)
print(f"Epoch {epoch+1}/{epochs}")
print(f"Baseline -> Loss: {loss_b:.4f}, Accuracy: {acc_b:.2f}%")
print(f"BatchNorm -> Loss: {loss_bn:.4f}, Accuracy: {acc_bn:.2f}%")
print("-" * 40)
# Plot Results
plt.figure(figsize=(12,5))
plt.subplot(1,2,1)
plt.plot(history['baseline_loss'], label='Without BatchNorm')
plt.plot(history['batchnorm_loss'], label='With BatchNorm')
plt.title('Training Loss Comparison')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.subplot(1,2,2)
plt.plot(history['baseline_acc'], label='Without BatchNorm')
plt.plot(history['batchnorm_acc'], label='With BatchNorm')
plt.title('Training Accuracy Comparison')
plt.xlabel('Epochs')
plt.ylabel('Accuracy (%)')
plt.legend()
plt.tight_layout()
plt.show()
Output :