<jupyter_start><jupyter_text>load library<jupyter_code>import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
from tensorflow import keras
# from tensorflow.keras.utils import to_categorical
# from tensorflow.keras.models import Sequential
# from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
# from tensorflow.keras.losses import categorical_crossentropy
# from tensorflow.keras.optimizers import Adam
# from tensorflow.keras.preprocessing.image import ImageDataGenerator

import matplotlib.pyplot as plt<jupyter_output><empty_output><jupyter_text>Load dataset<jupyter_code>train_data_path = 'emnist/emnist-balanced-train.csv'
test_data_path = 'emnist/emnist-balanced-test.csv'
train_data = pd.read_csv(train_data_path, header=None) #Carregar o dado de treino
train_data.head(10) #Imprimir apenas as 10 primeiras linhas
# The classes of this balanced dataset are as follows. Index into it based on class label
class_mapping = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabdefghnqrt'
# source data: https://arxiv.org/pdf/1702.05373.pdf
class_mapping[34]
train_data.shape<jupyter_output><empty_output><jupyter_text>Data is flipped<jupyter_code>num_classes = len(train_data[0].unique())
row_num = 8

plt.imshow(train_data.values[row_num, 1:].reshape([28, 28]), cmap='Greys_r')
plt.show()

img_flip = np.transpose(train_data.values[row_num,1:].reshape(28, 28), axes=[1,0]) # img_size * img_size arrays
plt.imshow(img_flip, cmap='Greys_r')

plt.show()
def show_img(data, row_num):
    img_flip = np.transpose(data.values[row_num,1:].reshape(28, 28), axes=[1,0]) # img_size * img_size arrays
    plt.title('Class: ' + str(data.values[row_num,0]) + ', Label: ' + str(class_mapping[data.values[row_num,0]]))
    plt.imshow(img_flip, cmap='Greys_r')
show_img(train_data, 149)
# 10 digits, 26 letters, and 11 capital letters that are different looking from their lowercase counterparts
num_classes = 47 
img_size = 28

def img_label_load(data_path, num_classes=None):
    data = pd.read_csv(data_path, header=None)
    data_rows = len(data)
    if not num_classes:
        num_classes = len(data[0].unique())
    
    # this assumes square imgs. Should be 28x28
    img_size = int(np.sqrt(len(data.iloc[0][1:])))
    
    # Images need to be transposed. This line also does the reshaping needed.
    imgs = np.transpose(data.values[:,1:].reshape(data_rows, img_size, img_size, 1), axes=[0,2,1,3]) # img_size * img_size arrays
    
    labels = keras.utils.to_categorical(data.values[:,0], num_classes) # one-hot encoding vectors
    
    return imgs/255., labels<jupyter_output><empty_output><jupyter_text>model, compile<jupyter_code>model = keras.models.Sequential()

# model.add(keras.layers.Reshape((img_size,img_size,1), input_shape=(784,)))
model.add(keras.layers.Conv2D(filters=12, kernel_size=(5,5), strides=2, activation='relu', 
                              input_shape=(img_size,img_size,1)))
# model.add(keras.layers.MaxPooling2D(pool_size=(2,2)))
model.add(keras.layers.Dropout(.5))

model.add(keras.layers.Conv2D(filters=18, kernel_size=(3,3) , strides=2, activation='relu'))
# model.add(keras.layers.MaxPooling2D(pool_size=(2,2)))
model.add(keras.layers.Dropout(.5))

model.add(keras.layers.Conv2D(filters=24, kernel_size=(2,2), activation='relu'))
# model.add(keras.layers.MaxPooling2D(pool_size=(2,2)))

# model.add(keras.layers.Conv2D(filters=30, kernel_size=(3,3), activation='relu'))

model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(units=150, activation='relu'))
model.add(keras.layers.Dense(units=num_classes, activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='Adam', metrics=['accuracy'])
model.summary()
for layer in model.layers:
    print(layer.get_output_at(0).get_shape().as_list())<jupyter_output>[None, 12, 12, 12]
[None, 12, 12, 12]
[None, 5, 5, 18]
[None, 5, 5, 18]
[None, 4, 4, 24]
[None, 384]
[None, 150]
[None, 47]<jupyter_text>Train<jupyter_code>X, y = img_label_load(train_data_path)
print(X.shape)
data_generator = keras.preprocessing.image.ImageDataGenerator(validation_split=.2)
## consider using this for more variety
data_generator_with_aug = keras.preprocessing.image.ImageDataGenerator(validation_split=.2,
                                            width_shift_range=.2, height_shift_range=.2,
                                            rotation_range=60, zoom_range=.2, shear_range=.3)

# if already ran this above, no need to do it again
# X, y = img_label_load(train_data_path)
# print("X.shape: ", X.shape)

training_data_generator = data_generator.flow(X, y, subset='training')
validation_data_generator = data_generator.flow(X, y, subset='validation')
history = model.fit_generator(training_data_generator, 
                              steps_per_epoch=500, epochs=5, # can change epochs to 10
                              validation_data=validation_data_generator)

test_X, test_y = img_label_load(test_data_path)
test_data_generator = data_generator.flow(X, y)

model.evaluate_generator(test_data_generator)<jupyter_output><empty_output><jupyter_text>Look at some predictions<jupyter_code>test_data = pd.read_csv(test_data_path, header=None)
show_img(test_data, 123)
X_test, y_test = img_label_load(test_data_path) # loads images and orients for model
def run_prediction(idx):
    result = np.argmax(model.predict(X_test[idx:idx+1]))
    print('Prediction: ', result, ', Char: ', class_mapping[result])
    print('Label: ', test_data.values[idx,0])
    show_img(test_data, idx)
import random

for _ in range(1,10):
    idx = random.randint(0, 47-1)
    run_prediction(idx)
show_img(test_data, 123)
np.argmax(y_test[123])<jupyter_output><empty_output><jupyter_text>Export model to TF SavedModel for CMLE Predictionhttps://www.tensorflow.org/api_docs/python/tf/keras/estimator/model_to_estimator<jupyter_code># First, convert Keras Model to TensorFlow Estimator
model_input_name = model.input_names[0]
estimator_model = keras.estimator.model_to_estimator(keras_model=model, model_dir="./estimator_model")
print(model_input_name)
# Next, export the TensorFlow Estimator to SavedModel

from functools import partial
import tensorflow as tf

def serving_input_receiver_fn():
    input_ph = tf.placeholder(tf.string, shape=[None], name='image_binary')
    images = tf.map_fn(partial(tf.image.decode_image, channels=1), input_ph, dtype=tf.uint8)
    images = tf.cast(images, tf.float32) / 255.
    images.set_shape([None, 28, 28, 1])

    # the first key is the name of first layer of the (keras) model. 
    # The second key is the name of the key that will be passed in the prediction request
    return tf.estimator.export.ServingInputReceiver({model_input_name: images}, {'bytes': input_ph})
export_path = estimator_model.export_savedmodel('./export', serving_input_receiver_fn=serving_input_receiver_fn)
export_path<jupyter_output><empty_output><jupyter_text>Keras exports<jupyter_code>with open('model.json', 'w') as f:
    f.write(model.to_json())
model.save_weights('./model.h5')

model.save('./full_model.h5')
!ls -lh<jupyter_output><empty_output><jupyter_text>Plot loss and accuracy<jupyter_code>import matplotlib.pyplot as plt

print(history.history.keys())

# accuracy
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('model accuracy')
plt.ylabel('accuracy')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='lower right')
plt.show()

# loss
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='upper right')
plt.show()<jupyter_output><empty_output><jupyter_text>Create some output files for sending to Cloud ML Engine's online prediction<jupyter_code>from PIL import Image

def export_png(row_num, data=test_data):
    array = np.transpose(data.values[row_num,1:].reshape(28, 28), axes=[1,0])
    img = Image.fromarray(array.astype(np.uint8))
    filename = 'class_' + str(data.values[row_num,0]) + '_label_' + str(class_mapping[data.values[row_num,0]]) + '.png'
    img.save(filename)
export_png(149)
import base64
import json

img_filename = 'class_19_label_J.png'
json_filename = 'class_19_label_J.json'

with open(img_filename, 'rb') as img_file :
    img_str = base64.b64encode(img_file.read())
    print(str(img_str))

    json_img = {"image_bytes":{"b64": str(img_str) }}
    print(type(json_img['image_bytes']['b64']))

with open(json_filename, 'w') as outfile:
    json.dump(json_img, outfile)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13484194564329874, 'fraction_numerical': 0.026595124227225007, 'mean_word_length': 5.761829652996846, 'pattern_counts': {'":': 2, '<': 40, '<?xml version=': 0, '>': 40, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '402338', 'license': 'MIT', 'n_tokens_mistral': 3229, 'n_tokens_neox': 3037, 'n_words': 560, 'path': 'Deep Learning/emnist GPU keras to TF.ipynb', 'repo_name': 'evandrocapo/readForMe', 'size': '8573'}