<jupyter_start><jupyter_text>Libraries Used- Keras- Numpy- Train Test Split, Shuffle, Confusion Matrix from SKLEARN,- MatPlotLib for visualization,- Seaborn for background and confusion matrix visualization,- Pandas dataframes for confusion matrix,- CV2 to read images,- TQDM For proccess visualization,- Drive mount from Google Colab- OS to loop through folders<jupyter_code>from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix
from matplotlib import pyplot as plt
from sklearn.utils import shuffle
from google.colab import drive
from tensorflow import keras
from tqdm import tqdm
import seaborn as sns
import pandas as pd
import numpy as np
import cv2
import os

%matplotlib inline<jupyter_output><empty_output><jupyter_text>Reading Images1. Mount HackathonDataset from Google Drive2. Loop through each folder<jupyter_code>drive.mount("/content/drive/")
dir = "/content/drive/MyDrive/HackathonDataset"
# @return x_train, y_train
def load_data():
  images, labels, errors, names, j, bar = [], [], [], {}, 0, tqdm(total=21065, position=0)
  for label in os.listdir(dir):
    if os.path.isdir(os.path.join(dir, label)):
      for img in os.listdir(os.path.join(dir, label)):
        try:
          image = cv2.imread(os.path.join(dir, label, img), 0) # grayscale mode
          # image = cv2.resize(image, (28, 28)) # 48x48 -> 28x28
          images.append(image)
          labels.append(j)
        except:
          errors.append(img)
        bar.update(1)
      names[j] = f"{label}"
      j += 1
      
  bar.close()
  print()
  for err in errors:
    print(f"Error: {err}")
  for k, v in names.items():
    print(f"{k}: {v}")

  return np.array(images), np.array(labels)<jupyter_output><empty_output><jupyter_text>Preprocessing1. Reshape x_train as (len, 48*48) (flatten images)2. Divide every value by 2554. Split data into train, test, and validation (90%, 5%, 5%)5. Reshape images into 4D (len, 48, 48, 1) for convolutions6. Shuffle images and labels- @return x_train, x_test, x_val, y_train, y_test, y_val<jupyter_code>def preprocess(x_train, y_train):
  # scaler = MinMaxScaler()
  x_train = x_train.reshape(x_train.shape[0], 48 ** 2)
  y_train = keras.utils.to_categorical(y_train, num_classes=4)
  # x_train = scaler.fit_transform(x_train)
  x_train = x_train / 255
  x_train, x_test, y_train, y_test = train_test_split(x_train, y_train, test_size=0.1)
  x_test, x_val, y_test, y_val = train_test_split(x_test, y_test, test_size=0.5)
  # x_train, y_train = SMOTE().fit_resample(x_train, y_train)
  x_train = x_train.reshape(x_train.shape[0], 48, 48, 1)
  x_test = x_test.reshape(x_test.shape[0], 48, 48, 1)
  x_val = x_val.reshape(x_val.shape[0], 48, 48, 1)
  x_train, y_train = shuffle(x_train, y_train)
  x_test, y_test = shuffle(x_test, y_test)
  x_val, y_val = shuffle(x_val, y_val)
  return x_train, x_test, x_val, y_train, y_test, y_val<jupyter_output><empty_output><jupyter_text>Model Building<jupyter_code>def get_model():
  model = keras.Sequential([
                            keras.layers.InputLayer(input_shape=(48, 48, 1)),
                            keras.layers.Conv2D(64, (5, 5), padding='same', kernel_initializer='he_normal'),
                            keras.layers.MaxPool2D((2, 2), padding='same'),
                            keras.layers.Activation('relu'),
                            keras.layers.BatchNormalization(),
                            keras.layers.Dropout(0.35),

                            keras.layers.Conv2D(64, (5, 5), padding='same', kernel_initializer='he_normal'),
                            keras.layers.MaxPool2D((2, 2), padding='same'),
                            keras.layers.Activation('relu'),
                            keras.layers.BatchNormalization(),
                            keras.layers.Dropout(0.35),

                            keras.layers.Conv2D(128, (3, 3), padding='same', kernel_initializer='he_normal'),
                            keras.layers.MaxPool2D((2, 2), padding='same'),
                            keras.layers.Activation('relu'),
                            keras.layers.BatchNormalization(),
                            keras.layers.Dropout(0.35),

                            keras.layers.Conv2D(128, (3, 3), padding='same', kernel_initializer='he_normal'),
                            keras.layers.Activation('relu'),
                            keras.layers.BatchNormalization(),
                            keras.layers.Dropout(0.35),

                            keras.layers.Flatten(),

                            keras.layers.Dense(128, kernel_initializer='he_normal'),
                            keras.layers.Activation('relu'),
                            keras.layers.BatchNormalization(),
                            keras.layers.Dropout(0.35),

                            keras.layers.Dense(128, kernel_initializer='he_normal'),
                            keras.layers.Activation('relu'),
                            keras.layers.BatchNormalization(),
                            keras.layers.Dropout(0.35),

                            keras.layers.Dense(4),
                            keras.layers.Activation('softmax')
  ])

  model.compile(
      optimizer = 'adam',
      loss = 'categorical_crossentropy',
      metrics = ['accuracy']
    )
 
  return model<jupyter_output><empty_output><jupyter_text>Callbacks<jupyter_code>def get_callbacks():

  def decay(epoch):

    initial_lr = 0.1

    def exp_decay(x):
      return initial_lr * np.exp(-0.1 * x)

    def step_decay(x):
      start = exp_decay(5)
      k = 0.5
      epoch_k = 10
      return start * (k ** np.floor((x + 1) / epoch_k))
    
    if epoch <= 5:
      return exp_decay(epoch)
    elif epoch < 100:
      return step_decay(epoch)
    return 0.0125 / epoch

  optimization_manager = keras.callbacks.LearningRateScheduler(decay)
  # checkpoint_manager = keras.callbacks.ModelCheckpoint(
      # "model.h5",
      # monitor='val_loss',
      # verbose=0,
      # save_best_only=True,
      # )

  return [optimization_manager]<jupyter_output><empty_output><jupyter_text>Training<jupyter_code>x_train, x_test, x_val, y_train, y_test, y_val = preprocess(*load_data())
model = get_model()
model.summary()
history = model.fit(
    x_train,
    y_train,
    batch_size = 32,
    validation_data = (x_val, y_val),
    callbacks = get_callbacks(),
    epochs = 100
)
predictions = model.predict(x_test)
model.evaluate(x_test, y_test)
model.save("model.h5")
sns.set()
plt.yticks(np.arange(0, 1, 0.05))
plt.plot(history.history['val_accuracy'])
plt.plot(history.history['accuracy'])
plt.title("Accuracy")
plt.legend(["Validation", "Train"], loc='lower right')
plt.gca().set_ylim([0.7, 2])
plt.plot(history.history['val_loss'])
plt.plot(history.history['loss'])
plt.title("Loss")
plt.legend(["Validation", "Train"], loc='upper right')
matrix = confusion_matrix(
    [np.argmax(pred) for pred in y_test],
    [np.argmax(pred) for pred in predictions],
)

map = pd.DataFrame(
    matrix,
    ["angry", "happy", "neutral", "sad"],
    ["angry", "happy", "neutral", "sad"]
)

sns.heatmap(
    map,
    annot=True,
    fmt='g',
    vmin=np.min(matrix),
    vmax=np.max(matrix),
    cmap='magma_r'
)
plt.ylabel("Correct")
plt.xlabel("Predicted")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13012477718360071, 'fraction_numerical': 0.024132730015082957, 'mean_word_length': 2.6690140845070425, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 26, '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': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '567588', 'license': 'WTFPL', 'n_tokens_mistral': 2595, 'n_tokens_neox': 2437, 'n_words': 479, 'path': 'main.ipynb', 'repo_name': 'bbayazit16/SAC-Phoenix-2021-Winner', 'size': '7293'}