Experiment 1: ANN Using Keras Library and Various Activation Experiment 1: ANN Using Keras Library and Various Activation Functions Functions
Experiment 1: ANN Using Keras Library and Various Activation Experiment 1: ANN Using Keras Library and Various Activation Functions Functions
Functions
In [1]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, models
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
from tensorflow.keras.utils import to_categorical
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification
from sklearn.preprocessing import StandardScaler
In [2]:
# Generate a classification dataset
X, y = make_classification(n_samples=1000, n_features=20, n_informative=15,
n_redundant=5, random_state=42)
In [3]:
def create_model(activation='relu'):
model = Sequential([
Dense(64, activation=activation, input_shape=(X_train.shape[1],)),
Dense(32, activation=activation),
Dense(16, activation=activation),
Dense(1, activation='sigmoid') # Output layer with sigmoid for binary classific
ation
])
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
return model
c:\Users\Rishi\AppData\Local\Programs\Python\Python312\Lib\site-packages\keras\src\layers
\core\dense.py:87: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a la
yer. When using Sequential models, prefer using an `Input(shape)` object as the first lay
er in the model instead.
super().__init__(activity_regularizer=activity_regularizer, **kwargs)
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ dense (Dense) │ (None, 64) │ 1,344 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_1 (Dense) │ (None, 32) │ 2,080 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_2 (Dense) │ (None, 16) │ 528 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_3 (Dense) │ (None, 1) │ 17 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
Model: "sequential_1"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ dense_4 (Dense) │ (None, 64) │ 1,344 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_5 (Dense) │ (None, 32) │ 2,080 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_6 (Dense) │ (None, 16) │ 528 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_7 (Dense) │ (None, 1) │ 17 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
Model: "sequential_2"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ dense_8 (Dense) │ (None, 64) │ 1,344 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_9 (Dense) │ (None, 32) │ 2,080 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_10 (Dense) │ (None, 16) │ 528 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_11 (Dense) │ (None, 1) │ 17 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
└─────────────────────────────────┴────────────────────────┴───────────────┘
Model: "sequential_3"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ dense_12 (Dense) │ (None, 64) │ 1,344 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_13 (Dense) │ (None, 32) │ 2,080 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_14 (Dense) │ (None, 16) │ 528 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_15 (Dense) │ (None, 1) │ 17 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
Model: "sequential_4"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ dense_16 (Dense) │ (None, 64) │ 1,344 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_17 (Dense) │ (None, 32) │ 2,080 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_18 (Dense) │ (None, 16) │ 528 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_19 (Dense) │ (None, 1) │ 17 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
In [4]:
# Train models and store training history
for activation in activation_functions:
print(f"\n Training model with {activation} activation function...")
histories[activation] = models[activation].fit(
X_train, y_train,
epochs=20,
batch_size=32,
validation_split=0.2,
verbose=1
)
Epoch 1/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.4988 - loss: 0.7235 - val_accuracy:
0.5250 - val_loss: 0.6876
Epoch 2/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.4988 - loss: 0.7235 - val_accuracy:
0.5250 - val_loss: 0.6876
Epoch 2/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.5574 - loss: 0.6877 - val_accuracy:
0.4812 - val_loss: 0.6862
Epoch 3/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.5574 - loss: 0.6877 - val_accuracy:
0.4812 - val_loss: 0.6862
Epoch 3/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.5633 - loss: 0.6819 - val_accuracy:
0.7250 - val_loss: 0.6747
Epoch 4/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.5633 - loss: 0.6819 - val_accuracy:
0.7250 - val_loss: 0.6747
Epoch 4/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.7033 - loss: 0.6693 - val_accuracy:
0.7250 - val_loss: 0.6646
Epoch 5/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.7033 - loss: 0.6693 - val_accuracy:
0.7250 - val_loss: 0.6646
Epoch 5/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.7318 - loss: 0.6558 - val_accuracy:
0.7375 - val_loss: 0.6499
Epoch 6/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.7318 - loss: 0.6558 - val_accuracy:
0.7375 - val_loss: 0.6499
Epoch 6/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.7223 - loss: 0.6450 - val_accuracy:
0.7500 - val_loss: 0.6299
Epoch 7/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.7223 - loss: 0.6450 - val_accuracy:
0.7500 - val_loss: 0.6299
Epoch 7/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.7689 - loss: 0.6148 - val_accuracy:
0.7750 - val_loss: 0.6061
Epoch 8/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.7689 - loss: 0.6148 - val_accuracy:
0.7750 - val_loss: 0.6061
Epoch 8/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.7623 - loss: 0.5901 - val_accuracy:
0.7750 - val_loss: 0.5771
Epoch 9/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.7623 - loss: 0.5901 - val_accuracy:
0.7750 - val_loss: 0.5771
Epoch 9/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.7813 - loss: 0.5577 - val_accuracy:
0.7812 - val_loss: 0.5502
Epoch 10/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.7813 - loss: 0.5577 - val_accuracy:
0.7812 - val_loss: 0.5502
Epoch 10/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.7828 - loss: 0.5270 - val_accuracy:
0.8000 - val_loss: 0.5248
Epoch 11/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.7828 - loss: 0.5270 - val_accuracy:
0.8000 - val_loss: 0.5248
Epoch 11/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8023 - loss: 0.4962 - val_accuracy:
0.7875 - val_loss: 0.5050
Epoch 12/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8023 - loss: 0.4962 - val_accuracy:
0.7875 - val_loss: 0.5050
Epoch 12/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8028 - loss: 0.4631 - val_accuracy:
0.7875 - val_loss: 0.4878
Epoch 13/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8028 - loss: 0.4631 - val_accuracy:
0.7875 - val_loss: 0.4878
Epoch 13/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8262 - loss: 0.4370 - val_accuracy:
0.7812 - val_loss: 0.4766
Epoch 14/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8262 - loss: 0.4370 - val_accuracy:
0.7812 - val_loss: 0.4766
Epoch 14/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8067 - loss: 0.4419 - val_accuracy:
0.8000 - val_loss: 0.4699
Epoch 15/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8067 - loss: 0.4419 - val_accuracy:
0.8000 - val_loss: 0.4699
Epoch 15/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8243 - loss: 0.4062 - val_accuracy:
0.8000 - val_loss: 0.4655
Epoch 16/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8243 - loss: 0.4062 - val_accuracy:
0.8000 - val_loss: 0.4655
Epoch 16/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8073 - loss: 0.4138 - val_accuracy:
0.8125 - val_loss: 0.4612
Epoch 17/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8073 - loss: 0.4138 - val_accuracy:
0.8125 - val_loss: 0.4612
Epoch 17/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8081 - loss: 0.4125 - val_accuracy:
0.7937 - val_loss: 0.4600
Epoch 18/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8081 - loss: 0.4125 - val_accuracy:
0.7937 - val_loss: 0.4600
Epoch 18/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8205 - loss: 0.4058 - val_accuracy:
0.7937 - val_loss: 0.4568
Epoch 19/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8205 - loss: 0.4058 - val_accuracy:
0.7937 - val_loss: 0.4568
Epoch 19/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8194 - loss: 0.4061 - val_accuracy:
0.8062 - val_loss: 0.4568
Epoch 20/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8194 - loss: 0.4061 - val_accuracy:
0.8062 - val_loss: 0.4568
Epoch 20/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8430 - loss: 0.3769 - val_accuracy:
0.7937 - val_loss: 0.4586
Epoch 1/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.6257 - loss: 0.6447 - val_accuracy:
0.7688 - val_loss: 0.5008
Epoch 2/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.6257 - loss: 0.6447 - val_accuracy:
0.7688 - val_loss: 0.5008
Epoch 2/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8291 - loss: 0.4360 - val_accuracy:
0.8250 - val_loss: 0.4518
Epoch 3/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8291 - loss: 0.4360 - val_accuracy:
0.8250 - val_loss: 0.4518
Epoch 3/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8380 - loss: 0.3965 - val_accuracy:
0.8000 - val_loss: 0.4410
Epoch 4/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8380 - loss: 0.3965 - val_accuracy:
0.8000 - val_loss: 0.4410
Epoch 4/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8310 - loss: 0.3797 - val_accuracy:
0.8250 - val_loss: 0.4248
Epoch 5/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - accuracy: 0.8310 - loss: 0.3797 - val_accuracy:
0.8250 - val_loss: 0.4248
Epoch 5/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8583 - loss: 0.3475 - val_accuracy:
0.8188 - val_loss: 0.4254
Epoch 6/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8583 - loss: 0.3475 - val_accuracy:
0.8188 - val_loss: 0.4254
Epoch 6/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8574 - loss: 0.3325 - val_accuracy:
0.7937 - val_loss: 0.4093
Epoch 7/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8574 - loss: 0.3325 - val_accuracy:
0.7937 - val_loss: 0.4093
Epoch 7/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8482 - loss: 0.3601 - val_accuracy:
0.8188 - val_loss: 0.4125
Epoch 8/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8482 - loss: 0.3601 - val_accuracy:
0.8188 - val_loss: 0.4125
Epoch 8/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8626 - loss: 0.3058 - val_accuracy:
0.8125 - val_loss: 0.3933
Epoch 9/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8626 - loss: 0.3058 - val_accuracy:
0.8125 - val_loss: 0.3933
Epoch 9/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8841 - loss: 0.2868 - val_accuracy:
0.8062 - val_loss: 0.4002
Epoch 10/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8841 - loss: 0.2868 - val_accuracy:
0.8062 - val_loss: 0.4002
Epoch 10/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8979 - loss: 0.2611 - val_accuracy:
0.8062 - val_loss: 0.3721
Epoch 11/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.8979 - loss: 0.2611 - val_accuracy:
0.8062 - val_loss: 0.3721
Epoch 11/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9114 - loss: 0.2449 - val_accuracy:
0.8062 - val_loss: 0.3571
Epoch 12/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9114 - loss: 0.2449 - val_accuracy:
0.8062 - val_loss: 0.3571
Epoch 12/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9137 - loss: 0.2131 - val_accuracy:
0.8188 - val_loss: 0.3570
Epoch 13/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9137 - loss: 0.2131 - val_accuracy:
0.8188 - val_loss: 0.3570
Epoch 13/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9264 - loss: 0.2103 - val_accuracy:
0.8313 - val_loss: 0.3371
Epoch 14/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9264 - loss: 0.2103 - val_accuracy:
0.8313 - val_loss: 0.3371
Epoch 14/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9290 - loss: 0.2037 - val_accuracy:
0.8500 - val_loss: 0.3201
Epoch 15/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9290 - loss: 0.2037 - val_accuracy:
0.8500 - val_loss: 0.3201
Epoch 15/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9316 - loss: 0.1930 - val_accuracy:
0.8687 - val_loss: 0.3115
Epoch 16/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9316 - loss: 0.1930 - val_accuracy:
0.8687 - val_loss: 0.3115
Epoch 16/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9407 - loss: 0.1641 - val_accuracy:
0.8750 - val_loss: 0.3133
Epoch 17/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9407 - loss: 0.1641 - val_accuracy:
0.8750 - val_loss: 0.3133
Epoch 17/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9554 - loss: 0.1592 - val_accuracy:
0.8938 - val_loss: 0.2834
Epoch 18/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9554 - loss: 0.1592 - val_accuracy:
0.8938 - val_loss: 0.2834
Epoch 18/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9671 - loss: 0.1399 - val_accuracy:
0.8875 - val_loss: 0.2831
Epoch 19/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9671 - loss: 0.1399 - val_accuracy:
0.8875 - val_loss: 0.2831
Epoch 19/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9660 - loss: 0.1393 - val_accuracy:
0.9000 - val_loss: 0.2684
Epoch 20/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9660 - loss: 0.1393 - val_accuracy:
0.9000 - val_loss: 0.2684
Epoch 20/20
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9642 - loss: 0.1350 - val_accuracy:
0.9062 - val_loss: 0.2630
20/20 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - accuracy: 0.9642 - loss: 0.1350 - val_accuracy:
0.9062 - val_loss: 0.2630
In [5]:
# Evaluate models on test data
results = {}
for activation in activation_functions:
print(f"\n Evaluating model with {activation} activation function:")
loss, accuracy = models[activation].evaluate(X_test, y_test, verbose=0)
results[activation] = {
'loss': loss,
'accuracy': accuracy
}
print(f"Test Loss: {loss:.4f}")
print(f"Test Accuracy: {accuracy:.4f}")
In [6]:
# Plot training & validation accuracy for each activation function
plt.figure(figsize=(16, 10))
plt.tight_layout()
plt.show()
In [7]:
# Define activation functions for visualization
def relu(x):
return np.maximum(0, x)
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def tanh(x):
return np.tanh(x)
# Create a plot
plt.figure(figsize=(12, 8))
plt.plot(x, relu(x), label='ReLU')
plt.plot(x, sigmoid(x), label='Sigmoid')
plt.plot(x, tanh(x), label='Tanh')
plt.plot(x, leaky_relu(x), label='Leaky ReLU (alpha=0.3)')
plt.plot(x, elu(x), label='ELU (alpha=1.0)')
plt.grid(True)
plt.legend()
plt.title('Activation Functions')
plt.xlabel('Input (x)')
plt.ylabel('Output f(x)')
plt.axhline(y=0, color='k', linestyle='-', alpha=0.3)
plt.axvline(x=0, color='k', linestyle='-', alpha=0.3)
plt.show()
Experiment 2: ANN on Diabetes Dataset
In [1]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, models
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import confusion_matrix, classification_report, roc_curve, roc_auc_s
core
# Check versions
print(f"TensorFlow version: {tf.__version__}")
print(f"Keras version: {keras.__version__}")
In [2]:
# Create synthetic target with ~35% positive cases (similar to original dataset)
# Using a formula that considers multiple risk factors
risk_score = (glucose > 140) * 3 + (bmi > 30) * 2 + (age > 40) * 1.5 + (pregnancies
> 6) * 1
outcome = (risk_score + np.random.normal(0, 1, n_samples) > 3).astype(int)
# Create dataframe
data = {
"Pregnancies": pregnancies,
"Glucose": glucose,
"BloodPressure": blood_pressure,
"SkinThickness": skin_thickness,
"Insulin": insulin,
"BMI": bmi,
"DiabetesPedigreeFunction": diabetes_pedigree,
"Age": age,
"Outcome": outcome
}
df = pd.DataFrame(data)
print("Created synthetic data similar to Pima Indians Diabetes dataset.")
1 1 85 66 29 0 26.6 0.351 31 0
3 1 89 66 23 94 28.1 0.167 21 0
In [3]:
# Basic statistics of the dataset
print("Basic statistics of the dataset:")
df.describe()
count 768.000000 768.000000 768.000000 768.000000 768.000000 768.000000 768.000000 768.000000 768.
mean 3.845052 120.894531 69.105469 20.536458 79.799479 31.992578 0.471876 33.240885 0.3
std 3.369578 31.972618 19.355807 15.952218 115.244002 7.884160 0.331329 11.760232 0.4
min 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.078000 21.000000 0.0
25% 1.000000 99.000000 62.000000 0.000000 0.000000 27.300000 0.243750 24.000000 0.0
50% 3.000000 117.000000 72.000000 23.000000 30.500000 32.000000 0.372500 29.000000 0.0
75% 6.000000 140.250000 80.000000 32.000000 127.250000 36.600000 0.626250 41.000000 1.0
max 17.000000 199.000000 122.000000 99.000000 846.000000 67.100000 2.420000 81.000000 1.0
In [4]:
# Check for missing values
print("\n Missing values in each column:")
df.isnull().sum()
In [5]:
plt.show()
Class distribution:
Outcome
0 65.104167
1 34.895833
Name: proportion, dtype: float64
C:\Users\Rishi\AppData\Local\Temp\ipykernel_22384\2991995795.py:8: FutureWarning:
Passing `palette` without assigning `hue` is deprecated and will be removed in v0.14.0. A
ssign the `x` variable to `hue` and set `legend=False` for the same effect.
In [7]:
# Replace zeros with NaN for these features
for feature in features_with_zeros:
df[feature] = df[feature].replace(0, np.nan)
In [ ]:
# Fill missing values with the median of each feature
for feature in features_with_zeros:
median_value = df[feature].median()
df[feature].fillna(median_value, inplace=True)
In [9]:
# Visualize features by outcome
plt.figure(figsize=(20, 15))
for i, feature in enumerate(df.columns[:-1]):
plt.subplot(3, 3, i+1)
sns.boxplot(x='Outcome', y=feature, data=df)
plt.title(f'{feature} by Diabetes Outcome')
plt.xlabel('Diabetes (0: No, 1: Yes)')
plt.ylabel(feature)
plt.tight_layout()
plt.show()
In [10]:
# Visualize correlation between features
plt.figure(figsize=(12, 10))
correlation_matrix = df.corr()
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', fmt='.2f')
plt.title('Correlation Matrix')
plt.show()
In [11]:
# Separate features and target
X = df.drop('Outcome', axis=1)
y = df['Outcome']
In [12]:
# Create a sequential model
model = Sequential([
# Input layer
Dense(32, activation='relu', input_shape=(X_train_scaled.shape[1],)),
Dropout(0.2), # Add dropout to prevent overfitting
# Hidden layer 1
Dense(16, activation='relu'),
Dropout(0.2),
# Hidden layer 2
Dense(8, activation='relu'),
c:\Users\Rishi\AppData\Local\Programs\Python\Python312\Lib\site-packages\keras\src\layers
\core\dense.py:87: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a la
yer. When using Sequential models, prefer using an `Input(shape)` object as the first lay
er in the model instead.
super().__init__(activity_regularizer=activity_regularizer, **kwargs)
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ dense (Dense) │ (None, 32) │ 288 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout (Dropout) │ (None, 32) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_1 (Dense) │ (None, 16) │ 528 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_1 (Dropout) │ (None, 16) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_2 (Dense) │ (None, 8) │ 136 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_3 (Dense) │ (None, 1) │ 9 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
In [ ]:
# Define early stopping callback to prevent overfitting
early_stopping = tf.keras.callbacks.EarlyStopping(
monitor='val_loss',
patience=10,
mode='min',
restore_best_weights=True
)
In [14]:
# Evaluate on test set
loss, accuracy = model.evaluate(X_test_scaled, y_test)
print(f"\n Test Loss: {loss:.4f}")
print(f"Test Accuracy: {accuracy:.4f}")
plt.tight_layout()
plt.show()
In [16]:
# Make predictions on the test set
y_pred_prob = model.predict(X_test_scaled)
y_pred = (y_pred_prob > 0.5).astype(int).flatten()
In [17]:
# Calculate ROC curve and AUC
fpr, tpr, thresholds = roc_curve(y_test, y_pred_prob)
auc = roc_auc_score(y_test, y_pred_prob)
# Sort by importance
importance_df = importance_df.sort_values('Importance', ascending=False)
C:\Users\Rishi\AppData\Local\Temp\ipykernel_22384\4215535867.py:18: FutureWarning:
Passing `palette` without assigning `hue` is deprecated and will be removed in v0.14.0. A
ssign the `y` variable to `hue` and set `legend=False` for the same effect.
# Convert to DataFrame
sample_df = pd.DataFrame(sample_data)
# Make predictions
sample_predictions = model.predict(sample_scaled)
# Display results
print("Predictions on Sample Data:")
results_df[['Diabetes Probability', 'Predicted Diabetes']]
Experiment 3: MNIST - Deep Neural Network with Keras
In [1]:
# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-pytho
n
# For example, here's several helpful packages to load in
# Any results you write to the current directory are saved as output.
Using TensorFlow backend.
digit-recognizer
In [2]:
# import dataset
from keras.datasets import mnist
# load dataset
(x_train, y_train),(x_test, y_test) = mnist.load_data()
Test labels: {0: 980, 1: 1135, 2: 1032, 3: 1010, 4: 982, 5: 892, 6: 958, 7: 1028, 8: 974
, 9: 1009}
, 9: 1009}
In [3]:
# sample 25 mnist digits from train dataset
indexes = np.random.randint(0, x_train.shape[0], size=25)
images = x_train[indexes]
labels = y_train[indexes]
plt.show()
plt.savefig("mnist-samples.png")
plt.close('all')
In [4]:
from keras.models import Sequential
from keras.layers import Dense, Activation, Dropout
from keras.utils import to_categorical, plot_model
In [5]:
# compute the number of labels
num_labels = len(np.unique(y_train))
In [6]:
In [7]:
# image dimensions (assumed square)
image_size = x_train.shape[1]
input_size = image_size * image_size
input_size
Out[7]:
784
In [8]:
# resize and normalize
x_train = np.reshape(x_train, [-1, input_size])
x_train = x_train.astype('float32') / 255
x_test = np.reshape(x_test, [-1, input_size])
x_test = x_test.astype('float32') / 255
In [9]:
# network parameters
batch_size = 128
hidden_units = 256
dropout = 0.45
In [10]:
# model is a 3-layer MLP with ReLU and dropout after each layer
model = Sequential()
model.add(Dense(hidden_units, input_dim=input_size))
model.add(Activation('relu'))
model.add(Dropout(dropout))
model.add(Dense(hidden_units))
model.add(Activation('relu'))
model.add(Dropout(dropout))
model.add(Dense(num_labels))
model.add(Activation('softmax'))
In [11]:
model.summary()
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense_1 (Dense) (None, 256) 200960
_________________________________________________________________
activation_1 (Activation) (None, 256) 0
_________________________________________________________________
dropout_1 (Dropout) (None, 256) 0
_________________________________________________________________
dense_2 (Dense) (None, 256) 65792
_________________________________________________________________
activation_2 (Activation) (None, 256) 0
_________________________________________________________________
dropout_2 (Dropout) (None, 256) 0
_________________________________________________________________
dense_3 (Dense) (None, 10) 2570
_________________________________________________________________
activation_3 (Activation) (None, 10) 0
=================================================================
Total params: 269,322
Trainable params: 269,322
Non-trainable params: 0
_________________________________________________________________
In [12]:
plot_model(model, to_file='mlp-mnist.png', show_shapes=True)
Out[12]:
In [13]:
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
In [ ]:
model.fit(x_train, y_train, epochs=20, batch_size=batch_size)
In [15]:
loss, acc = model.evaluate(x_test, y_test, batch_size=batch_size)
print("\n Test accuracy: %.1f%%" % (100.0 * acc))
In [16]:
from keras.regularizers import l2
model.add(Dense(hidden_units,
kernel_regularizer=l2(0.001),
input_dim=input_size))
Experiment 4: Handwritten Digit Recognition using CNN
(Convolutional Neural Networks)
In [1]:
# image processing
import matplotlib.image as mpimg
# utility functions
from tensorflow.keras.utils import to_categorical
# sequential model
from tensorflow.keras.models import Sequential
# layers
from tensorflow.keras.layers import Conv2D, MaxPool2D, Dense, Flatten, Dropout
In [2]:
# list of files
! ls ../input/digit-recognizer
In [3]:
# import train and test dataset
train = pd.read_csv("../input/digit-recognizer/train.csv")
test = pd.read_csv("../input/digit-recognizer/test.csv")
In [4]:
# training dataset
train.head()
Out[4]:
label pixel0 pixel1 pixel2 pixel3 pixel4 pixel5 pixel6 pixel7 pixel8 ... pixel774 pixel775 pixel776 pixel777 pixel778 pixel7
0 1 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0
2 1 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0
3 4 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0
4 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0
In [5]:
# test dataset
test.head()
Out[5]:
pixel0 pixel1 pixel2 pixel3 pixel4 pixel5 pixel6 pixel7 pixel8 pixel9 ... pixel774 pixel775 pixel776 pixel777 pixel778 pixe
0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0
2 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0
3 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0
4 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0
In [6]:
# looking for missing values
print(train.isna().sum().sum())
print(test.isna().sum().sum())
0
0
In [7]:
plt.figure(figsize=(8, 5))
sns.countplot(train['label'], palette='Dark2')
plt.title('Train labels count')
plt.show()
In [8]:
train['label'].value_counts().sort_index()
Out[8]:
0 4132
1 4684
2 4177
3 4351
4 4072
5 3795
6 4137
7 4401
8 4063
9 4188
Name: label, dtype: int64
In [9]:
# first few train images with labels
fig, ax = plt.subplots(figsize=(18, 8))
for ind, row in train.iloc[:8, :].iterrows():
plt.subplot(2, 4, ind+1)
plt.title(row[0])
img = row.to_numpy()[1:].reshape(28, 28)
fig.suptitle('Train images', fontsize=24)
plt.axis('off')
plt.imshow(img, cmap='magma')
In [10]:
# first few test images
fig, ax = plt.subplots(figsize=(18, 8))
for ind, row in test.iloc[:8, :].iterrows():
plt.subplot(2, 4, ind+1)
img = row.to_numpy()[:].reshape(28, 28)
fig.suptitle('Test images', fontsize=24)
plt.axis('off')
plt.imshow(img, cmap='magma')
In [11]:
# split into image and labels and convert to numpy array
X = train.iloc[:, 1:].to_numpy()
y = train['label'].to_numpy()
# test dataset
test = test.loc[:, :].to_numpy()
(42000, 784)
(42000,)
(28000, 784)
In [12]:
# normalize the data
# ==================
X = X / 255.0
test = test / 255.0
In [13]:
# reshape dataset
# ===============
# reshape the dataframe to 3x3 matrix with 1 channel grey scale values
X = X.reshape(-1,28,28,1)
test = test.reshape(-1,28,28,1)
(42000, 784)
(28000, 784)
(42000, 28, 28, 1)
(28000, 28, 28, 1)
In [14]:
# one hot encode target
# =====================
(42000,)
1
(42000, 10)
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
In [15]:
# train test split
# ================
# random seed
random_seed = 2
# shape
for i in [X_train, y_train_enc, X_val, y_val_enc]:
print(i.shape)
In [16]:
g = plt.imshow(X_train[0][:,:,0])
print(y_train_enc[0])
[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]
In [17]:
g = plt.imshow(X_train[9][:,:,0])
print(y_train_enc[9])
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
In [18]:
INPUT_SHAPE = (28,28,1)
OUTPUT_SHAPE = 10
BATCH_SIZE = 128
EPOCHS = 10
VERBOSE = 2
In [19]:
model = Sequential()
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(10, activation='softmax'))
In [20]:
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
In [21]:
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (None, 26, 26, 32) 320
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 13, 13, 32) 0
_________________________________________________________________
conv2d_1 (Conv2D) (None, 11, 11, 64) 18496
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 5, 5, 64) 0
_________________________________________________________________
flatten (Flatten) (None, 1600) 0
_________________________________________________________________
dense (Dense) (None, 128) 204928
_________________________________________________________________
dropout (Dropout) (None, 128) 0
_________________________________________________________________
dense_1 (Dense) (None, 64) 8256
_________________________________________________________________
dropout_1 (Dropout) (None, 64) 0
_________________________________________________________________
dense_2 (Dense) (None, 10) 650
=================================================================
Total params: 232,650
Trainable params: 232,650
Non-trainable params: 0
_________________________________________________________________
In [ ]:
history = model.fit(X_train, y_train_enc,
epochs=EPOCHS,
batch_size=BATCH_SIZE,
verbose=VERBOSE,
validation_split=0.3)
In [23]:
plt.figure(figsize=(14, 5))
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'], label='Training Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.savefig('./foo.png')
plt.show()
In [24]:
# model loss and accuracy on validation set
model.evaluate(X_val, y_val_enc, verbose=False)
Out[24]:
[0.04319758138058768, 0.98825395]
In [25]:
# predicted values
y_pred_enc = model.predict(X_val)
# actual
y_act = [np.argmax(i) for i in y_val_enc]
print(y_pred_enc[0])
print(y_pred[0])
In [26]:
print(classification_report(y_act, y_pred))
In [27]:
fig, ax = plt.subplots(figsize=(7, 7))
sns.heatmap(confusion_matrix(y_act, y_pred), annot=True,
cbar=False, fmt='1d', cmap='Blues', ax=ax)
ax.set_title('Confusion Matrix', loc='left', fontsize=16)
ax.set_xlabel('Predicted')
ax.set_ylabel('Actual')
plt.show()
In [28]:
# predicted values
y_pred_enc = model.predict(test)
print(y_pred_enc[0])
print(y_pred[0])
In [29]:
# predicted targets of each images
# (labels above the images are predicted labels)
fig, ax = plt.subplots(figsize=(18, 12))
for ind, row in enumerate(test[:15]):
plt.subplot(3, 5, ind+1)
plt.title(y_pred[ind])
img = row.reshape(28, 28)
fig.suptitle('Predicted values', fontsize=24)
plt.axis('off')
plt.imshow(img, cmap='cividis')
Experiment 5: House Price Prediction using Neural
Networks
In [1]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, BatchNormalization
from tensorflow.keras.optimizers import Adam
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import warnings
# Ignore warnings
warnings.filterwarnings('ignore')
# Check versions
print(f"TensorFlow version: {tf.__version__}")
print(f"Keras version: {keras.__version__}")
In [2]:
# Generate features
data = {
# Size features
'SquareFootage': np.random.normal(2200, 800, n_samples),
'NumBedrooms': np.random.randint(1, 6, n_samples),
'NumBathrooms': np.random.choice([1, 1.5, 2, 2.5, 3, 3.5, 4], n_samples),
'LotSize': np.random.normal(10000, 5000, n_samples),
# Property characteristics
'YearBuilt': np.random.randint(1950, 2023, n_samples),
'Garage': np.random.randint(0, 4, n_samples),
'HasPool': np.random.choice([0, 1], n_samples, p=[0.8, 0.2]),
'HasBasement': np.random.choice([0, 1], n_samples, p=[0.3, 0.7]),
# Create DataFrame
df = pd.DataFrame(data)
return df
SquareFootage NumBedrooms NumBathrooms LotSize YearBuilt Garage HasPool HasBasement DistanceToCity Schoo
In [3]:
# Basic statistics of the dataset
house_df.describe()
Out[3]:
count 1500.000000 1500.000000 1500.000000 1500.000000 1500.000000 1500.000000 1500.000000 1500.000000 150
In [4]:
# Check for missing values
print("Missing values in each column:")
house_df.isnull().sum()
In [5]:
# Visualize the distribution of house prices
plt.figure(figsize=(10, 6))
sns.histplot(house_df['Price'], kde=True)
plt.title('Distribution of House Prices')
plt.xlabel('Price ($)')
plt.ylabel('Frequency')
plt.show()
In [6]:
# Explore relationships between features and house prices
plt.figure(figsize=(15, 10))
plt.tight_layout()
plt.show()
In [7]:
# Explore categorical features
plt.figure(figsize=(15, 5))
# Plot HasPool
plt.subplot(1, 3, 1)
sns.boxplot(x='HasPool', y='Price', data=house_df)
plt.title('Price by Pool Presence')
plt.xlabel('Has Pool (1=Yes, 0=No)')
plt.ylabel('Price')
# Plot HasBasement
plt.subplot(1, 3, 2)
sns.boxplot(x='HasBasement', y='Price', data=house_df)
plt.title('Price by Basement Presence')
plt.xlabel('Has Basement (1=Yes, 0=No)')
plt.ylabel('Price')
# Plot Garage
plt.subplot(1, 3, 3)
sns.boxplot(x='Garage', y='Price', data=house_df)
plt.title('Price by Garage Size')
plt.xlabel('Number of Garage Spaces')
plt.ylabel('Price')
plt.tight_layout()
plt.show()
In [8]:
# Compute and visualize correlation matrix
correlation_matrix = house_df.corr()
plt.figure(figsize=(14, 10))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', fmt='.2f', linewidths=0.5)
plt.title('Correlation Matrix of House Features')
plt.tight_layout()
plt.show()
In [9]:
# Sort correlations with Price for better insights
price_correlations = correlation_matrix['Price'].sort_values(ascending=False)
print("Features Correlation with Price:")
price_correlations
In [10]:
# Prepare features and target
X = house_df.drop(['Price', 'YearBuilt'], axis=1) # Drop price (target) and YearBuilt (
redundant with PropertyAge)
y = house_df['Price']
In [11]:
# Scale the features
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_val_scaled = scaler.transform(X_val)
X_test_scaled = scaler.transform(X_test)
# Check scaled data
print("Scaled training data - first 5 rows:")
pd.DataFrame(X_train_scaled[:5], columns=X.columns)
SquareFootage NumBedrooms NumBathrooms LotSize Garage HasPool HasBasement DistanceToCity SchoolRating Crim
-
0 -1.541859 1.346061 -1.512224 0.125611 0.472375 0.639841 -0.020848 -0.323407 0.8
0.470032
-
1 0.014937 -1.421172 -0.531170 0.239143 1.356500 -1.562889 -0.225932 -0.138350 -0.1
0.470032
-
2 -1.246153 -0.729363 0.449883 0.204953 0.472375 0.639841 1.189736 1.669335 -1.1
0.470032
-
3 1.137920 0.654253 0.449883 2.873937 0.472375 0.639841 -0.861980 1.258086 1.4
0.470032
- - -
4 0.140264 1.346061 0.940410 0.639841 1.439414 -1.238716 -0.0
0.245218 1.295875 0.470032
In [12]:
# Create a neural network for regression
def build_model(input_dim):
model = Sequential([
# Input layer
Dense(64, activation='relu', input_dim=input_dim),
BatchNormalization(),
Dropout(0.2),
# Hidden layer 1
Dense(32, activation='relu'),
BatchNormalization(),
Dropout(0.2),
# Hidden layer 2
Dense(16, activation='relu'),
BatchNormalization(),
Dropout(0.1),
return model
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ dense (Dense) │ (None, 64) │ 896 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ batch_normalization │ (None, 64) │ 256 │
│ (BatchNormalization) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout (Dropout) │ (None, 64) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_1 (Dense) │ (None, 32) │ 2,080 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ batch_normalization_1 │ (None, 32) │ 128 │
│ (BatchNormalization) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_1 (Dropout) │ (None, 32) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_2 (Dense) │ (None, 16) │ 528 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ batch_normalization_2 │ (None, 16) │ 64 │
│ (BatchNormalization) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_2 (Dropout) │ (None, 16) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_3 (Dense) │ (None, 1) │ 17 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
In [ ]:
# Define callbacks for training
callbacks = [
# Early stopping to prevent overfitting
keras.callbacks.EarlyStopping(
monitor='val_loss',
patience=20,
mode='min',
restore_best_weights=True
),
# Reduce learning rate when training plateaus
keras.callbacks.ReduceLROnPlateau(
monitor='val_loss',
factor=0.2,
patience=5,
min_lr=0.00001
)
]
In [14]:
# Plot training history
plt.figure(figsize=(12, 5))
plt.tight_layout()
plt.show()
In [15]:
# Evaluate on test set
test_loss, test_mae = model.evaluate(X_test_scaled, y_test, verbose=0)
print(f"Test Loss (MSE): {test_loss:.2f}")
print(f"Test MAE: ${test_mae:.2f}")
In [16]:
# Make predictions
y_pred = model.predict(X_test_scaled)
plt.show()
In [18]:
# Plot residuals
residuals = y_test - y_pred.flatten()
plt.figure(figsize=(12, 5))
# Residuals vs Predicted
plt.subplot(1, 2, 1)
plt.scatter(y_pred, residuals, alpha=0.5)
plt.axhline(y=0, color='r', linestyle='--')
plt.title('Residuals vs Predicted Values')
plt.xlabel('Predicted Price ($)')
plt.ylabel('Residuals')
plt.grid(True, alpha=0.3)
# Residual distribution
plt.subplot(1, 2, 2)
sns.histplot(residuals, kde=True)
plt.title('Distribution of Residuals')
plt.xlabel('Residual Value')
plt.ylabel('Frequency')
plt.tight_layout()
plt.show()
In [ ]:
# Function to measure feature importance using permutation method
def permutation_importance(model, X, y, n_repeats=10):
baseline_mae = mean_absolute_error(y, model.predict(X))
importances = []
importances.append(np.mean(col_importances))
return importances
# Sort by importance
importance_df = importance_df.sort_values('Importance', ascending=False)
In [21]:
# Create sample houses for prediction
sample_houses = pd.DataFrame([
# Small starter home
{
'SquareFootage': 1200,
'NumBedrooms': 2,
'NumBathrooms': 1,
'LotSize': 5000,
'PropertyAge': 40,
'Garage': 1,
'HasPool': 0,
'HasBasement': 0,
'DistanceToCity': 20,
'SchoolRating': 6.5,
'CrimeRate': 7.2,
'MedianNeighborhoodIncome': 45000,
'RoomsPerSqft': (2 + 1) / 1200
},
# Medium suburban home
{
'SquareFootage': 2500,
'NumBedrooms': 3,
'NumBathrooms': 2.5,
'LotSize': 8500,
'PropertyAge': 15,
'Garage': 2,
'HasPool': 0,
'HasBasement': 1,
'DistanceToCity': 12,
'SchoolRating': 8.2,
'CrimeRate': 3.1,
'MedianNeighborhoodIncome': 85000,
'RoomsPerSqft': (3 + 2.5) / 2500
},
# Luxury home
{
'SquareFootage': 4200,
'NumBedrooms': 5,
'NumBathrooms': 4.5,
'LotSize': 15000,
'PropertyAge': 5,
'Garage': 3,
'HasPool': 1,
'HasBasement': 1,
'DistanceToCity': 8,
'SchoolRating': 9.8,
'CrimeRate': 1.2,
'MedianNeighborhoodIncome': 150000,
'RoomsPerSqft': (5 + 4.5) / 4200
}
])
# Make predictions
sample_predictions = model.predict(sample_houses_scaled).flatten()
In [23]:
varied_houses.append(house_copy)
# Convert to DataFrame
varied_df = pd.DataFrame(varied_houses)
return predictions
# Use the medium suburban home as our base for what-if analysis
base_house = sample_houses.iloc[1].to_dict()
base_house.pop('House Type', None)
base_house.pop('Predicted Price', None)
Out[23]:
925.1508178710938
In [ ]:
In [25]:
In [27]:
# Create a function to predict house price based on input features
def predict_house_price(square_footage, num_bedrooms, num_bathrooms, lot_size, property_a
ge,
garage_spaces, has_pool, has_basement, distance_to_city,
school_rating, crime_rate, median_neighborhood_income):
# Make prediction
predicted_price = model.predict(house_features_scaled)[0][0]
return predicted_price
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, Conv1D, MaxPooling1D, Flatten, LSTM,
BatchNormalization
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import confusion_matrix, classification_report
import librosa
import librosa.display
import IPython.display as ipd
import os
import warnings
# Ignore warnings
warnings.filterwarnings('ignore')
# Check versions
print(f"TensorFlow version: {tf.__version__}")
print(f"Keras version: {keras.__version__}")
print(f"Librosa version: {librosa.__version__}")
In [2]:
# Try to download a small version of the Speech Commands dataset
try:
# Create a directory for our audio files
os.makedirs('speech_data', exist_ok=True)
using_synthetic_data = False
except Exception as e:
print(f"Error: {e}")
print("Failed to download Speech Commands dataset. Creating synthetic audio data inst
ead.")
using_synthetic_data = True
In [3]:
# Normalize
x = x / np.max(np.abs(x))
X.append(x)
y.append(command)
In [4]:
# Function to load and process real audio files
def load_audio_files(commands, data_dir='speech_data', max_files_per_command=200, duratio
n=1.0, sr=16000):
X = []
y = []
X.append(audio)
y.append(command)
except Exception as e:
print(f"Error loading file {file_path}: {e}")
continue
In [5]:
# Visualize some audio waveforms
plt.figure(figsize=(15, 10))
commands_to_plot = set(y) # Get unique commands
plt.subplot(len(commands_to_plot), 2, 2*idx+1)
plt.plot(audio)
plt.title(f'Waveform for "{command}"')
plt.xlabel('Sample')
plt.ylabel('Amplitude')
# Plot the spectrogram
plt.subplot(len(commands_to_plot), 2, 2*idx+2)
D = librosa.amplitude_to_db(np.abs(librosa.stft(audio)), ref=np.max)
librosa.display.specshow(D, y_axis='log', x_axis='time')
plt.title(f'Spectrogram for "{command}"')
plt.colorbar(format='%+2.0f dB')
plt.tight_layout()
plt.show()
In [6]:
# Play some audio samples (only works in interactive notebook environments)
for command in list(set(y))[:3]: # Only play first few commands
audio_idx = np.where(y == command)[0][0]
audio = X[audio_idx]
In [7]:
# Function to extract MFCCs from audio data
def extract_mfccs(audio, sr=16000, n_mfcc=13):
mfccs = librosa.feature.mfcc(y=audio, sr=sr, n_mfcc=n_mfcc)
return mfccs.T # Transpose to get time steps as first dimension
# Extract MFCCs for all samples
n_mfcc = 13 # Number of MFCC coefficients to extract
X_mfccs = []
In [8]:
# Visualize MFCC features for different commands
plt.figure(figsize=(15, 10))
commands_to_plot = set(y) # Get unique commands
plt.subplot(len(commands_to_plot), 1, idx+1)
librosa.display.specshow(mfcc.T, x_axis='time')
plt.title(f'MFCC for "{command}"')
plt.colorbar()
plt.tight_layout()
plt.show()
In [9]:
In [9]:
# Encode the labels
label_encoder = LabelEncoder()
y_encoded = label_encoder.fit_transform(y)
Label encoding:
down -> 0
left -> 1
no -> 2
right -> 3
up -> 4
yes -> 5
Training data shape: (960, 32, 13)
Testing data shape: (240, 32, 13)
y_train_cat shape: (960, 6)
y_test_cat shape: (240, 6)
In [10]:
# 1. Build a CNN model
def build_cnn_model(input_shape, num_classes):
model = Sequential([
# Convolutional layers
Conv1D(32, 3, activation='relu', padding='same', input_shape=input_shape),
BatchNormalization(),
MaxPooling1D(pool_size=2),
model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
return model
# 2. Build an LSTM model (recurrent neural network)
def build_lstm_model(input_shape, num_classes):
model = Sequential([
# LSTM layers
LSTM(64, return_sequences=True, input_shape=input_shape),
Dropout(0.2),
LSTM(64),
Dropout(0.2),
# Dense layers
Dense(32, activation='relu'),
Dropout(0.3),
Dense(num_classes, activation='softmax')
])
model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
return model
# Create models
input_shape = X_train.shape[1:]
num_classes = len(label_encoder.classes_)
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ conv1d (Conv1D) │ (None, 32, 32) │ 1,280 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ batch_normalization │ (None, 32, 32) │ 128 │
│ (BatchNormalization) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ max_pooling1d (MaxPooling1D) │ (None, 16, 32) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv1d_1 (Conv1D) │ (None, 16, 64) │ 6,208 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ batch_normalization_1 │ (None, 16, 64) │ 256 │
│ (BatchNormalization) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ max_pooling1d_1 (MaxPooling1D) │ (None, 8, 64) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv1d_2 (Conv1D) │ (None, 8, 128) │ 24,704 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ batch_normalization_2 │ (None, 8, 128) │ 512 │
│ (BatchNormalization) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ max_pooling1d_2 (MaxPooling1D) │ (None, 4, 128) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ flatten (Flatten) │ (None, 512) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense (Dense) │ (None, 128) │ 65,664 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout (Dropout) │ (None, 128) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_1 (Dense) │ (None, 6) │ 774 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
Model: "sequential_1"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ lstm (LSTM) │ (None, 32, 64) │ 19,968 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_1 (Dropout) │ (None, 32, 64) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ lstm_1 (LSTM) │ (None, 64) │ 33,024 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_2 (Dropout) │ (None, 64) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_2 (Dense) │ (None, 32) │ 2,080 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_3 (Dropout) │ (None, 32) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_3 (Dense) │ (None, 6) │ 198 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
In [ ]:
# Define callbacks for early stopping
callbacks = [
tf.keras.callbacks.EarlyStopping(
monitor='val_loss',
patience=5,
mode='min',
restore_best_weights=True
)
]
In [12]:
# Plot training histories
plt.figure(figsize=(12, 5))
# Plot accuracy
plt.subplot(1, 2, 1)
plt.plot(cnn_history.history['accuracy'], label='CNN Training')
plt.plot(cnn_history.history['val_accuracy'], label='CNN Validation')
plt.plot(lstm_history.history['accuracy'], label='LSTM Training')
plt.plot(lstm_history.history['val_accuracy'], label='LSTM Validation')
plt.title('Model Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.grid(True, alpha=0.3)
# Plot loss
plt.subplot(1, 2, 2)
plt.plot(cnn_history.history['loss'], label='CNN Training')
plt.plot(cnn_history.history['val_loss'], label='CNN Validation')
plt.plot(lstm_history.history['loss'], label='LSTM Training')
plt.plot(lstm_history.history['val_loss'], label='LSTM Validation')
plt.title('Model Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
In [13]:
# Evaluate models on the test set
print("Evaluating CNN model...")
cnn_test_loss, cnn_test_acc = cnn_model.evaluate(X_test, y_test_cat, verbose=0)
print(f"CNN Test Loss: {cnn_test_loss:.4f}")
print(f"CNN Test Accuracy: {cnn_test_acc:.4f}")
In [14]:
# Make predictions with both models
cnn_predictions = cnn_model.predict(X_test)
cnn_pred_classes = np.argmax(cnn_predictions, axis=1)
lstm_predictions = lstm_model.predict(X_test)
lstm_pred_classes = np.argmax(lstm_predictions, axis=1)
plt.tight_layout()
plt.show()
In [15]:
In [16]:
# Make prediction
prediction = model.predict(mfccs)[0]
predicted_class_idx = np.argmax(prediction)
predicted_command = label_encoder.classes_[predicted_class_idx]
confidence = prediction[predicted_class_idx]
In [17]:
# Test speech recognition on a few samples
plt.figure(figsize=(15, 10))
plt.tight_layout()
plt.show()
# Print results
print(f"Heard: '{predicted_command}' (Confidence: {confidence:.2f})")
print(f"Executing: {action_result}")
print(f"[Actual command was: '{true_command}']")
print("-" * 40)
Demo completed.
In [19]:
# Simulate Google Speech-to-Text API integration
def simulate_google_speech_api(audio, language_code="en-US"):
"""Simulate calling Google Speech-to-Text API"""
# In a real implementation, you would:
# 1. Convert the audio to the correct format
# 2. Call the Google Speech-to-Text API
# 3. Process the response
# For simulation, we'll just use our existing model but add some API-like output
predicted_command, confidence, _ = recognize_command(
audio, best_model, label_encoder
)
return response
print("-" * 40)
In [20]:
return dtw_matrix[n, m]
In [21]:
# Create template examples for each command
templates = []
template_labels = []
# Print results
print(f"Sample {i+1} (True: '{true_command}'):")
print(f" DTW Recognition: '{dtw_command}' (Confidence: {dtw_confidence:.2f})")
print(f" NN Recognition: '{nn_command} ' (Confidence: {nn_confidence:.2f})")
print("-" * 40)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, models, Sequential
from tensorflow.keras.layers import Dense, Dropout, Conv2D, MaxPooling2D, Flatten
from tensorflow.keras.layers import LSTM, TimeDistributed, Reshape, BatchNormalization
from tensorflow.keras.datasets import cifar10
from tensorflow.keras.utils import to_categorical
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns
In [2]:
# Standard approach for CIFAR-10 (works without issues due to its relatively small size)
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
# Note: For very large datasets, you would use the streaming approach like this:
# Example code (not run, just for demonstration):
"""
from datasets import load_dataset
print("\n Note: For CIFAR-10, streaming is unnecessary due to its manageable size,")
print("but for very large datasets, streaming mode helps avoid memory overflow errors.")
In [3]:
# Example of how to handle larger datasets with the datasets library
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# This function shows how you would approach training with a streaming dataset
def train_with_streaming_data(model, dataset_stream, batch_size=32, steps_per_epoch=100,
epochs=10):
"""
Train a model using a streaming dataset to avoid memory issues.
Parameters:
- model: Compiled Keras model
- dataset_stream: Streaming dataset
- batch_size: Batch size for training
- steps_per_epoch: Number of batches per epoch
- epochs: Number of epochs to train
"""
# This is a conceptual function - implementation would depend on your specific datase
t
return model
print("For CIFAR-10, we use the standard approach, but the streaming method is valuable f
or massive datasets")
For CIFAR-10, we use the standard approach, but the streaming method is valuable for mass
ive datasets
return model
/usr/local/lib/python3.11/dist-packages/keras/src/layers/convolutional/base_conv.py:107:
UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Seq
uential models, prefer using an `Input(shape)` object as the first layer in the model ins
tead.
super().__init__(activity_regularizer=activity_regularizer, **kwargs)
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ conv2d (Conv2D) │ (None, 32, 32, 32) │ 896 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ batch_normalization │ (None, 32, 32, 32) │ 128 │
│ (BatchNormalization) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv2d_1 (Conv2D) │ (None, 32, 32, 32) │ 9,248 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ batch_normalization_1 │ (None, 32, 32, 32) │ 128 │
│ (BatchNormalization) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ max_pooling2d (MaxPooling2D) │ (None, 16, 16, 32) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout (Dropout) │ (None, 16, 16, 32) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv2d_2 (Conv2D) │ (None, 16, 16, 64) │ 18,496 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ batch_normalization_2 │ (None, 16, 16, 64) │ 256 │
│ (BatchNormalization) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv2d_3 (Conv2D) │ (None, 16, 16, 64) │ 36,928 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ batch_normalization_3 │ (None, 16, 16, 64) │ 256 │
│ (BatchNormalization) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ max_pooling2d_1 (MaxPooling2D) │ (None, 8, 8, 64) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_1 (Dropout) │ (None, 8, 8, 64) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv2d_4 (Conv2D) │ (None, 8, 8, 128) │ 73,856 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ batch_normalization_4 │ (None, 8, 8, 128) │ 512 │
│ (BatchNormalization) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv2d_5 (Conv2D) │ (None, 8, 8, 128) │ 147,584 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ batch_normalization_5 │ (None, 8, 8, 128) │ 512 │
│ (BatchNormalization) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ max_pooling2d_2 (MaxPooling2D) │ (None, 4, 4, 128) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_2 (Dropout) │ (None, 4, 4, 128) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ flatten (Flatten) │ (None, 2048) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense (Dense) │ (None, 512) │ 1,049,088 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ batch_normalization_6 │ (None, 512) │ 2,048 │
│ (BatchNormalization) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_3 (Dropout) │ (None, 512) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_1 (Dense) │ (None, 10) │ 5,130 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
In [ ]:
# Train the CNN model with data augmentation
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import gc # Garbage collection to manage memory
try:
# Reduce batch size if you're having memory issues
batch_size = 32 # Reduced from 64 to try to avoid memory issues
except Exception as e:
print(f"Error during CNN model training: {e}")
print("\n Troubleshooting tips:")
print("1. Try reducing batch_size further")
print("2. Try reducing the model complexity")
print("3. Check if you have enough memory available")
# Try with a much smaller batch size and fewer epochs as a fallback
try:
print("\n Attempting training with smaller batch size...")
cnn_history = cnn_model.fit(
datagen.flow(X_train, y_train_cat, batch_size=16),
validation_data=(X_test, y_test_cat),
epochs=10, # Reduced epochs for faster completion
callbacks=[early_stopping, reduce_lr],
verbose=1
)
print("Fallback training completed successfully!")
except Exception as e2:
print(f"Fallback training also failed: {e2}")
In [7]:
# Prepare data for RNN (reshape images to sequences)
# For RNN, we'll treat each row of the image as a time step
X_train_rnn = X_train.reshape(X_train.shape[0], 32, 32*3) # 32 time steps, each with 32
*3 features
X_test_rnn = X_test.reshape(X_test.shape[0], 32, 32*3)
In [8]:
# Define RNN model architecture
def create_rnn_model():
model = Sequential([
# LSTM layers
LSTM(128, return_sequences=True, input_shape=(32, 32*3)),
Dropout(0.25),
LSTM(128),
Dropout(0.25),
# Output layer
Dense(128, activation='relu'),
Dropout(0.5),
Dense(10, activation='softmax')
])
return model
/usr/local/lib/python3.11/dist-packages/keras/src/layers/rnn/rnn.py:200: UserWarning: Do
not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models,
prefer using an `Input(shape)` object as the first layer in the model instead.
super().__init__(**kwargs)
Model: "sequential_1"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ lstm (LSTM) │ (None, 32, 128) │ 115,200 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_4 (Dropout) │ (None, 32, 128) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ lstm_1 (LSTM) │ (None, 128) │ 131,584 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_5 (Dropout) │ (None, 128) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_2 (Dense) │ (None, 128) │ 16,512 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_6 (Dropout) │ (None, 128) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_3 (Dense) │ (None, 10) │ 1,290 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
In [ ]:
# Train the RNN model
early_stopping = keras.callbacks.EarlyStopping(monitor='val_loss', patience=5, restore_be
st_weights=True)
rnn_history = rnn_model.fit(
X_train_rnn, y_train_cat,
batch_size=128,
epochs=25,
validation_data=(X_test_rnn, y_test_cat),
callbacks=[early_stopping],
verbose=1
)
In [10]:
# Evaluate the CNN model
cnn_loss, cnn_accuracy = cnn_model.evaluate(X_test, y_test_cat, verbose=0)
print(f"CNN Test Accuracy: {cnn_accuracy:.4f}")
In [11]:
# Plot training history comparison
plt.figure(figsize=(12, 5))
# Plot accuracy
plt.subplot(1, 2, 1)
plt.plot(cnn_history.history['accuracy'], label='CNN Training Accuracy')
plt.plot(cnn_history.history['val_accuracy'], label='CNN Validation Accuracy')
plt.plot(rnn_history.history['accuracy'], label='RNN Training Accuracy')
plt.plot(rnn_history.history['val_accuracy'], label='RNN Validation Accuracy')
plt.title('Model Accuracy Comparison')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(loc='lower right')
# Plot loss
plt.subplot(1, 2, 2)
plt.plot(cnn_history.history['loss'], label='CNN Training Loss')
plt.plot(cnn_history.history['val_loss'], label='CNN Validation Loss')
plt.plot(rnn_history.history['loss'], label='RNN Training Loss')
plt.plot(rnn_history.history['val_loss'], label='RNN Validation Loss')
plt.title('Model Loss Comparison')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(loc='upper right')
plt.tight_layout()
plt.show()
In [12]:
In [13]:
# Plot confusion matrices
plt.figure(figsize=(16, 7))
plt.tight_layout()
plt.show()
In [14]:
# Display some sample predictions
def plot_sample_predictions(model_name, X, predictions, true_labels, indices=None):
if indices is None:
indices = np.random.randint(0, len(X), 15)
plt.figure(figsize=(12, 10))
for i, idx in enumerate(indices):
plt.subplot(3, 5, i+1)
plt.imshow(X[idx])
plt.title(f"True: {class_names[true_labels[idx][0]]}\n Pred: {class_names[predict
ed_classes[idx]]}")
plt.axis('off')
if true_labels[idx][0] != predicted_classes[idx]:
plt.gca().set_title(plt.gca().get_title(), color='red')
plt.tight_layout()
plt.suptitle(f"{model_name} Sample Predictions", fontsize=16, y=1.02)
plt.show()
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import re
import string
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
from nltk.stem import WordNetLemmatizer, PorterStemmer
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Embedding, LSTM, SpatialDropout1D, Dropout, B
idirectional
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.decomposition import PCA, TruncatedSVD
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
from sklearn.datasets import fetch_20newsgroups
import warnings
# Suppress warnings
warnings.filterwarnings('ignore')
# Check versions
print(f"TensorFlow version: {tf.__version__}")
print(f"Keras version: {keras.__version__}")
print(f"NLTK version: {nltk.__version__}")
print(f"Pandas version: {pd.__version__}")
In [2]:
def generate_synthetic_sentiment_data(n_samples=5000):
"""Generate synthetic text data with sentiment labels"""
negative_words = [
"bad", "terrible", "awful", "horrible", "worst", "hate", "disappointed", "poor",
"disappointing", "dislike", "mediocre", "ugly", "boring", "stupid", "waste",
"annoying", "useless", "unpleasant", "frustrating", "pathetic", "dreadful", "app
alling",
"disgusting", "disaster", "inferior", "dull", "unhappy", "awful"
]
neutral_words = [
"okay", "fine", "average", "decent", "acceptable", "fair", "satisfactory", "mode
rate",
"adequate", "reasonable", "neither", "mixed", "balanced", "so-so", "standard",
"ordinary", "regular", "typical", "usual", "common", "intermediate", "middle-of-
the-road"
]
negative_templates = [
"This product is {negative}.",
"I {negative} this movie.",
"The service was {negative} and I would not recommend it.",
"A {negative} experience overall.",
"This is a {negative} {item} that failed to meet my expectations.",
"I'm {negative} with my purchase.",
"The {item} works {negative} and is not worth the money.",
"I was {negative} by how poorly this {item} performed.",
"My experience with this {item} has been {negative}.",
"This {negative} {item} made me unhappy."
]
neutral_templates = [
"This product is {neutral}.",
"I thought this movie was {neutral}.",
"The service was {neutral}.",
"A {neutral} experience overall.",
"This is a {neutral} {item} that met my basic expectations.",
"I'm {neutral} about my purchase.",
"The {item} works {neutral} for the price.",
"I was neither impressed nor disappointed by this {item}.",
"My experience with this {item} has been {neutral}.",
"This {neutral} {item} is just okay."
]
# Generate samples
texts = []
sentiments = []
for _ in range(n_samples):
sentiment = np.random.choice([0, 1, 2]) # 0: negative, 1: neutral, 2: positive
item = np.random.choice(item_types)
if sentiment == 0: # Negative
template = np.random.choice(negative_templates)
sentiment_word = np.random.choice(negative_words)
text = template.format(negative=sentiment_word, item=item)
elif sentiment == 1: # Neutral
template = np.random.choice(neutral_templates)
sentiment_word = np.random.choice(neutral_words)
text = template.format(neutral=sentiment_word, item=item)
else: # Positive
template = np.random.choice(positive_templates)
sentiment_word = np.random.choice(positive_words)
text = template.format(positive=sentiment_word, item=item)
texts.append(text)
sentiments.append(sentiment)
# Create DataFrame
data = pd.DataFrame({
'text': texts,
'sentiment': sentiments
})
return data
In [3]:
# Calculate percentages
sentiment_counts = sentiment_data['sentiment_label'].value_counts(normalize=True) * 100
print("Sentiment distribution percentages:")
for sentiment, percentage in sentiment_counts.items():
print(f"{sentiment}: {percentage:.2f}%")
Sentiment distribution percentages:
neutral: 33.92%
positive: 33.52%
negative: 32.56%
In [4]:
# Download NLTK resources first
nltk.download('punkt')
nltk.download('stopwords')
nltk.download('wordnet')
# Count frequency
word_freq = pd.Series(all_words).value_counts().head(top_n)
# Plot
plt.subplot(3, 1, i+1)
sns.barplot(x=word_freq.values, y=word_freq.index, palette='viridis')
plt.title(f'Top {top_n} Words in {sentiment.capitalize()} Reviews')
plt.xlabel('Frequency')
plt.ylabel('Words')
plt.tight_layout()
plt.show()
# Visualize word frequencies
plot_word_freq_by_sentiment(sentiment_data)
In [5]:
def preprocess_text(text, remove_stopwords=True, lemmatize=True):
"""Preprocess text for NLP tasks"""
# Convert to lowercase
text = text.lower()
# Remove URLs
text = re.sub(r'http\S+|www\S+|https\S+', '', text, flags=re.MULTILINE)
# Tokenize
tokens = word_tokenize(text)
return preprocessed_text
Sentiment: negative
Original: This is a waste product that failed to meet my expectations.
Processed: waste product failed meet expectation
Sentiment: negative
Original: A disaster experience overall.
Processed: disaster experience overall
Sentiment: positive
Original: I'm superb with my purchase.
Processed: im superb purchase
Sentiment: neutral
Original: My experience with this service has been usual.
Processed: experience service usual
Sentiment: negative
Original: My experience with this headphones has been unhappy.
Processed: experience headphone unhappy
In [6]:
# Split the data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(
sentiment_data['processed_text'],
sentiment_data['sentiment'],
test_size=0.2,
random_state=42
)
# TF-IDF
tfidf_vectorizer = TfidfVectorizer(max_features=5000)
tfidf_train = tfidf_vectorizer.fit_transform(X_train)
tfidf_test = tfidf_vectorizer.transform(X_test)
In [7]:
def train_evaluate_ml_model(model, X_train, X_test, y_train, y_test, model_name):
"""Train and evaluate a machine learning model"""
# Train the model
model.fit(X_train, y_train)
# Make predictions
y_pred = model.predict(X_test)
# Calculate metrics
accuracy = accuracy_score(y_test, y_pred)
report = classification_report(y_test, y_pred, target_names=['Negative', 'Neutral',
'Positive'])
# Print results
print(f"Model: {model_name} ")
print(f"Accuracy: {accuracy:.4f}")
print("Classification Report:")
print(report)
# Confusion Matrix
cm = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',
xticklabels=['Negative', 'Neutral', 'Positive'],
yticklabels=['Negative', 'Neutral', 'Positive'])
plt.xlabel('Predicted')
plt.ylabel('True')
plt.title(f'Confusion Matrix - {model_name} ')
plt.tight_layout()
plt.show()
plt.figure(figsize=(15, 12))
for i, class_name in enumerate(class_labels):
# Top positive coefficients for this class
top_positive = np.argsort(coefficients[i])[-10:]
top_pos_coeffs = coefficients[i][top_positive]
top_pos_features = [feature_names[j] for j in top_positive]
# Plot
plt.subplot(3, 1, i+1)
# Plot positive
plt.barh(range(len(top_pos_features)), top_pos_coeffs, color='forestgreen')
plt.yticks(range(len(top_pos_features)), top_pos_features)
plt.tight_layout()
plt.show()
else:
print("This model type doesn't support feature importance visualization.")
# Tokenize text
tokenizer = Tokenizer(num_words=max_features)
tokenizer.fit_on_texts(X_train)
X_train_seq = tokenizer.texts_to_sequences(X_train)
X_test_seq = tokenizer.texts_to_sequences(X_test)
In [10]:
# Build LSTM model for sentiment analysis
def create_lstm_model():
model = Sequential()
model.add(Embedding(max_features, 128, input_length=maxlen))
model.add(SpatialDropout1D(0.2))
model.add(Bidirectional(LSTM(64, dropout=0.2, recurrent_dropout=0.2)))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(3, activation='softmax')) # 3 classes: negative, neutral, positive
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['accuracy'])
return model
# Callbacks
early_stopping = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3, restor
e_best_weights=True)
reduce_lr = tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.2, patienc
e=2, min_lr=0.001)
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩
│ embedding (Embedding) │ ? │ 0 (unbuilt) │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ spatial_dropout1d (SpatialDropout1D) │ ? │ 0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ bidirectional (Bidirectional) │ ? │ 0 (unbuilt) │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense (Dense) │ ? │ 0 (unbuilt) │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dropout (Dropout) │ ? │ 0 │
├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤
│ dense_1 (Dense) │ ? │ 0 (unbuilt) │
└──────────────────────────────────────┴─────────────────────────────┴─────────────────┘
Epoch 1/15
29/29 ━━━━━━━━━━━━━━━━━━━━ 26s 434ms/step - accuracy: 0.3771 - loss: 1.0906 - val_accurac
y: 0.9425 - val_loss: 0.9523 - learning_rate: 0.0010
Epoch 2/15
29/29 ━━━━━━━━━━━━━━━━━━━━ 11s 391ms/step - accuracy: 0.7555 - loss: 0.8183 - val_accurac
y: 1.0000 - val_loss: 0.2278 - learning_rate: 0.0010
Epoch 3/15
29/29 ━━━━━━━━━━━━━━━━━━━━ 11s 388ms/step - accuracy: 0.9556 - loss: 0.1988 - val_accurac
y: 1.0000 - val_loss: 0.0035 - learning_rate: 0.0010
Epoch 4/15
29/29 ━━━━━━━━━━━━━━━━━━━━ 11s 394ms/step - accuracy: 0.9973 - loss: 0.0202 - val_accurac
y: 1.0000 - val_loss: 3.5055e-04 - learning_rate: 0.0010
Epoch 5/15
29/29 ━━━━━━━━━━━━━━━━━━━━ 11s 385ms/step - accuracy: 0.9988 - loss: 0.0079 - val_accurac
y: 1.0000 - val_loss: 1.2586e-04 - learning_rate: 0.0010
Epoch 6/15
29/29 ━━━━━━━━━━━━━━━━━━━━ 11s 387ms/step - accuracy: 1.0000 - loss: 0.0040 - val_accurac
y: 1.0000 - val_loss: 8.2057e-05 - learning_rate: 0.0010
Epoch 7/15
29/29 ━━━━━━━━━━━━━━━━━━━━ 11s 387ms/step - accuracy: 1.0000 - loss: 0.0040 - val_accurac
y: 1.0000 - val_loss: 3.6909e-05 - learning_rate: 0.0010
Epoch 8/15
29/29 ━━━━━━━━━━━━━━━━━━━━ 11s 378ms/step - accuracy: 0.9990 - loss: 0.0029 - val_accurac
y: 1.0000 - val_loss: 2.3085e-05 - learning_rate: 0.0010
Epoch 9/15
29/29 ━━━━━━━━━━━━━━━━━━━━ 11s 389ms/step - accuracy: 1.0000 - loss: 0.0019 - val_accurac
y: 1.0000 - val_loss: 2.9360e-05 - learning_rate: 0.0010
Epoch 10/15
29/29 ━━━━━━━━━━━━━━━━━━━━ 11s 380ms/step - accuracy: 1.0000 - loss: 9.8354e-04 - val_acc
uracy: 1.0000 - val_loss: 1.0132e-05 - learning_rate: 0.0010
Epoch 11/15
29/29 ━━━━━━━━━━━━━━━━━━━━ 11s 378ms/step - accuracy: 1.0000 - loss: 9.8051e-04 - val_acc
uracy: 1.0000 - val_loss: 1.5896e-05 - learning_rate: 0.0010
Epoch 12/15
29/29 ━━━━━━━━━━━━━━━━━━━━ 11s 388ms/step - accuracy: 1.0000 - loss: 9.5763e-04 - val_acc
29/29 ━━━━━━━━━━━━━━━━━━━━ 11s 388ms/step - accuracy: 1.0000 - loss: 9.5763e-04 - val_acc
uracy: 1.0000 - val_loss: 7.4489e-06 - learning_rate: 0.0010
Epoch 13/15
29/29 ━━━━━━━━━━━━━━━━━━━━ 11s 377ms/step - accuracy: 1.0000 - loss: 0.0011 - val_accurac
y: 1.0000 - val_loss: 8.0250e-06 - learning_rate: 0.0010
Epoch 14/15
29/29 ━━━━━━━━━━━━━━━━━━━━ 11s 385ms/step - accuracy: 0.9997 - loss: 0.0011 - val_accurac
y: 1.0000 - val_loss: 9.1459e-06 - learning_rate: 0.0010
Epoch 15/15
29/29 ━━━━━━━━━━━━━━━━━━━━ 11s 392ms/step - accuracy: 1.0000 - loss: 8.8211e-04 - val_acc
uracy: 1.0000 - val_loss: 4.0683e-06 - learning_rate: 0.0010
In [11]:
# Plot training history
plt.figure(figsize=(12, 5))
# Plot accuracy
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()
plt.grid(True, linestyle='--', alpha=0.6)
# Plot loss
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.grid(True, linestyle='--', alpha=0.6)
plt.tight_layout()
plt.show()
In [12]:
# Evaluate LSTM model
lstm_pred = lstm_model.predict(X_test_pad)
y_pred_classes = np.argmax(lstm_pred, axis=1)
y_test_classes = np.argmax(y_test_cat, axis=1)
In [13]:
# Plot comparison
plt.figure(figsize=(10, 6))
bars = plt.bar(models.keys(), models.values(), color=['skyblue', 'lightgreen', 'coral'])
plt.title('Model Accuracy Comparison')
plt.xlabel('Model')
plt.ylabel('Accuracy')
plt.ylim(0, 1.0)
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.tight_layout()
plt.show()
In [14]:
In [15]:
# Preprocess the newsgroups data
# Apply more aggressive preprocessing for this dataset
def preprocess_newsgroups(text):
# Convert to lowercase
text = text.lower()
return text
# Display a sample
print("Original text sample:")
print(newsgroups_train.data[0][:500] + "...")
print("\n Processed text sample:")
print(train_data_processed[0][:500] + "...")
In [16]:
# Extract features using TF-IDF
tfidf_vectorizer = TfidfVectorizer(max_features=5000, stop_words='english')
X_train_tfidf = tfidf_vectorizer.fit_transform(train_data_processed)
X_test_tfidf = tfidf_vectorizer.transform(test_data_processed)
# Target labels
y_train = newsgroups_train.target
y_test = newsgroups_test.target
In [17]:
# Train a classifier
classifier = LogisticRegression(max_iter=1000, C=10.0, solver='liblinear', multi_class='
ovr')
classifier.fit(X_train_tfidf, y_train)
# Make predictions
y_pred = classifier.predict(X_test_tfidf)
# Evaluate
accuracy = accuracy_score(y_test, y_pred)
report = classification_report(y_test, y_pred, target_names=categories)
In [18]:
In [19]:
# Vectorize
text_tfidf = vectorizer.transform([processed_text])
# Create results
result = {
'predicted_class': label_names[prediction],
'prediction_index': prediction,
'probabilities': []
}
return result
# Example texts to classify
test_examples = [
"I think we need stricter regulations on firearms to prevent violence.",
"The semiconductor industry is evolving with new transistor technologies.",
"Last night's hockey game was amazing with multiple goals in overtime.",
"Religious beliefs should not influence public policy decisions."
]
Example 3: Last night's hockey game was amazing with multiple goals in overtime.
Predicted class: sci.electronics
Probabilities:
sci.electronics: 0.9507
alt.atheism: 0.0189
talk.politics.guns: 0.0163
rec.sport.hockey: 0.0141
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import yfinance as yf # For fetching stock data
from datetime import datetime, timedelta
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, LSTM, Dropout, GRU, Bidirectional
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import math
import warnings
# Suppress warnings
warnings.filterwarnings('ignore')
# Check versions
print(f"TensorFlow version: {tf.__version__}")
print(f"Keras version: {keras.__version__}")
print(f"Pandas version: {pd.__version__}")
print(f"NumPy version: {np.__version__}")
In [4]:
# Define the stock tickers and time period
tickers = ['AAPL', 'MSFT', 'GOOGL', 'AMZN']
start_date = '2018-01-01'
end_date = datetime.now().strftime('%Y-%m-%d ')
# Combine components
prices = base_price + trend + seasonality + np.cumsum(noise)
# Create DataFrame
df = pd.DataFrame({
'Date': date_range,
'Open': prices * np.random.uniform(0.99, 1.01, n_days),
'High': prices * np.random.uniform(1.01, 1.03, n_days),
'Low': prices * np.random.uniform(0.97, 0.99, n_days),
'Close': prices,
'Adj Close': prices,
'Volume': volume
})
[*********************100%***********************] 1 of 1 completed
[*********************100%***********************] 1 of 1 completed
[*********************100%***********************] 1 of 1 completed
[*********************100%***********************] 1 of 1 completed
Out[4]:
In [5]:
# Check basic statistics
print(f"\n Statistics for {selected_stock}:")
print(df.describe())
plt.figure(figsize=(16, 8))
plt.plot(df['Date'], df['Close'], label='Close Price')
plt.plot(df['Date'], df['MA50'], label='50-day MA', color='orange')
plt.plot(df['Date'], df['MA200'], label='200-day MA', color='red')
plt.title(f'{selected_stock} Stock Price with Moving Averages')
plt.xlabel('Date', fontsize=14)
plt.ylabel('Price (USD)', fontsize=14)
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
In [7]:
# Compare all stocks on the same chart
plt.figure(figsize=(16, 8))
In [9]:
# Simple LSTM model
def create_simple_lstm_model(sequence_length):
model = Sequential([
LSTM(50, return_sequences=True, input_shape=(sequence_length, 1)),
Dropout(0.2),
LSTM(50, return_sequences=False),
Dropout(0.2),
Dense(25),
Dense(1)
])
model.compile(optimizer='adam', loss='mean_squared_error')
return model
# Create models
simple_lstm_model = create_simple_lstm_model(sequence_length)
stacked_lstm_model = create_stacked_lstm_model(sequence_length)
bidirectional_lstm_model = create_bidirectional_lstm_model(sequence_length)
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ lstm (LSTM) │ (None, 60, 50) │ 10,400 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout (Dropout) │ (None, 60, 50) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ lstm_1 (LSTM) │ (None, 50) │ 20,200 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_1 (Dropout) │ (None, 50) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense (Dense) │ (None, 25) │ 1,275 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_1 (Dense) │ (None, 1) │ 26 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
In [ ]:
# Define callbacks for training
callbacks = [
EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True),
ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=5, min_lr=1e-5)
]
In [11]:
# Plot training history for all models
plt.figure(figsize=(14, 7))
In [13]:
# Plot the predictions vs actual
def plot_predictions(predictions, actual, model_name, dates=None):
plt.figure(figsize=(16, 8))
Out[16]:
In [17]:
plt.tight_layout()
plt.show()
# Plot R² scores
plt.figure(figsize=(10, 6))
r2_values = metrics.loc['R² Score']
bars = plt.bar(r2_values.index, r2_values.values, color=['red', 'green', 'orange'])
plt.title('Model Comparison: R² Score')
plt.ylabel('R² Score')
plt.ylim(0, 1)
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
In [ ]:
# Function to predict future stock prices
def predict_future_prices(model, last_sequence, days_to_predict, scaler):
"""Predict future stock prices given the last sequence of data"""
future_predictions = []
current_sequence = last_sequence.copy()
for _ in range(days_to_predict):
# Reshape for prediction
current_reshaped = current_sequence.reshape(1, current_sequence.shape[0], 1)
return future_predictions
In [ ]:
In [ ]:
# Moving Averages
df_temp['MA5'] = df_temp['Close'].rolling(window=5).mean()
df_temp['MA10'] = df_temp['Close'].rolling(window=10).mean()
df_temp['MA20'] = df_temp['Close'].rolling(window=20).mean()
df_temp['MA50'] = df_temp['Close'].rolling(window=50).mean()
# Bollinger Bands
df_temp['MA20_std'] = df_temp['Close'].rolling(window=20).std()
df_temp['Upper_Band'] = df_temp['MA20'] + (df_temp['MA20_std'] * 2)
df_temp['Lower_Band'] = df_temp['MA20'] - (df_temp['MA20_std'] * 2)
return df_temp
In [23]:
# Plot RSI
if 'RSI' in indicators:
df['RSI'].plot(ax=axes[1], color='purple', label='RSI')
# Add overbought/oversold levels
axes[1].axhline(y=70, color='red', linestyle='--', alpha=0.5)
axes[1].axhline(y=30, color='green', linestyle='--', alpha=0.5)
axes[1].text(df.index[0], 70, 'Overbought', color='red')
axes[1].text(df.index[0], 30, 'Oversold', color='green')
# Plot MACD
if 'MACD' in indicators:
df['MACD'].plot(ax=axes[2], color='blue', label='MACD')
df['MACD_Signal'].plot(ax=axes[2], color='red', label='Signal Line')
plt.tight_layout()
plt.show()
return price_paths
# Get the last known price
last_price = y_test_inv[-1]
# Run simulation
simulated_paths = monte_carlo_simulation(last_price, days_to_simulate, num_simulations,
volatility)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import re
import string
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
from nltk.stem import WordNetLemmatizer
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.models import Sequential, Model
from tensorflow.keras.layers import Dense, LSTM, Embedding, SpatialDropout1D, Dropout, B
idirectional
from tensorflow.keras.layers import Input, GlobalMaxPooling1D, Conv1D, MaxPooling1D, conc
atenate
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau
from tensorflow.keras.utils import to_categorical
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
from sklearn.preprocessing import LabelEncoder
import matplotlib.cm as cm
from wordcloud import WordCloud
import warnings
# Suppress warnings
warnings.filterwarnings('ignore')
# Check versions
print(f"TensorFlow version: {tf.__version__}")
print(f"Keras version: {keras.__version__}")
print(f"NLTK version: {nltk.__version__}")
In [2]:
def generate_synthetic_twitter_data(n_samples=5000):
"""Generate synthetic Twitter data with emotion labels"""
# Define emotions and their associated words/phrases
emotions = {
'joy': [
"happy", "excited", "blessed", "wonderful", "fantastic", "thrilled", "love",
"joyful", "delighted", "ecstatic", "pleased", "overjoyed", "grateful", "blis
sful",
"elated", "cheerful", "content", "jubilant", "peaceful", "radiant", "sunny"
],
'sadness': [
"sad", "depressed", "heartbroken", "miserable", "grief", "sorrowful", "unhap
py",
"disappointed", "despondent", "hopeless", "melancholy", "gloomy", "blue", "d
own",
"hurt", "lost", "devastated", "tearful", "regretful", "broken", "crying"
],
'anger': [
"angry", "furious", "outraged", "annoyed", "irritated", "fuming", "enraged",
"mad", "resentful", "bitter", "incensed", "livid", "hostile", "irate",
"seething", "hate", "frustrated", "disgusted", "infuriated", "upset", "offen
ded"
],
'fear': [
"afraid", "scared", "terrified", "frightened", "anxious", "worried", "nervou
s",
"panicked", "horrified", "fearful", "dread", "uneasy", "alarmed", "threatene
d",
"intimidated", "apprehensive", "paranoid", "tense", "stressed", "petrified",
"timid"
],
'surprise': [
"surprised", "shocked", "astonished", "amazed", "stunned", "unexpected", "wo
w",
"speechless", "startled", "dumbfounded", "flabbergasted", "bewildered", "ast
ounded",
"mind-blown", "awestruck", "taken aback", "could not believe", "unbelievable
", "whoa", "omg"
]
}
# Generate tweets
tweets = []
labels = []
emotion_distribution = {
'joy': int(n_samples * 0.25),
'sadness': int(n_samples * 0.20),
'anger': int(n_samples * 0.20),
'fear': int(n_samples * 0.15),
'surprise': int(n_samples * 0.20)
}
# Create tweet
tweet = template.format(emotion_word, context)
tweets.append(tweet)
labels.append(emotion)
# Create DataFrame
data = pd.DataFrame({
'tweet': tweets,
'emotion': labels
})
return data
tweet emotion
0 Today has been so lost. the canceled plans has... sadness
tweet emotion
1 Nothing makes me more irritated than poor cust... anger
Categorical distributions
Error: Runtime no longer has a reference to this dataframe, please re-run this cell and t
ry again.
In [3]:
plt.grid(axis='y', alpha=0.3)
plt.tight_layout()
plt.show()
# Calculate percentages
emotion_counts = tweet_data['emotion'].value_counts(normalize=True) * 100
print("Emotion distribution percentages:")
for emotion, percentage in emotion_counts.items():
print(f"{emotion}: {percentage:.2f}%")
In [4]:
# Analyze tweet length by emotion
tweet_data['tweet_length'] = tweet_data['tweet'].apply(len)
plt.figure(figsize=(12, 6))
sns.boxplot(x='emotion', y='tweet_length', data=tweet_data, palette='viridis')
plt.title('Tweet Length by Emotion', fontsize=16)
plt.xlabel('Emotion', fontsize=14)
plt.ylabel('Tweet Length (characters)', fontsize=14)
plt.grid(axis='y', alpha=0.3)
plt.tight_layout()
plt.show()
In [5]:
# Generate word clouds for each emotion
def plot_wordcloud(text, title, max_words=100):
wordcloud = WordCloud(
background_color='white',
max_words=max_words,
max_font_size=40,
scale=3,
random_state=42
).generate(text)
plt.figure(figsize=(10, 6))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.title(title, fontsize=16)
plt.tight_layout(pad=0)
plt.show()
# Remove URLs
tweet = re.sub(r'http\S+|www\S+|https\S+', '', tweet, flags=re.MULTILINE)
# Remove user mentions and hashtag symbol (keep the hashtag text)
tweet = re.sub(r'@\w+', '', tweet)
tweet = re.sub(r'#', '', tweet)
# Remove punctuation
tweet = re.sub(r'[^\w\s]', '', tweet)
# Lemmatize
try:
lemmatizer = WordNetLemmatizer()
tokens = [lemmatizer.lemmatize(word) for word in tokens]
except:
# If lemmatization fails, use the original tokens
pass
return preprocessed_tweet
Emotion: sadness
Original: Today has been so lost. the canceled plans has me in tears.
Processed: today lost canceled plan tear
Emotion: anger
Original: Nothing makes me more irritated than poor customer service. Seriously?!
Processed: nothing make irritated poor customer service seriously
Emotion: anger
Original: Why am I so outraged about people not wearing masks? Because it's totally wrong
!
Processed: outraged people wearing mask totally wrong
Emotion: joy
Original: I'm feeling so excited today! Life is good! #blessed
Processed: im feeling excited today life good blessed
Emotion: joy
Original: I'm elated to announce that our vacation! Dreams do come true. #grateful
Processed: im elated announce vacation dream come true grateful
In [7]:
# Encode emotion labels
label_encoder = LabelEncoder()
encoded_labels = label_encoder.fit_transform(tweet_data['emotion'])
num_classes = len(label_encoder.classes_)
# Tokenize text
max_words = 10000 # Maximum number of words to consider
max_len = 100 # Maximum sequence length
In [8]:
model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
return model
model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
return model
model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
return model
model.compile(
optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy']
)
return model
In [ ]:
# Initialize empty dictionaries to store models and histories
models = {}
histories = {}
history = model.fit(
X_train_pad, y_train,
epochs=15,
batch_size=64,
validation_split=0.1,
callbacks=callbacks,
verbose=1
)
In [10]:
# Plot accuracy
plt.subplot(1, 2, 1)
for model_name, history in histories.items():
plt.plot(history.history['accuracy'], label=f'{model_name} Training')
plt.plot(history.history['val_accuracy'], label=f'{model_name} Validation', linestyl
e='--')
# Plot loss
plt.subplot(1, 2, 2)
for model_name, history in histories.items():
plt.plot(history.history['loss'], label=f'{model_name} Training')
plt.plot(history.history['val_loss'], label=f'{model_name} Validation', linestyle='-
-')
plt.tight_layout()
plt.show()
In [11]:
# Function to evaluate model and produce classification report and confusion matrix
def evaluate_model_detail(model, model_name, X_test, y_test, label_mapping):
# Get predictions
y_pred_prob = model.predict(X_test)
y_pred = np.argmax(y_pred_prob, axis=1)
y_true = np.argmax(y_test, axis=1)
In [13]:
# Analyze misclassifications to understand model weaknesses
def analyze_misclassifications(X_test_raw, y_true, y_pred, label_mapping, n_examples=10)
:
# Get original texts from test set
misclassified_indices = np.where(y_true != y_pred)[0]
if len(misclassified_indices) == 0:
print("No misclassifications found!")
return
# Limit to n examples
n_examples = min(n_examples, len(misclassified_indices))
selected_indices = np.random.choice(misclassified_indices, n_examples, replace=False
)
print(f"Tweet: {text}")
print(f"True emotion: {true_label} ")
print(f"Predicted emotion: {pred_label} ")
print("-" * 80)
# Calculate confusion pairs (which emotions get confused with each other)
confusion_pairs = {}
for idx in misclassified_indices:
true_label = label_mapping[y_true[idx]]
pred_label = label_mapping[y_pred[idx]]
pair = (true_label, pred_label)
if pair in confusion_pairs:
confusion_pairs[pair] += 1
else:
confusion_pairs[pair] = 1
# Analyze misclassifications
analyze_misclassifications(X_test_raw, y_true, y_pred, label_mapping, n_examples=5)
No misclassifications found!
In [14]:
# Create a function to predict emotions from new tweets
def predict_emotion(tweet, model, tokenizer, label_mapping, max_len=100):
"""Predict the emotion of a single tweet"""
# Preprocess the tweet
processed_tweet = preprocess_tweet(tweet)
# Convert to sequence
sequence = tokenizer.texts_to_sequences([processed_tweet])
# Pad sequence
padded_sequence = pad_sequences(sequence, maxlen=max_len, padding='post', truncating
='post')
# Make prediction
prediction = model.predict(padded_sequence)[0]
return {
'emotion': emotion,
'probability': float(probability),
'all_probabilities': all_probs
}
Example 1: I'm so happy today! Just got a promotion at work and feeling blessed! #grat
eful
Predicted Emotion: joy (Confidence: 100.00%)
All Emotion Probabilities:
- joy: 100.00%
- fear: 0.00%
- surprise: 0.00%
- anger: 0.00%
- sadness: 0.00%
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 73ms/step
Example 2: Feeling so sad after watching that movie. It really broke my heart.
Predicted Emotion: sadness (Confidence: 99.96%)
All Emotion Probabilities:
- sadness: 99.96%
- fear: 0.04%
- joy: 0.00%
- anger: 0.00%
- surprise: 0.00%
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 61ms/step
Example 3: Can't believe how terrible the customer service was! I'm absolutely furious ri
ght now!
Predicted Emotion: anger (Confidence: 100.00%)
All Emotion Probabilities:
- anger: 100.00%
- sadness: 0.00%
- fear: 0.00%
- surprise: 0.00%
- joy: 0.00%
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 58ms/step
Example 4: I'm really nervous about my presentation tomorrow. Can't sleep thinking about
it. #anxiety
Predicted Emotion: fear (Confidence: 100.00%)
All Emotion Probabilities:
- fear: 100.00%
- anger: 0.00%
- sadness: 0.00%
- joy: 0.00%
- surprise: 0.00%
1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 61ms/step
Example 5: OMG! I just won the lottery! I can't believe this is happening to me! What a s
urprise!
Predicted Emotion: surprise (Confidence: 99.97%)
All Emotion Probabilities:
- surprise: 99.97%
- sadness: 0.02%
- joy: 0.01%
- anger: 0.00%
- fear: 0.00%
In [15]:
# Plot
plt.figure(figsize=(12, 6))
In [16]:
# Create a simple interactive tool for emotion prediction
def interactive_emotion_predictor():
print("=== Twitter Emotion Predictor ===\n ")
print("Enter a tweet to analyze its emotion, or type 'quit' to exit.\n ")
while True:
# Get input from user
tweet = input("\n Enter a tweet: ")
# Predict emotion
result = predict_emotion(tweet, best_model, tokenizer, label_mapping, max_len)
# Display result
print(f"\n Predicted Emotion: {result['emotion']} (Confidence: {result['probabilit
y']:.2%})")
# Check versions
print(f"TensorFlow version: {tf.__version__}")
print(f"Keras version: {keras.__version__}")
print(f"NumPy version: {np.__version__}")
print(f"Pandas version: {pd.__version__}")
In [2]:
# Set random seeds for reproducibility
np.random.seed(42)
tf.random.set_seed(42)
In [3]:
# Simple sequential model
model_sequential = keras.Sequential([
keras.layers.Dense(64, activation='relu', input_shape=(784,)),
keras.layers.Dense(32, activation='relu'),
keras.layers.Dense(10, activation='softmax')
])
# Model summary
model_sequential.summary()
/usr/local/lib/python3.11/dist-packages/keras/src/layers/core/dense.py:87: UserWarning: D
o not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models
, prefer using an `Input(shape)` object as the first layer in the model instead.
super().__init__(activity_regularizer=activity_regularizer, **kwargs)
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ dense (Dense) │ (None, 64) │ 50,240 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_1 (Dense) │ (None, 32) │ 2,080 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_2 (Dense) │ (None, 10) │ 330 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
Total params: 52,650 (205.66 KB)
In [4]:
# Functional API example
inputs = keras.Input(shape=(784,))
x = keras.layers.Dense(64, activation='relu')(inputs)
x = keras.layers.Dense(32, activation='relu')(x)
outputs = keras.layers.Dense(10, activation='softmax')(x)
# Model summary
model_functional.summary()
Model: "functional_1"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ input_layer_1 (InputLayer) │ (None, 784) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_3 (Dense) │ (None, 64) │ 50,240 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_4 (Dense) │ (None, 32) │ 2,080 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_5 (Dense) │ (None, 10) │ 330 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
In [5]:
# Subclassing example
class CustomModel(keras.Model):
def __init__(self):
super(CustomModel, self).__init__()
self.dense1 = keras.layers.Dense(64, activation='relu')
self.dense2 = keras.layers.Dense(32, activation='relu')
self.dense3 = keras.layers.Dense(10, activation='softmax')
model_subclass = CustomModel()
Model: "custom_model"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ dense_6 (Dense) │ ? │ 0 (unbuilt) │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_7 (Dense) │ ? │ 0 (unbuilt) │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_8 (Dense) │ ? │ 0 (unbuilt) │
└─────────────────────────────────┴────────────────────────┴───────────────┘
Let's look at a more complex model using some of these layer types:
In [6]:
# Create a more complex model with different layer types
complex_model = keras.Sequential([
# Reshape input to 28x28x1 for CNNs
keras.layers.Reshape((28, 28, 1), input_shape=(784,)),
# Convolutional layers
keras.layers.Conv2D(32, kernel_size=(3, 3), activation='relu'),
keras.layers.MaxPooling2D(pool_size=(2, 2)),
keras.layers.Conv2D(64, kernel_size=(3, 3), activation='relu'),
keras.layers.MaxPooling2D(pool_size=(2, 2)),
# Model summary
complex_model.summary()
/usr/local/lib/python3.11/dist-packages/keras/src/layers/reshaping/reshape.py:39: UserWar
ning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential
models, prefer using an `Input(shape)` object as the first layer in the model instead.
super().__init__(**kwargs)
Model: "sequential_1"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ reshape (Reshape) │ (None, 28, 28, 1) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv2d (Conv2D) │ (None, 26, 26, 32) │ 320 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ max_pooling2d (MaxPooling2D) │ (None, 13, 13, 32) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv2d_1 (Conv2D) │ (None, 11, 11, 64) │ 18,496 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ max_pooling2d_1 (MaxPooling2D) │ (None, 5, 5, 64) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ flatten (Flatten) │ (None, 1600) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_9 (Dense) │ (None, 128) │ 204,928 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout (Dropout) │ (None, 128) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_10 (Dense) │ (None, 10) │ 1,290 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
In [7]:
# Load Fashion MNIST dataset with error handling
try:
# Attempt to load the dataset directly
(x_train, y_train), (x_test, y_test) = keras.datasets.fashion_mnist.load_data()
except Exception as e:
print(f"Error loading dataset directly: {e}")
# If you have the dataset files locally, you can specify the path
# Otherwise, try using a different download method
print("Attempting to download using TensorFlow's get_file utility...")
base_url = 'https://storage.googleapis.com/tensorflow/tf-keras-datasets/'
train_images_path = get_file('train-images-idx3-ubyte.gz', base_url + 'train-images-id
x3-ubyte.gz')
train_labels_path = get_file('train-labels-idx1-ubyte.gz', base_url + 'train-labels-id
x1-ubyte.gz')
test_images_path = get_file('t10k-images-idx3-ubyte.gz', base_url + 't10k-images-idx3-
ubyte.gz')
test_labels_path = get_file('t10k-labels-idx1-ubyte.gz', base_url + 't10k-labels-idx1-
ubyte.gz')
print("⚠️ WARNING: Using randomly generated dummy data. Real model training will not be
meaningful.")
In [8]:
# Define class names for Fashion MNIST
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
In [9]:
# Preprocess the data
# Normalize pixel values to be between 0 and 1
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0
In [ ]:
# Create a simple model for Fashion MNIST
fashion_model = keras.Sequential([
keras.layers.Dense(128, activation='relu', input_shape=(784,)),
keras.layers.Dropout(0.2),
keras.layers.Dense(64, activation='relu'),
keras.layers.Dropout(0.2),
keras.layers.Dense(10, activation='softmax')
])
In [11]:
# Evaluate the model
test_loss, test_acc = fashion_model.evaluate(x_test_flat, y_test, verbose=2)
print(f'\n Test accuracy: {test_acc:.4f}')
In [12]:
# Plot training history
plt.figure(figsize=(12, 4))
plt.tight_layout()
plt.show()
In [13]:
# Make predictions
predictions = fashion_model.predict(x_test_flat)
plt.imshow(img, cmap=plt.cm.binary)
predicted_label = np.argmax(predictions_array[i])
if predicted_label == true_label:
color = 'blue'
else:
color = 'red'
thisplot[predicted_label].set_color('red')
thisplot[true_label].set_color('blue')
# Plot the first X test images, their predicted labels, and the true labels
num_rows = 5
num_cols = 3
num_images = num_rows*num_cols
plt.figure(figsize=(2*2*num_cols, 2*num_rows))
for i in range(num_images):
plt.subplot(num_rows, 2*num_cols, 2*i+1)
plot_image(i, predictions, y_test, x_test)
plt.subplot(num_rows, 2*num_cols, 2*i+2)
plot_value_array(i, predictions, y_test)
plt.tight_layout()
plt.show()
In [15]:
# Reshape data for CNN
x_train_cnn = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test_cnn = x_test.reshape(x_test.shape[0], 28, 28, 1)
In [16]:
# Create a CNN model
cnn_model = keras.Sequential([
keras.layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),
keras.layers.MaxPooling2D((2, 2)),
keras.layers.Conv2D(64, (3, 3), activation='relu'),
keras.layers.MaxPooling2D((2, 2)),
keras.layers.Flatten(),
keras.layers.Dense(128, activation='relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(10, activation='softmax')
])
cnn_model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
cnn_model.summary()
/usr/local/lib/python3.11/dist-packages/keras/src/layers/convolutional/base_conv.py:107:
UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Seq
uential models, prefer using an `Input(shape)` object as the first layer in the model ins
tead.
super().__init__(activity_regularizer=activity_regularizer, **kwargs)
Model: "sequential_3"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ conv2d_2 (Conv2D) │ (None, 26, 26, 32) │ 320 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ max_pooling2d_2 (MaxPooling2D) │ (None, 13, 13, 32) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv2d_3 (Conv2D) │ (None, 11, 11, 64) │ 18,496 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ max_pooling2d_3 (MaxPooling2D) │ (None, 5, 5, 64) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ flatten_1 (Flatten) │ (None, 1600) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_14 (Dense) │ (None, 128) │ 204,928 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_3 (Dropout) │ (None, 128) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_15 (Dense) │ (None, 10) │ 1,290 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
In [ ]:
# Train the CNN model with early stopping and learning rate reduction
early_stopping = keras.callbacks.EarlyStopping(
monitor='val_loss',
patience=3,
restore_best_weights=True
)
lr_scheduler = keras.callbacks.ReduceLROnPlateau(
monitor='val_loss',
factor=0.5,
patience=2
)
cnn_history = cnn_model.fit(
x_train_cnn, y_train,
epochs=15,
batch_size=64,
validation_split=0.2,
callbacks=[early_stopping, lr_scheduler],
verbose=1
)
In [18]:
# Evaluate the CNN model
cnn_test_loss, cnn_test_acc = cnn_model.evaluate(x_test_cnn, y_test, verbose=2)
print(f'\n CNN Test accuracy: {cnn_test_acc:.4f}')
In [19]:
In [21]:
return preprocessed
Model: "functional_5"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ input_layer_6 (InputLayer) │ (None, 96, 96, 3) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ mobilenetv2_1.00_96 │ (None, 3, 3, 1280) │ 2,257,984 │
│ (Functional) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ global_average_pooling2d │ (None, 1280) │ 0 │
│ (GlobalAveragePooling2D) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_16 (Dense) │ (None, 128) │ 163,968 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_4 (Dropout) │ (None, 128) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_17 (Dense) │ (None, 10) │ 1,290 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
In [24]:
# Verify it works
loaded_model_loss, loaded_model_acc = loaded_model.evaluate(x_test_cnn, y_test, verbose=
2)
print(f'\n Loaded model test accuracy: {loaded_model_acc:.4f} ')
WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.savin
g.save_model(model)`. This file format is considered legacy. We recommend using instead t
he native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(m
odel, 'my_model.keras')`.
In [ ]:
# necessary imports
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
plt.style.use('fivethirtyeight')
%matplotlib inline
In [ ]:
df = pd.read_csv(r'C:\Users\Rishi\Churn_Modelling.csv')
df.head()
Out[ ]:
RowNumber CustomerId Surname CreditScore Geography Gender Age Tenure Balance NumOfProducts HasCrCard IsAc
In [3]:
df.describe()
Out[3]:
count 10000.00000 1.000000e+04 10000.000000 10000.000000 10000.000000 10000.000000 10000.000000 10000.00000 10000
In [4]:
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10000 entries, 0 to 9999
Data columns (total 14 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 RowNumber 10000 non-null int64
1 CustomerId 10000 non-null int64
2 Surname 10000 non-null object
3 CreditScore 10000 non-null int64
4 Geography 10000 non-null object
5 Gender 10000 non-null object
6 Age 10000 non-null int64
7 Tenure 10000 non-null int64
8 Balance 10000 non-null float64
9 NumOfProducts 10000 non-null int64
10 HasCrCard 10000 non-null int64
11 IsActiveMember 10000 non-null int64
12 EstimatedSalary 10000 non-null float64
13 Exited 10000 non-null int64
dtypes: float64(2), int64(9), object(3)
memory usage: 1.1+ MB
In [ ]:
# checking for null values
In [6]:
values = df.Exited.value_counts()
labels = ['Not Exited', 'Exited']
patches, texts, autotexts = ax.pie(values, labels = labels, autopct = '%1.2f%% ', shadow
= True,
startangle = 90, explode = explode)
In [7]:
# visualizing categorical variables
plt.tight_layout()
plt.show()
In [8]:
# visualizing continuous variables
plt.tight_layout()
plt.show()
In [9]:
# heatmap
corr = df.corr()
In [10]:
CreditScore Geography Gender Age Tenure Balance NumOfProducts HasCrCard IsActiveMember EstimatedSalary Exited
France 5014
Germany 2509
Spain 2477
Name: Geography, dtype: int64
In [12]:
# Encoding categorical variables
In [13]:
df.head()
Out[13]:
CreditScore Geography Gender Age Tenure Balance NumOfProducts HasCrCard IsActiveMember EstimatedSalary Exited
In [14]:
# creating features and label
X = df.drop('Exited', axis = 1)
y = to_categorical(df.Exited)
In [15]:
# splitting data into training set and test set
In [16]:
# Scaling data
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
In [ ]:
import keras
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import BatchNormalization
# initializing ann
model = Sequential()
# adding the first input layer and the first hidden layer
model.add(Dense(10, kernel_initializer = 'normal', activation = 'relu', input_shape = (1
0, )))
In [18]:
plt.figure(figsize = (12, 6))
train_loss = model_history.history['loss']
val_loss = model_history.history['val_loss']
epoch = range(1, 101)
sns.lineplot(epoch, train_loss, label = 'Training Loss')
sns.lineplot(epoch, val_loss, label = 'Validation Loss')
plt.title('Training and Validation Loss\n ')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
In [19]:
plt.figure(figsize = (12, 6))
train_loss = model_history.history['accuracy']
val_loss = model_history.history['val_accuracy']
epoch = range(1, 101)
sns.lineplot(epoch, train_loss, label = 'Training accuracy')
sns.lineplot(epoch, val_loss, label = 'Validation accuracy')
plt.title('Training and Validation Accuracy\n ')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.show()
In [20]:
acc = model.evaluate(X_test, y_test)[1]
In [21]:
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
dense (Dense) (None, 10) 110
_________________________________________________________________
dropout (Dropout) (None, 10) 0
_________________________________________________________________
batch_normalization (BatchNo (None, 10) 40
_________________________________________________________________
dense_1 (Dense) (None, 7) 77
_________________________________________________________________
dropout_1 (Dropout) (None, 7) 0
_________________________________________________________________
batch_normalization_1 (Batch (None, 7) 28
_________________________________________________________________
dense_2 (Dense) (None, 2) 16
=================================================================
Total params: 271
Trainable params: 237
Non-trainable params: 34
_________________________________________________________________
In [22]:
from tensorflow.keras.utils import plot_model
In [ ]:
In [ ]:
train_dataset = tf.data.Dataset.from_tensor_slices(x_train).shuffle(BUFFER_SIZE).batch(B
ATCH_SIZE)
In [ ]:
# Visualize some samples from the dataset
plt.figure(figsize=(10, 10))
for i in range(25):
plt.subplot(5, 5, i+1)
# Rescale to [0, 1]
plt.imshow(x_train[i, :, :, 0] * 0.5 + 0.5, cmap='gray')
plt.axis('off')
plt.tight_layout()
plt.show()
In [ ]:
# Define the random noise dimension
NOISE_DIM = 100
# First, transform the input into a small spatial extent with many channels
model.add(layers.Dense(7 * 7 * 256, use_bias=False, input_shape=(NOISE_DIM,)))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU(alpha=0.2))
# Final layer with tanh activation to generate images with pixel values in [-1, 1]
model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias
=False, activation='tanh'))
return model
/usr/local/lib/python3.11/dist-packages/keras/src/layers/core/dense.py:87: UserWarning: D
o not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models
, prefer using an `Input(shape)` object as the first layer in the model instead.
super().__init__(activity_regularizer=activity_regularizer, **kwargs)
/usr/local/lib/python3.11/dist-packages/keras/src/layers/activations/leaky_relu.py:41: Us
erWarning: Argument `alpha` is deprecated. Use `negative_slope` instead.
warnings.warn(
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ dense (Dense) │ (None, 12544) │ 1,254,400 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ batch_normalization │ (None, 12544) │ 50,176 │
│ (BatchNormalization) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ leaky_re_lu (LeakyReLU) │ (None, 12544) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ reshape (Reshape) │ (None, 7, 7, 256) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv2d_transpose │ (None, 7, 7, 128) │ 819,200 │
│ (Conv2DTranspose) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ batch_normalization_1 │ (None, 7, 7, 128) │ 512 │
│ (BatchNormalization) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ leaky_re_lu_1 (LeakyReLU) │ (None, 7, 7, 128) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv2d_transpose_1 │ (None, 14, 14, 64) │ 204,800 │
│ (Conv2DTranspose) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ batch_normalization_2 │ (None, 14, 14, 64) │ 256 │
│ (BatchNormalization) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ leaky_re_lu_2 (LeakyReLU) │ (None, 14, 14, 64) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv2d_transpose_2 │ (None, 28, 28, 1) │ 1,600 │
│ (Conv2DTranspose) │ │ │
└─────────────────────────────────┴────────────────────────┴───────────────┘
In [ ]:
# Build the discriminator model
def build_discriminator():
model = keras.Sequential()
return model
/usr/local/lib/python3.11/dist-packages/keras/src/layers/convolutional/base_conv.py:107:
UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Seq
uential models, prefer using an `Input(shape)` object as the first layer in the model ins
uential models, prefer using an `Input(shape)` object as the first layer in the model ins
tead.
super().__init__(activity_regularizer=activity_regularizer, **kwargs)
Model: "sequential_1"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ conv2d (Conv2D) │ (None, 14, 14, 64) │ 1,664 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ leaky_re_lu_3 (LeakyReLU) │ (None, 14, 14, 64) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout (Dropout) │ (None, 14, 14, 64) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv2d_1 (Conv2D) │ (None, 7, 7, 128) │ 204,928 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ leaky_re_lu_4 (LeakyReLU) │ (None, 7, 7, 128) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_1 (Dropout) │ (None, 7, 7, 128) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ flatten (Flatten) │ (None, 6272) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_1 (Dense) │ (None, 1) │ 6,273 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
In [ ]:
In [ ]:
# Define a function to generate and save images
def generate_and_save_images(model, epoch, test_input):
# Generate images
predictions = model(test_input, training=False)
In [ ]:
# Define the training step
@tf.function
def train_step(images):
# Generate random noise for the generator
noise = tf.random.normal([BATCH_SIZE, NOISE_DIM])
# Calculate losses
gen_loss = generator_loss(fake_output)
disc_loss = discriminator_loss(real_output, fake_output)
# Calculate gradients
gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)
gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_va
riables)
# Apply gradients
generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_v
ariables))
discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, discriminator
.trainable_variables))
In [ ]:
# Define the training function
def train(dataset, epochs):
# Create a fixed noise vector for visualization
seed = tf.random.normal([25, NOISE_DIM])
# Track losses
gen_losses = []
disc_losses = []
# Training loop
for epoch in range(1, epochs + 1):
start_time = time.time()
# Train on batches
for image_batch in dataset:
gen_loss, disc_loss = train_step(image_batch)
batch_gen_losses.append(gen_loss)
batch_disc_losses.append(disc_loss)
# Print progress
print(f"Epoch {epoch} /{epochs}, "
f"Generator Loss: {avg_gen_loss:.4f}, "
f"Discriminator Loss: {avg_disc_loss:.4f}, "
f"Time: {time.time() - start_time:.2f} sec")
plt.subplot(1, 2, 2)
plt.plot(range(1, epochs + 1), disc_losses, label='Discriminator')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Discriminator Loss')
plt.grid(True)
plt.tight_layout()
plt.show()
In [ ]:
# Define the number of epochs
EPOCHS = 50
Epoch 21/50, Generator Loss: 1.1547, Discriminator Loss: 1.0748, Time: 12.01 sec
Epoch 22/50, Generator Loss: 1.0937, Discriminator Loss: 1.1145, Time: 12.05 sec
Epoch 23/50, Generator Loss: 1.1250, Discriminator Loss: 1.1247, Time: 12.06 sec
Epoch 24/50, Generator Loss: 1.0968, Discriminator Loss: 1.1338, Time: 12.09 sec
Epoch 25/50, Generator Loss: 1.0754, Discriminator Loss: 1.1494, Time: 12.14 sec
Epoch 25/50, Generator Loss: 1.0754, Discriminator Loss: 1.1494, Time: 12.14 sec
Epoch 26/50, Generator Loss: 1.0967, Discriminator Loss: 1.1201, Time: 12.14 sec
Epoch 27/50, Generator Loss: 1.0493, Discriminator Loss: 1.1688, Time: 12.10 sec
Epoch 28/50, Generator Loss: 1.0357, Discriminator Loss: 1.1652, Time: 12.09 sec
Epoch 29/50, Generator Loss: 1.0498, Discriminator Loss: 1.1800, Time: 12.08 sec
Epoch 30/50, Generator Loss: 1.0252, Discriminator Loss: 1.1832, Time: 12.08 sec
Epoch 31/50, Generator Loss: 1.0058, Discriminator Loss: 1.1969, Time: 12.10 sec
Epoch 32/50, Generator Loss: 1.0144, Discriminator Loss: 1.1886, Time: 12.16 sec
Epoch 33/50, Generator Loss: 0.9977, Discriminator Loss: 1.1890, Time: 12.19 sec
Epoch 34/50, Generator Loss: 0.9557, Discriminator Loss: 1.2099, Time: 12.20 sec
Epoch 35/50, Generator Loss: 0.9276, Discriminator Loss: 1.2330, Time: 12.20 sec
Epoch 36/50, Generator Loss: 0.9567, Discriminator Loss: 1.2123, Time: 12.18 sec
Epoch 37/50, Generator Loss: 0.9403, Discriminator Loss: 1.2133, Time: 12.17 sec
Epoch 38/50, Generator Loss: 0.9853, Discriminator Loss: 1.2095, Time: 12.18 sec
Epoch 39/50, Generator Loss: 0.9811, Discriminator Loss: 1.2113, Time: 12.20 sec
Epoch 40/50, Generator Loss: 0.9665, Discriminator Loss: 1.2082, Time: 12.20 sec
Epoch 41/50, Generator Loss: 0.9887, Discriminator Loss: 1.1944, Time: 12.14 sec
Epoch 42/50, Generator Loss: 0.9751, Discriminator Loss: 1.2128, Time: 12.14 sec
Epoch 43/50, Generator Loss: 0.9558, Discriminator Loss: 1.2182, Time: 12.15 sec
Epoch 44/50, Generator Loss: 0.9504, Discriminator Loss: 1.2224, Time: 12.14 sec
Epoch 45/50, Generator Loss: 0.9616, Discriminator Loss: 1.2101, Time: 12.17 sec
Epoch 46/50, Generator Loss: 0.9443, Discriminator Loss: 1.2246, Time: 12.16 sec
Epoch 47/50, Generator Loss: 0.9527, Discriminator Loss: 1.2142, Time: 12.15 sec
Epoch 48/50, Generator Loss: 0.9618, Discriminator Loss: 1.2021, Time: 12.14 sec
Epoch 49/50, Generator Loss: 0.9717, Discriminator Loss: 1.2104, Time: 12.11 sec
Epoch 50/50, Generator Loss: 0.9633, Discriminator Loss: 1.2100, Time: 12.11 sec
GAN training completed!
In [ ]:
for i, ax in enumerate(axes.flatten()):
if i < num_examples:
ax.imshow(generated_images[i, :, :, 0], cmap='gray')
ax.axis('off')
plt.tight_layout()
plt.subplots_adjust(top=0.95)
plt.show()
In [ ]:
# Create an animation of the generation process
# We can use the saved images from different epochs
try:
import imageio
from IPython.display import display, HTML
import glob
In [ ]:
In [ ]:
# Load MNIST dataset with labels
(x_train, y_train), (_, _) = keras.datasets.mnist.load_data()
In [ ]:
# Upsampling layers
x = layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=Fal
se )(x)
x = layers.BatchNormalization()(x)
x = layers.LeakyReLU(alpha=0.2)(x)
# Convolutional layers
x = layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same')(combined_input)
x = layers.LeakyReLU(alpha=0.2)(x)
x = layers.Dropout(0.3)(x)
Conditional Generator:
Model: "functional_19"
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃ Connected to ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ input_layer_3 │ (None, 1) │ 0 │ - │
│ (InputLayer) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ embedding │ (None, 1, 50) │ 500 │ input_layer_3[0]… │
│ (Embedding) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ input_layer_2 │ (None, 100) │ 0 │ - │
│ (InputLayer) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ flatten_1 (Flatten) │ (None, 50) │ 0 │ embedding[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ concatenate │ (None, 150) │ 0 │ input_layer_2[0]… │
│ (Concatenate) │ │ │ flatten_1[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense_2 (Dense) │ (None, 12544) │ 1,881,600 │ concatenate[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 12544) │ 50,176 │ dense_2[0][0] │
│ (BatchNormalizatio… │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ leaky_re_lu_5 │ (None, 12544) │ 0 │ batch_normalizat… │
│ (LeakyReLU) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ reshape_1 (Reshape) │ (None, 7, 7, 256) │ 0 │ leaky_re_lu_5[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_transpose_3 │ (None, 7, 7, 128) │ 819,200 │ reshape_1[0][0] │
│ (Conv2DTranspose) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 7, 7, 128) │ 512 │ conv2d_transpose… │
│ (BatchNormalizatio… │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ leaky_re_lu_6 │ (None, 7, 7, 128) │ 0 │ batch_normalizat… │
│ (LeakyReLU) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_transpose_4 │ (None, 14, 14, │ 204,800 │ leaky_re_lu_6[0]… │
│ (Conv2DTranspose) │ 64) │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ batch_normalizatio… │ (None, 14, 14, │ 256 │ conv2d_transpose… │
│ (BatchNormalizatio… │ 64) │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ leaky_re_lu_7 │ (None, 14, 14, │ 0 │ batch_normalizat… │
│ (LeakyReLU) │ 64) │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_transpose_5 │ (None, 28, 28, 1) │ 1,600 │ leaky_re_lu_7[0]… │
│ (Conv2DTranspose) │ │ │ │
└─────────────────────┴───────────────────┴────────────┴───────────────────┘
Conditional Discriminator:
Model: "functional_20"
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃ Connected to ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ input_layer_5 │ (None, 1) │ 0 │ - │
│ (InputLayer) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ embedding_1 │ (None, 1, 50) │ 500 │ input_layer_5[0]… │
│ (Embedding) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ flatten_2 (Flatten) │ (None, 50) │ 0 │ embedding_1[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense_3 (Dense) │ (None, 784) │ 39,984 │ flatten_2[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ input_layer_4 │ (None, 28, 28, 1) │ 0 │ - │
│ (InputLayer) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ reshape_2 (Reshape) │ (None, 28, 28, 1) │ 0 │ dense_3[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ concatenate_1 │ (None, 28, 28, 2) │ 0 │ input_layer_4[0]… │
│ (Concatenate) │ │ │ reshape_2[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_2 (Conv2D) │ (None, 14, 14, │ 3,264 │ concatenate_1[0]… │
│ │ 64) │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ leaky_re_lu_8 │ (None, 14, 14, │ 0 │ conv2d_2[0][0] │
│ (LeakyReLU) │ 64) │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dropout_2 (Dropout) │ (None, 14, 14, │ 0 │ leaky_re_lu_8[0]… │
│ │ 64) │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv2d_3 (Conv2D) │ (None, 7, 7, 128) │ 204,928 │ dropout_2[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ leaky_re_lu_9 │ (None, 7, 7, 128) │ 0 │ conv2d_3[0][0] │
│ (LeakyReLU) │ │ │ │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dropout_3 (Dropout) │ (None, 7, 7, 128) │ 0 │ leaky_re_lu_9[0]… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ flatten_3 (Flatten) │ (None, 6272) │ 0 │ dropout_3[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ dense_4 (Dense) │ (None, 1) │ 6,273 │ flatten_3[0][0] │
└─────────────────────┴───────────────────┴────────────┴───────────────────┘
In [ ]:
# Calculate losses
gen_loss = generator_loss(fake_output)
disc_loss = discriminator_loss(real_output, fake_output)
# Calculate gradients
gradients_of_generator = gen_tape.gradient(gen_loss, conditional_generator.trainable_
variables)
gradients_of_discriminator = disc_tape.gradient(disc_loss, conditional_discriminator.
trainable_variables)
# Apply gradients
generator_optimizer.apply_gradients(zip(gradients_of_generator, conditional_generator
.trainable_variables))
discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, conditional_d
iscriminator.trainable_variables))
In [ ]:
# Generate images
generated_images = conditional_generator([noise, labels], training=False)
generated_images = generated_images * 0.5 + 0.5 # Convert to [0, 1] range
In [ ]:
# Define the training function
def train(dataset, epochs):
# Create a fixed noise vector for visualization
seed = tf.random.normal([25, NOISE_DIM])
# Track losses
gen_losses = []
disc_losses = []
# Re-initialize optimizers inside the training loop to ensure they are built with the
correct variables
# This can sometimes help with tf.function related issues where variables are not pro
perly registered
# with the optimizer in graph mode.
conditional_generator_optimizer = keras.optimizers.Adam(1e-4)
conditional_discriminator_optimizer = keras.optimizers.Adam(1e-4)
# Training loop
for epoch in range(1, epochs + 1):
start_time = time.time()
# Train on batches
for image_batch, label_batch in dataset:
# Pass the correct optimizers to the train step
gen_loss, disc_loss = train_conditional_step(
image_batch,
label_batch,
conditional_generator_optimizer,
conditional_discriminator_optimizer
)
batch_gen_losses.append(gen_loss)
batch_disc_losses.append(disc_loss)
# Print progress
print(f"Epoch {epoch} /{epochs}, "
f"Generator Loss: {avg_gen_loss:.4f}, "
f"Discriminator Loss: {avg_disc_loss:.4f}, "
f"Time: {time.time() - start_time:.2f} sec")
plt.subplot(1, 2, 2)
plt.plot(range(1, epochs + 1), disc_losses, label='Discriminator')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Discriminator Loss')
plt.grid(True)
plt.tight_layout()
plt.show()
# Calculate losses
gen_loss = generator_loss(fake_output)
disc_loss = discriminator_loss(real_output, fake_output)
# Calculate gradients
gradients_of_generator = gen_tape.gradient(gen_loss, conditional_generator.trainable_
variables)
gradients_of_discriminator = disc_tape.gradient(disc_loss, conditional_discriminator.
trainable_variables)
# Apply gradients
# Pass the gradients and variables as lists or tuples explicitly
generator_optimizer.apply_gradients(zip(gradients_of_generator, conditional_generator
.trainable_variables))
discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, conditional_d
iscriminator.trainable_variables))
Epoch 6/10, Generator Loss: 1.1119, Discriminator Loss: 1.1047, Time: 12.13 sec
Epoch 7/10, Generator Loss: 1.0590, Discriminator Loss: 1.1147, Time: 12.11 sec
Epoch 8/10, Generator Loss: 1.0267, Discriminator Loss: 1.1591, Time: 12.19 sec
Epoch 9/10, Generator Loss: 1.1146, Discriminator Loss: 1.0851, Time: 12.28 sec
Epoch 10/10, Generator Loss: 1.1838, Discriminator Loss: 1.0617, Time: 12.28 sec
Conditional GAN training completed!