Import Libraries

%matplotlib inline

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

Download Data

(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

Plot Examples

plt.figure(figsize=(10, 10))

for i in range(16):
    plt.subplot(4, 4, i + 1)
    plt.imshow(x_train[i], cmap='binary')
    plt.xlabel(str(y_train[i]))
    plt.xticks([])
    plt.yticks([])
plt.show()

Normalize Data

x_train = np.reshape(x_train, (60000, 784))
x_train = x_train / 255.

x_test = np.reshape(x_test, (10000, 784))
x_test = x_test / 255.

Create a Neural Network Model

model = tf.keras.models.Sequential([
    tf.keras.layers.Dense(32, activation='sigmoid', input_shape=(784,)),
    tf.keras.layers.Dense(32, activation='sigmoid'),
    tf.keras.layers.Dense(10, activation='softmax')
])

model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

Train the Model

_ = model.fit(
    x_train, y_train,
    validation_data=(x_test, y_test),
    epochs=20, batch_size=1024,
    verbose=2
)
Train on 60000 samples, validate on 10000 samples
Epoch 1/20
60000/60000 - 1s - loss: 2.1994 - accuracy: 0.3593 - val_loss: 1.9857 - val_accuracy: 0.6710
Epoch 2/20
60000/60000 - 0s - loss: 1.7957 - accuracy: 0.6828 - val_loss: 1.5774 - val_accuracy: 0.7260
Epoch 3/20
60000/60000 - 0s - loss: 1.3886 - accuracy: 0.7427 - val_loss: 1.1907 - val_accuracy: 0.7763
Epoch 4/20
60000/60000 - 0s - loss: 1.0471 - accuracy: 0.7973 - val_loss: 0.9006 - val_accuracy: 0.8376
Epoch 5/20
60000/60000 - 0s - loss: 0.8084 - accuracy: 0.8505 - val_loss: 0.7101 - val_accuracy: 0.8699
Epoch 6/20
60000/60000 - 0s - loss: 0.6540 - accuracy: 0.8751 - val_loss: 0.5875 - val_accuracy: 0.8869
Epoch 7/20
60000/60000 - 0s - loss: 0.5524 - accuracy: 0.8868 - val_loss: 0.5048 - val_accuracy: 0.8963
Epoch 8/20
60000/60000 - 0s - loss: 0.4820 - accuracy: 0.8960 - val_loss: 0.4462 - val_accuracy: 0.9027
Epoch 9/20
60000/60000 - 0s - loss: 0.4308 - accuracy: 0.9015 - val_loss: 0.4034 - val_accuracy: 0.9095
Epoch 10/20
60000/60000 - 0s - loss: 0.3921 - accuracy: 0.9065 - val_loss: 0.3702 - val_accuracy: 0.9132
Epoch 11/20
60000/60000 - 0s - loss: 0.3617 - accuracy: 0.9112 - val_loss: 0.3445 - val_accuracy: 0.9165
Epoch 12/20
60000/60000 - 0s - loss: 0.3370 - accuracy: 0.9163 - val_loss: 0.3224 - val_accuracy: 0.9196
Epoch 13/20
60000/60000 - 0s - loss: 0.3161 - accuracy: 0.9201 - val_loss: 0.3045 - val_accuracy: 0.9222
Epoch 14/20
60000/60000 - 0s - loss: 0.2985 - accuracy: 0.9229 - val_loss: 0.2908 - val_accuracy: 0.9255
Epoch 15/20
60000/60000 - 0s - loss: 0.2832 - accuracy: 0.9269 - val_loss: 0.2765 - val_accuracy: 0.9275
Epoch 16/20
60000/60000 - 0s - loss: 0.2697 - accuracy: 0.9294 - val_loss: 0.2664 - val_accuracy: 0.9297
Epoch 17/20
60000/60000 - 0s - loss: 0.2578 - accuracy: 0.9319 - val_loss: 0.2546 - val_accuracy: 0.9324
Epoch 18/20
60000/60000 - 0s - loss: 0.2469 - accuracy: 0.9348 - val_loss: 0.2455 - val_accuracy: 0.9350
Epoch 19/20
60000/60000 - 0s - loss: 0.2372 - accuracy: 0.9377 - val_loss: 0.2371 - val_accuracy: 0.9371
Epoch 20/20
60000/60000 - 0s - loss: 0.2283 - accuracy: 0.9393 - val_loss: 0.2289 - val_accuracy: 0.9386

Save the Model

model.save('model.h5')

ml_server.py

import json
import tensorflow as tf
import numpy as np
import os
import random
import string

from flask import Flask, request

app = Flask(__name__)

model = tf.keras.models.load_model('model.h5')
feature_model = tf.keras.models.Model(model.inputs, [layer.output for layer in model.layers])

_, (x_test, _) = tf.keras.datasets.mnist.load_data()
x_test = x_test / 255.

def get_prediction():
    index = np.random.choice(x_test.shape[0])
    image = x_test[index,:,:]
    image_arr = np.reshape(image, (1, 784))
    return feature_model.predict(image_arr), image

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        preds, image = get_prediction()
        final_preds = [p.tolist() for p in preds]
        return json.dumps({'prediction': final_preds, 'image': image.tolist()})
    return 'Welcome to the ml server'

if __name__ == '__main__':
    app.run()

app.py

import requests
import json
import numpy as np
import streamlit as st
import os
import matplotlib.pyplot as plt

URI = 'http://127.0.0.1:5000'

st.title('Neural Network Visualizer')
st.sidebar.markdown('# Input Image')

if st.button('Get random predictions'):
    response = requests.post(URI, data={})
    # print(response.text)
    response = json.loads(response.text)
    preds = response.get('prediction')
    image = response.get('image')
    image = np.reshape(image, (28, 28))

    st.sidebar.image(image, width=150)

    for layer, p in enumerate(preds):
        numbers = np.squeeze(np.array(p))

        plt.figure(figsize=(32, 4))

        if layer == 2:
            row = 1
            col = 10
        else:
            row = 2
            col = 16

        for i, number in enumerate(numbers):
            plt.subplot(row, col, i + 1)
            plt.imshow((number * np.ones((8, 8, 3))).astype('float32'), cmap='binary')
            plt.xticks([])
            plt.yticks([])
            if layer == 2:
                plt.xlabel(str(i), fontsize=40)
        plt.subplots_adjust(wspace=0.05, hspace=0.05)
        plt.tight_layout()

        st.text('Layer {}'.format(layer + 1), )
        st.pyplot()