<jupyter_start><jupyter_text><jupyter_code>import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.layers import Dropout

from tensorflow.keras.utils import to_categorical
# Load mnist data set into train and test splits
(X_train, y_train), (X_valid, y_valid) = mnist.load_data()
# Preprocess Data - Same steps as followed in shallow network
X_train = X_train.reshape(60000, 784).astype('float32')
X_valid = X_valid.reshape(10000, 784).astype('float32')

X_train /= 255
X_valid /= 255

n_classes = 10
y_train = to_categorical(y_train, n_classes)
y_valid = to_categorical(y_valid, n_classes)
# Model Designing - For deep neuaral network, general rule of thumb is : 
# 1 i/p layer, 1 o/p layer and 3 or more hidden layers

# Create a sequntial Model
model = Sequential()

# Batch normalization helps normalize the o/p a from one hidden layer to next
# It works by normalizing z value (w.x + b) prior to running activation function
# It is similar to input scaling performed on input vector X
# Key difference is z is not normalized with mean 0 & std dev of 1 like i/p vectors, 
# It includes 2 learnable parameters beta and gamma which shifts the mean and variance of z

# Add first hidden layers with batch normalization
model.add(Dense(64, activation = 'relu', input_shape = (784,)))
model.add(BatchNormalization())

# Add second hidden layer with batch normalization
model.add(Dense(64, activation='relu'))
model.add(BatchNormalization())

# Add third hiddden layer with batch normalization and 20% Dropout
# Dropout prevent overfitting by dropping certain percentage of neurons in each run
model.add(Dense(64, activation='relu'))
model.add(BatchNormalization())
model.add(Dropout(.2))  

# Add o/p softmax layer of 10 neurons
model.add(Dense(10, activation = 'softmax'))


# Compile / Configure model
model.compile(optimizer = 'nadam', loss = 'categorical_crossentropy', metrics = ['accuracy'])
# Review model summary
model.summary()
# Fitting the model
model.fit(x=X_train, y= y_train, batch_size=128, epochs = 20, verbose = 1, validation_data=(X_valid, y_valid))
# Evaluate model performance
model.evaluate(X_valid, y_valid)
# Importing numpy
import numpy as np

# Performing a sample prediction
X_valid_0 = X_valid[0].reshape(1,784)
y_pred = model.predict(X_valid_0)

# Print results
print(f'Actual y_valid[0]                   : {y_valid[0]}')
print(f'Taking raw np.argmax (Index)        : {np.argmax(y_pred)}')
print(f'Taking np.argmax(predict, axis = -1): {np.argmax(model.predict(X_valid_0), axis=-1)}')
print(f'Raw prediction using predict method : {[round(i,0) for i  in y_pred[0]]}') # Predict method expects an array of i/p
#print(f'Using Pred class                    : {model.predict_classes(X_valid_0)}') #-- Deprecated
# Concludes basic deep neural network architecture for classification problem based on JonKrohn's lectures.<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09862385321100918, 'fraction_numerical': 0.02326343381389253, 'mean_word_length': 5.155241935483871, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '667292', 'license': 'MIT', 'n_tokens_mistral': 1027, 'n_tokens_neox': 959, 'n_words': 323, 'path': 'Neural Networks/03_Deep_Net_in_tensorflow_mnist_classification.ipynb', 'repo_name': 'kishore145/AI-ML-Foundations', 'size': '3052'}