<jupyter_start><jupyter_text>**Baseline Model Development Notebook**  1. Initial Set-Up  1.1. GPU Set-UP<jupyter_code>%tensorflow_version 2.x

import tensorflow as tf
device_name = tf.test.gpu_device_name()
if device_name != '/device:GPU:0':
  raise SystemError('GPU device not found')
print('Found GPU at: {}'.format(device_name))<jupyter_output>Found GPU at: /device:GPU:0<jupyter_text>1.2. Create access to Google Drive<jupyter_code>from google.colab import drive
drive.mount('/content/drive')<jupyter_output>Mounted at /content/drive<jupyter_text>1.3. Import Libraries<jupyter_code>import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import h5py
import gc
import tensorflow as tf
from sklearn.model_selection import train_test_split
from keras_preprocessing.image import ImageDataGenerator
from keras import models
from keras import layers
from keras import optimizers
from keras import regularizers
from keras.callbacks import EarlyStopping
from keras.callbacks import ModelCheckpoint
from tensorflow.keras.models import Sequential
from tensorflow.keras import Model
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, Activation
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.callbacks import EarlyStopping
from keras.constraints import maxnorm
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.optimizers import RMSprop
from tensorflow.keras.models import load_model
from sklearn.metrics import confusion_matrix,classification_report<jupyter_output><empty_output><jupyter_text>1.4. Dataset Collection<jupyter_code>!7z x /content/drive/MyDrive/EDSA/images.7z<jupyter_output>7-Zip [64] 16.02 : Copyright (c) 1999-2016 <NAME> : 2016-05-21
p7zip Version 16.02 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,64 bits,2 CPUs Intel(R) Xeon(R) CPU @ 2.20GHz (406F0),ASM,AES-NI)

Scanning the drive for archives:
  0M Scan /content/drive/MyDrive/EDSA/                                      1 file, 4942431249 bytes (4714 MiB)

Extracting archive: /content/drive/MyDrive/EDSA/images.7z
--
Path = /content/drive/MyDrive/EDSA/images.7z
Type = 7z
Physical Size = 4942431249
Headers Size = 1206945
Method = LZMA2:24
Solid = +
Blocks = 3

  0%      0% 102 - images/apple_pie/1005649.jpg                                         0% 185 - images/apple_pie/1295996.jpg                                         0% 274 - images/apple_pie/1626685.jpg[...]<jupyter_text>1.4.1. Dataset Split - Train, Validation, Test<jupyter_code>!pip install split-folders
import splitfolders
splitfolders.ratio('/content/images', output="output", seed=1337, ratio=(.7, .2, .1))<jupyter_output>Collecting split-folders
  Downloading https://files.pythonhosted.org/packages/b8/5f/3c2b2f7ea5e047c8cdc3bb00ae582c5438fcdbbedcc23b3cc1c2c7aae642/split_folders-0.4.3-py3-none-any.whl
Installing collected packages: split-folders
Successfully installed split-folders-0.4.3<jupyter_text>2. Model Development For the baseline model the chosen approach consists in designing an initial simple model and successively add layers and configurations until reaching the highest accuracy possible. 
Everytime the results get worse, the changes are discarded.  2.1. Model 1 - Simple Model<jupyter_code>train_datagen = ImageDataGenerator(
                                  rescale = 1./255.)

valid_datagen = ImageDataGenerator(rescale = 1./255)


train_generator = train_datagen.flow_from_directory(directory="/content/output/train",
                                                    subset="training",
                                                    batch_size=64,
                                                    shuffle=True,
                                                    class_mode="categorical",
                                                    target_size=(64,64),
                                                    seed=42)



valid_generator=valid_datagen.flow_from_directory(directory="/content/output/val",
                                                  batch_size=64,
                                                  shuffle=True,
                                                  class_mode="categorical",
                                                  target_size=(64,64),
                                                  seed=42)


X_train, y_train = train_generator.next()
#Input Layer
baseline_model_1 = Sequential()

baseline_model_1.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='valid', input_shape=X_train.shape[1:]))
baseline_model_1.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

# MLP - layer:
baseline_model_1.add(Flatten())
# MLP - layer:
baseline_model_1.add(Dense(2048, activation='relu'))

# MLP - output layer:
baseline_model_1.add(Dense(y_train.shape[1], activation='softmax'))

# Check built model:
baseline_model_1.summary()
opt_1 = Adam()

baseline_model_1.compile(loss='categorical_crossentropy',
              optimizer=opt_1,
              metrics=['acc'])
X_val, y_val = valid_generator.next()
early_stop = EarlyStopping(patience=30, monitor='val_loss', mode='min', restore_best_weights=True)


history_baseline_model_1 = baseline_model_1.fit_generator(train_generator,
                              steps_per_epoch=160, #steps_per_epoch,
                              epochs=100,
                              validation_data=valid_generator,
                              validation_steps=10, #validation_steps,
                              callbacks=[early_stop],
                              shuffle= True
                             )

baseline_model_1.save('food_baseline_model_1.h5')<jupyter_output>/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1844: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  warnings.warn('`Model.fit_generator` is deprecated and '<jupyter_text>2.2. Model 2 - Additional Convolutional Layers When comparing to Model 1, one more convolutional layer and pooling layer were added. The added convolutional layer has 256 filters.<jupyter_code>train_datagen_2 = ImageDataGenerator(
                                  rescale = 1./255.)

valid_datagen_2 = ImageDataGenerator(rescale = 1./255)


train_generator_2 = train_datagen_2.flow_from_directory(directory="/content/output/train",
                                                    subset="training",
                                                    batch_size=64,
                                                    shuffle=True,
                                                    class_mode="categorical",
                                                    target_size=(64,64),
                                                    seed=42)



valid_generator_2 = valid_datagen_2.flow_from_directory(directory="/content/output/val",
                                                  batch_size=64,
                                                  shuffle=True,
                                                  class_mode="categorical",
                                                  target_size=(64,64),
                                                  seed=42)

X_train, y_train = train_generator_2.next()
#Input Layer
baseline_model_2 = Sequential()

baseline_model_2.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='valid', input_shape=X_train.shape[1:]))
baseline_model_2.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_2.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_2.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

# MLP - input layer:
baseline_model_2.add(Flatten())
# MLP - hidden layer:
baseline_model_2.add(Dense(2048, activation='relu'))


# MLP - output layer:
baseline_model_2.add(Dense(y_train.shape[1], activation='softmax'))

# Check built model:
baseline_model_2.summary()
opt_2 = Adam()

baseline_model_2.compile(loss='categorical_crossentropy',
              optimizer=opt_2,
              metrics=['acc'])
X_val, y_val = valid_generator_2.next()
early_stop = EarlyStopping(patience=30, monitor='val_loss', mode='min', restore_best_weights=True)


history_baseline_model_2 = baseline_model_2.fit_generator(train_generator_2,
                              steps_per_epoch=160, #steps_per_epoch,
                              epochs=100,
                              validation_data=valid_generator_2,
                              validation_steps=10, #validation_steps,
                              callbacks=[early_stop],
                              shuffle= True
                             )

baseline_model_2.save('food_baseline_model_2.h5')<jupyter_output>/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1844: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  warnings.warn('`Model.fit_generator` is deprecated and '<jupyter_text>2.3. Model 3 - Additional Convolutional Layers When comparing to Model 2, one more convolutional layer and pooling layer were added. The added convolutional layer has 512 filters.<jupyter_code>train_datagen_3 = ImageDataGenerator(
                                  rescale = 1./255.)

valid_datagen_3 = ImageDataGenerator(rescale = 1./255)


train_generator_3 = train_datagen_3.flow_from_directory(directory="/content/output/train",
                                                    subset="training",
                                                    batch_size=64,
                                                    shuffle=True,
                                                    class_mode="categorical",
                                                    target_size=(64,64),
                                                    seed=42)



valid_generator_3 = valid_datagen_3.flow_from_directory(directory="/content/output/val",
                                                  batch_size=64,
                                                  shuffle=True,
                                                  class_mode="categorical",
                                                  target_size=(64,64),
                                                  seed=42)
X_train, y_train = train_generator_3.next()
#Input Layer
baseline_model_3 = Sequential()

baseline_model_3.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='valid', input_shape=X_train.shape[1:]))
baseline_model_3.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_3.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_3.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_3.add(Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_3.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

# MLP - input layer:
baseline_model_3.add(Flatten())
# MLP - hidden layer:
baseline_model_3.add(Dense(2048, activation='relu'))


# MLP - output layer:
baseline_model_3.add(Dense(y_train.shape[1], activation='softmax'))

# Check built model:
baseline_model_3.summary()
opt_3 = Adam()

baseline_model_3.compile(loss='categorical_crossentropy',
              optimizer=opt_3,
              metrics=['acc'])
X_val, y_val = valid_generator_3.next()
early_stop = EarlyStopping(patience=30, monitor='val_loss', mode='min', restore_best_weights=True)


history_baseline_model_3 = baseline_model_3.fit_generator(train_generator_3,
                              steps_per_epoch=160, #steps_per_epoch,
                              epochs=100,
                              validation_data=valid_generator_3,
                              validation_steps=10, #validation_steps,
                              callbacks=[early_stop],
                              shuffle= True
                             )

baseline_model_3.save('food_baseline_model_3.h5')<jupyter_output>/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1844: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  warnings.warn('`Model.fit_generator` is deprecated and '<jupyter_text>2.4. Model 4 - Additional Convolutional Layers When comparing to Model 3, one more convolutional layer and pooling layer were added. The added convolutional layer has 1024 filters.<jupyter_code>train_datagen_4 = ImageDataGenerator(
                                  rescale = 1./255.)

valid_datagen_4 = ImageDataGenerator(rescale = 1./255)


train_generator_4 = train_datagen_4.flow_from_directory(directory="/content/output/train",
                                                    subset="training",
                                                    batch_size=64,
                                                    shuffle=True,
                                                    class_mode="categorical",
                                                    target_size=(64,64),
                                                    seed=42)



valid_generator_4 = valid_datagen_4.flow_from_directory(directory="/content/output/val",
                                                  batch_size=64,
                                                  shuffle=True,
                                                  class_mode="categorical",
                                                  target_size=(64,64),
                                                  seed=42)
X_train, y_train = train_generator_4.next()
#Input Layer
baseline_model_4 = Sequential()

baseline_model_4.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='valid', input_shape=X_train.shape[1:]))
baseline_model_4.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_4.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_4.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_4.add(Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_4.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_4.add(Conv2D(filters=1024, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_4.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

# MLP - input layer:
baseline_model_4.add(Flatten())
# MLP - hidden layer:
baseline_model_4.add(Dense(2048, activation='relu'))


# MLP - output layer:
baseline_model_4.add(Dense(y_train.shape[1], activation='softmax'))

# Check built model:
baseline_model_4.summary()
opt_4 = Adam()

baseline_model_4.compile(loss='categorical_crossentropy',
              optimizer=opt_4,
              metrics=['acc'])
X_val, y_val = valid_generator_4.next()
early_stop = EarlyStopping(patience=30, monitor='val_loss', mode='min', restore_best_weights=True)


history_baseline_model_4 = baseline_model_4.fit_generator(train_generator_4,
                              steps_per_epoch=160, #steps_per_epoch,
                              epochs=100,
                              validation_data=valid_generator_4,
                              validation_steps=10, #validation_steps,
                              callbacks=[early_stop],
                              shuffle= True
                             )

baseline_model_4.save('food_baseline_model_4.h5')<jupyter_output>/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1844: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  warnings.warn('`Model.fit_generator` is deprecated and '<jupyter_text>2.5. Model 5 - Additional Dense Layers When comparing to Model 4, one more dense layer was introduced.<jupyter_code>train_datagen_5 = ImageDataGenerator(
                                  rescale = 1./255.)

valid_datagen_5 = ImageDataGenerator(rescale = 1./255)


train_generator_5 = train_datagen_5.flow_from_directory(directory="/content/output/train",
                                                    subset="training",
                                                    batch_size=64,
                                                    shuffle=True,
                                                    class_mode="categorical",
                                                    target_size=(64,64),
                                                    seed=42)



valid_generator_5 = valid_datagen_5.flow_from_directory(directory="/content/output/val",
                                                  batch_size=64,
                                                  shuffle=True,
                                                  class_mode="categorical",
                                                  target_size=(64,64),
                                                  seed=42)
X_train, y_train = train_generator_5.next()
#Input Layer
baseline_model_5 = Sequential()

baseline_model_5.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='valid', input_shape=X_train.shape[1:]))
baseline_model_5.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_5.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_5.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_5.add(Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_5.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_5.add(Conv2D(filters=1024, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_5.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

# MLP - input layer:
baseline_model_5.add(Flatten())
# MLP - hidden layer:
baseline_model_5.add(Dense(2048, activation='relu'))
baseline_model_5.add(Dense(4096, activation='relu'))



# MLP - output layer:
baseline_model_5.add(Dense(y_train.shape[1], activation='softmax'))

# Check built model:
baseline_model_5.summary()
opt_5 = Adam()

baseline_model_5.compile(loss='categorical_crossentropy',
              optimizer=opt_5,
              metrics=['acc'])
X_val, y_val = valid_generator_5.next()
early_stop = EarlyStopping(patience=30, monitor='val_loss', mode='min', restore_best_weights=True)


history_baseline_model_5 = baseline_model_5.fit_generator(train_generator_5,
                              steps_per_epoch=160, #steps_per_epoch,
                              epochs=100,
                              validation_data=valid_generator_5,
                              validation_steps=10, #validation_steps,
                              callbacks=[early_stop],
                              shuffle= True
                             )

baseline_model_5.save('food_baseline_model_5.h5')<jupyter_output>/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1844: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  warnings.warn('`Model.fit_generator` is deprecated and '<jupyter_text>2.6. Model 6 - Additional Dense Layers When comparing to Model 5, one more dense layer was introduced.<jupyter_code>train_datagen_6 = ImageDataGenerator(
                                  rescale = 1./255.)

valid_datagen_6 = ImageDataGenerator(rescale = 1./255)


train_generator_6 = train_datagen_6.flow_from_directory(directory="/content/output/train",
                                                    subset="training",
                                                    batch_size=64,
                                                    shuffle=True,
                                                    class_mode="categorical",
                                                    target_size=(64,64),
                                                    seed=42)



valid_generator_6 = valid_datagen_6.flow_from_directory(directory="/content/output/val",
                                                  batch_size=64,
                                                  shuffle=True,
                                                  class_mode="categorical",
                                                  target_size=(64,64),
                                                  seed=42)
X_train, y_train = train_generator_6.next()
#Input Layer
baseline_model_6 = Sequential()

baseline_model_6.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='valid', input_shape=X_train.shape[1:]))
baseline_model_6.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_6.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_6.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_6.add(Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_6.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_6.add(Conv2D(filters=1024, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_6.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

# MLP - input layer:
baseline_model_6.add(Flatten())
# MLP - hidden layer:
baseline_model_6.add(Dense(2048, activation='relu'))
baseline_model_6.add(Dense(4096, activation='relu'))
baseline_model_6.add(Dense(4096, activation='relu'))



# MLP - output layer:
baseline_model_6.add(Dense(y_train.shape[1], activation='softmax'))

# Check built model:
baseline_model_6.summary()
opt_6 = Adam()

baseline_model_6.compile(loss='categorical_crossentropy',
              optimizer=opt_6,
              metrics=['acc'])
X_val, y_val = valid_generator_6.next()
early_stop = EarlyStopping(patience=30, monitor='val_loss', mode='min', restore_best_weights=True)


history_baseline_model_6 = baseline_model_6.fit_generator(train_generator_6,
                              steps_per_epoch=160, #steps_per_epoch,
                              epochs=100,
                              validation_data=valid_generator_6,
                              validation_steps=10, #validation_steps,
                              callbacks=[early_stop],
                              shuffle= True
                             )

baseline_model_6.save('food_baseline_model_6.h5')<jupyter_output>/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1844: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  warnings.warn('`Model.fit_generator` is deprecated and '<jupyter_text>2.7. Model 7 - Add Dropout Since the results did not improve, the added dense layers have been removed. In addition, the dropout feature was introduced to the dense layer to avoid overfitting.<jupyter_code>train_datagen_7 = ImageDataGenerator(
                                  rescale = 1./255.)

valid_datagen_7 = ImageDataGenerator(rescale = 1./255)


train_generator_7 = train_datagen_7.flow_from_directory(directory="/content/output/train",
                                                    subset="training",
                                                    batch_size=64,
                                                    shuffle=True,
                                                    class_mode="categorical",
                                                    target_size=(64,64),
                                                    seed=42)



valid_generator_7 = valid_datagen_7.flow_from_directory(directory="/content/output/val",
                                                  batch_size=64,
                                                  shuffle=True,
                                                  class_mode="categorical",
                                                  target_size=(64,64),
                                                  seed=42)
X_train, y_train = train_generator_7.next()
#Input Layer
baseline_model_7 = Sequential()

baseline_model_7.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='valid', input_shape=X_train.shape[1:]))
baseline_model_7.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_7.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_7.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_7.add(Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_7.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_7.add(Conv2D(filters=1024, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_7.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

# MLP - input layer:
baseline_model_7.add(Flatten())
# MLP - hidden layer:
baseline_model_7.add(Dense(2048, activation='relu'))
baseline_model_7.add(Dropout(0.2))



# MLP - output layer:
baseline_model_7.add(Dense(y_train.shape[1], activation='softmax'))

# Check built model:
baseline_model_7.summary()
opt_7 = Adam()

baseline_model_7.compile(loss='categorical_crossentropy',
              optimizer=opt_7,
              metrics=['acc'])
X_val, y_val = valid_generator_7.next()
early_stop = EarlyStopping(patience=30, monitor='val_loss', mode='min', restore_best_weights=True)


history_baseline_model_7 = baseline_model_7.fit_generator(train_generator_7,
                              steps_per_epoch=160, #steps_per_epoch,
                              epochs=100,
                              validation_data=valid_generator_7,
                              validation_steps=10, #validation_steps,
                              callbacks=[early_stop],
                              shuffle= True
                             )

baseline_model_7.save('food_baseline_model_7.h5')<jupyter_output>/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1844: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  warnings.warn('`Model.fit_generator` is deprecated and '<jupyter_text>2.8. Model 8 - Increase Dropout Rate When compared to Model 7, the dropout rate increased from 0.2 to 0.3.<jupyter_code>train_datagen_8 = ImageDataGenerator(
                                  rescale = 1./255.)

valid_datagen_8 = ImageDataGenerator(rescale = 1./255)


train_generator_8 = train_datagen_8.flow_from_directory(directory="/content/output/train",
                                                    subset="training",
                                                    batch_size=64,
                                                    shuffle=True,
                                                    class_mode="categorical",
                                                    target_size=(64,64),
                                                    seed=42)



valid_generator_8 = valid_datagen_8.flow_from_directory(directory="/content/output/val",
                                                  batch_size=64,
                                                  shuffle=True,
                                                  class_mode="categorical",
                                                  target_size=(64,64),
                                                  seed=42)
X_train, y_train = train_generator_8.next()
#Input Layer
baseline_model_8 = Sequential()

baseline_model_8.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='valid', input_shape=X_train.shape[1:]))
baseline_model_8.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_8.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_8.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_8.add(Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_8.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_8.add(Conv2D(filters=1024, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_8.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

# MLP - input layer:
baseline_model_8.add(Flatten())
# MLP - hidden layer:
baseline_model_8.add(Dense(2048, activation='relu'))
baseline_model_8.add(Dropout(0.3))


# MLP - output layer:
baseline_model_8.add(Dense(y_train.shape[1], activation='softmax'))

# Check built model:
baseline_model_8.summary()
opt_8 = Adam()

baseline_model_8.compile(loss='categorical_crossentropy',
              optimizer=opt_8,
              metrics=['acc'])
X_val, y_val = valid_generator_8.next()
early_stop = EarlyStopping(patience=30, monitor='val_loss', mode='min', restore_best_weights=True)


history_baseline_model_8 = baseline_model_8.fit_generator(train_generator_8,
                              steps_per_epoch=160, #steps_per_epoch,
                              epochs=100,
                              validation_data=valid_generator_8,
                              validation_steps=10, #validation_steps,
                              callbacks=[early_stop],
                              shuffle= True
                             )

baseline_model_8.save('food_baseline_model_8.h5')<jupyter_output>/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1844: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  warnings.warn('`Model.fit_generator` is deprecated and '<jupyter_text>2.9. Model 9 - Combine Kernel Constraint with Dropout Rate When compared to Model 8, the kernel constraint attribute was introduced to the Dense Layer<jupyter_code>train_datagen_9 = ImageDataGenerator(
                                  rescale = 1./255.)

valid_datagen_9 = ImageDataGenerator(rescale = 1./255)


train_generator_9 = train_datagen_9.flow_from_directory(directory="/content/output/train",
                                                    subset="training",
                                                    batch_size=64,
                                                    shuffle=True,
                                                    class_mode="categorical",
                                                    target_size=(64,64),
                                                    seed=42)



valid_generator_9 = valid_datagen_9.flow_from_directory(directory="/content/output/val",
                                                  batch_size=64,
                                                  shuffle=True,
                                                  class_mode="categorical",
                                                  target_size=(64,64),
                                                  seed=42)
X_train, y_train = train_generator_9.next()
#Input Layer
baseline_model_9 = Sequential()

baseline_model_9.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='valid', input_shape=X_train.shape[1:]))
baseline_model_9.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_9.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_9.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_9.add(Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_9.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_9.add(Conv2D(filters=1024, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_9.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

# MLP - input layer:
baseline_model_9.add(Flatten())
# MLP - hidden layer:
baseline_model_9.add(Dense(2048, activation='relu',kernel_constraint=maxnorm(3)))
baseline_model_9.add(Dropout(0.3))



# MLP - output layer:
baseline_model_9.add(Dense(y_train.shape[1], activation='softmax'))

# Check built model:
baseline_model_9.summary()
opt_9 = Adam()

baseline_model_9.compile(loss='categorical_crossentropy',
              optimizer=opt_9,
              metrics=['acc'])
X_val, y_val = valid_generator_9.next()
early_stop = EarlyStopping(patience=30, monitor='val_loss', mode='min', restore_best_weights=True)


history_baseline_model_9 = baseline_model_9.fit_generator(train_generator_9,
                              steps_per_epoch=160, #steps_per_epoch,
                              epochs=100,
                              validation_data=valid_generator_9,
                              validation_steps=10, #validation_steps,
                              callbacks=[early_stop],
                              shuffle= True
                             )

baseline_model_9.save('food_baseline_model_9.h5')<jupyter_output>/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1844: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  warnings.warn('`Model.fit_generator` is deprecated and '<jupyter_text>2.10. Model 10 - Include Learning Rate on Optimizer<jupyter_code>train_datagen_10 = ImageDataGenerator(
                                  rescale = 1./255.)

valid_datagen_10 = ImageDataGenerator(rescale = 1./255)


train_generator_10 = train_datagen_10.flow_from_directory(directory="/content/output/train",
                                                    subset="training",
                                                    batch_size=64,
                                                    shuffle=True,
                                                    class_mode="categorical",
                                                    target_size=(64,64),
                                                    seed=42)



valid_generator_10 = valid_datagen_10.flow_from_directory(directory="/content/output/val",
                                                  batch_size=64,
                                                  shuffle=True,
                                                  class_mode="categorical",
                                                  target_size=(64,64),
                                                  seed=42)
X_train, y_train = train_generator_10.next()
#Input Layer
baseline_model_10 = Sequential()

baseline_model_10.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='valid', input_shape=X_train.shape[1:]))
baseline_model_10.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_10.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_10.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_10.add(Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_10.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_10.add(Conv2D(filters=1024, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_10.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

# MLP - input layer:
baseline_model_10.add(Flatten())
# MLP - hidden layer:
baseline_model_10.add(Dense(2048, activation='relu',kernel_constraint=maxnorm(3)))
baseline_model_10.add(Dropout(0.3))



# MLP - output layer:
baseline_model_10.add(Dense(y_train.shape[1], activation='softmax'))

# Check built model:
baseline_model_10.summary()
opt_10 = Adam(lr=0.01)

baseline_model_10.compile(loss='categorical_crossentropy',
              optimizer=opt_10,
              metrics=['acc'])
X_val, y_val = valid_generator_10.next()
early_stop = EarlyStopping(patience=30, monitor='val_loss', mode='min', restore_best_weights=True)


history_baseline_model_10 = baseline_model_10.fit_generator(train_generator_10,
                              steps_per_epoch=160, #steps_per_epoch,
                              epochs=100,
                              validation_data=valid_generator_10,
                              validation_steps=10, #validation_steps,
                              callbacks=[early_stop],
                              shuffle= True
                             )

baseline_model_10.save('food_baseline_model_10.h5')<jupyter_output>/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1844: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  warnings.warn('`Model.fit_generator` is deprecated and '<jupyter_text>2.11. Model 11 - Change optimizer to RMSprop<jupyter_code>train_datagen_11 = ImageDataGenerator(
                                  rescale = 1./255.)

valid_datagen_11 = ImageDataGenerator(rescale = 1./255)


train_generator_11 = train_datagen_11.flow_from_directory(directory="/content/output/train",
                                                    subset="training",
                                                    batch_size=64,
                                                    shuffle=True,
                                                    class_mode="categorical",
                                                    target_size=(64,64),
                                                    seed=42)



valid_generator_11 = valid_datagen_11.flow_from_directory(directory="/content/output/val",
                                                  batch_size=64,
                                                  shuffle=True,
                                                  class_mode="categorical",
                                                  target_size=(64,64),
                                                  seed=42)
X_train, y_train = train_generator_11.next()
#Input Layer
baseline_model_11 = Sequential()

baseline_model_11.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='valid', input_shape=X_train.shape[1:]))
baseline_model_11.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_11.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_11.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_11.add(Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_11.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_11.add(Conv2D(filters=1024, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_11.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

# MLP - input layer:
baseline_model_11.add(Flatten())
# MLP - hidden layer:
baseline_model_11.add(Dense(2048, activation='relu',kernel_constraint=maxnorm(3)))
baseline_model_11.add(Dropout(0.3))



# MLP - output layer:
baseline_model_11.add(Dense(y_train.shape[1], activation='softmax'))

# Check built model:
baseline_model_11.summary()
opt_11 = RMSprop(lr=0.001)

baseline_model_11.compile(loss='categorical_crossentropy',
              optimizer=opt_11,
              metrics=['acc'])
X_val, y_val = valid_generator_11.next()
early_stop = EarlyStopping(patience=30, monitor='val_loss', mode='min', restore_best_weights=True)


history_baseline_model_11 = baseline_model_11.fit_generator(train_generator_11,
                              steps_per_epoch=160, #steps_per_epoch,
                              epochs=100,
                              validation_data=valid_generator_11,
                              validation_steps=10, #validation_steps,
                              callbacks=[early_stop],
                              shuffle= True
                             )

baseline_model_11.save('food_baseline_model_11.h5')<jupyter_output>/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1844: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  warnings.warn('`Model.fit_generator` is deprecated and '<jupyter_text>2.12. Model 12 - Increase Batch Size and Steps per epoch<jupyter_code>train_datagen_12 = ImageDataGenerator(
                                  rescale = 1./255.)

valid_datagen_12 = ImageDataGenerator(rescale = 1./255)


train_generator_12 = train_datagen_12.flow_from_directory(directory="/content/output/train",
                                                    subset="training",
                                                    batch_size=128,
                                                    shuffle=True,
                                                    class_mode="categorical",
                                                    target_size=(64,64),
                                                    seed=42)



valid_generator_12 = valid_datagen_12.flow_from_directory(directory="/content/output/val",
                                                  batch_size=128,
                                                  shuffle=True,
                                                  class_mode="categorical",
                                                  target_size=(64,64),
                                                  seed=42)
X_train, y_train = train_generator_12.next()
#Input Layer
baseline_model_12 = Sequential()

baseline_model_12.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='valid', input_shape=X_train.shape[1:]))
baseline_model_12.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_12.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_12.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_12.add(Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_12.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_12.add(Conv2D(filters=1024, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_12.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

# MLP - input layer:
baseline_model_12.add(Flatten())
# MLP - hidden layer:
baseline_model_12.add(Dense(2048, activation='relu',kernel_constraint=maxnorm(3)))
baseline_model_12.add(Dropout(0.3))



# MLP - output layer:
baseline_model_12.add(Dense(y_train.shape[1], activation='softmax'))

# Check built model:
baseline_model_12.summary()
opt_12 = RMSprop(lr=0.001)

baseline_model_12.compile(loss='categorical_crossentropy',
              optimizer=opt_12,
              metrics=['acc'])
X_val, y_val = valid_generator_12.next()
early_stop = EarlyStopping(patience=30, monitor='val_loss', mode='min', restore_best_weights=True)


history_baseline_model_12 = baseline_model_12.fit_generator(train_generator_12,
                              steps_per_epoch=320, #steps_per_epoch,
                              epochs=100,
                              validation_data=valid_generator_12,
                              validation_steps=32, #validation_steps,
                              callbacks=[early_stop],
                              shuffle= True
                             )

baseline_model_12.save('food_baseline_model_12.h5')<jupyter_output>/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1844: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  warnings.warn('`Model.fit_generator` is deprecated and '<jupyter_text>2.13. Model 13 - Change padding to 'same'<jupyter_code>train_datagen_13 = ImageDataGenerator(
                                  rescale = 1./255.)

valid_datagen_13 = ImageDataGenerator(rescale = 1./255)


train_generator_13 = train_datagen_13.flow_from_directory(directory="/content/output/train",
                                                    subset="training",
                                                    batch_size=128,
                                                    shuffle=True,
                                                    class_mode="categorical",
                                                    target_size=(64,64),
                                                    seed=42)



valid_generator_13 = valid_datagen_13.flow_from_directory(directory="/content/output/val",
                                                  batch_size=128,
                                                  shuffle=True,
                                                  class_mode="categorical",
                                                  target_size=(64,64),
                                                  seed=42)
X_train, y_train = train_generator_13.next()
#Input Layer
baseline_model_13 = Sequential()

baseline_model_13.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='same', input_shape=X_train.shape[1:]))
baseline_model_13.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_13.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='same'))
baseline_model_13.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_13.add(Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='same'))
baseline_model_13.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_13.add(Conv2D(filters=1024, kernel_size=(3, 3), activation='relu', padding='same'))
baseline_model_13.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

# MLP - input layer:
baseline_model_13.add(Flatten())
# MLP - hidden layer:
baseline_model_13.add(Dense(2048, activation='relu',kernel_constraint=maxnorm(3)))
baseline_model_13.add(Dropout(0.3))



# MLP - output layer:
baseline_model_13.add(Dense(y_train.shape[1], activation='softmax'))

# Check built model:
baseline_model_13.summary()
opt_13 = RMSprop(lr=0.001)

baseline_model_13.compile(loss='categorical_crossentropy',
              optimizer=opt_13,
              metrics=['acc'])
X_val, y_val = valid_generator_13.next()
early_stop = EarlyStopping(patience=30, monitor='val_loss', mode='min', restore_best_weights=True)


history_baseline_model_13 = baseline_model_13.fit_generator(train_generator_13,
                              steps_per_epoch=320, #steps_per_epoch,
                              epochs=100,
                              validation_data=valid_generator_13,
                              validation_steps=32, #validation_steps,
                              callbacks=[early_stop],
                              shuffle= True
                             )

baseline_model_13.save('food_baseline_model_13.h5')<jupyter_output>/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1844: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  warnings.warn('`Model.fit_generator` is deprecated and '<jupyter_text>2.14. Model 14 - Include Data Augmentation techniques Several Data Augmentation techniques were applied to the model. However, all of them presented worse results.<jupyter_code>train_datagen_14 = ImageDataGenerator(samplewise_center = True,
                                  samplewise_std_normalization = True,
                                  rescale = 1./255.)

valid_datagen_14 = ImageDataGenerator(rescale = 1./255)


train_generator_14 = train_datagen_14.flow_from_directory(directory="/content/output/train",
                                                    subset="training",
                                                    batch_size=128,
                                                    shuffle=True,
                                                    class_mode="categorical",
                                                    target_size=(64,64),
                                                    seed=42)



valid_generator_14 = valid_datagen_14.flow_from_directory(directory="/content/output/val",
                                                  batch_size=128,
                                                  shuffle=True,
                                                  class_mode="categorical",
                                                  target_size=(64,64),
                                                  seed=42)
X_train, y_train = train_generator_14.next()
#Input Layer
baseline_model_14 = Sequential()

baseline_model_14.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='valid', input_shape=X_train.shape[1:]))
baseline_model_14.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_14.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_14.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_14.add(Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_14.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_14.add(Conv2D(filters=1024, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_14.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

# MLP - input layer:
baseline_model_14.add(Flatten())
# MLP - hidden layer:
baseline_model_14.add(Dense(2048, activation='relu',kernel_constraint=maxnorm(3)))
baseline_model_14.add(Dropout(0.3))



# MLP - output layer:
baseline_model_14.add(Dense(y_train.shape[1], activation='softmax'))

# Check built model:
baseline_model_14.summary()
opt_14 = RMSprop(lr=0.001)

baseline_model_14.compile(loss='categorical_crossentropy',
              optimizer=opt_14,
              metrics=['acc'])
X_val, y_val = valid_generator_14.next()
early_stop = EarlyStopping(patience=30, monitor='val_loss', mode='min', restore_best_weights=True)


history_baseline_model_14 = baseline_model_14.fit_generator(train_generator_14,
                              steps_per_epoch=320, #steps_per_epoch,
                              epochs=100,
                              validation_data=valid_generator_14,
                              validation_steps=32, #validation_steps,
                              callbacks=[early_stop],
                              shuffle= True
                             )

baseline_model_14.save('food_baseline_model_14.h5')<jupyter_output>/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1844: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  warnings.warn('`Model.fit_generator` is deprecated and '<jupyter_text>2.15. Model 15 - Additional  Data Augmentation techniques
 Several Data Augmentation techniques were applied to the model. However, all of them presented worse results.<jupyter_code>train_datagen_15 = ImageDataGenerator(samplewise_center = True,
                                  samplewise_std_normalization = True,
                                  rescale = 1./255.,rotation_range = 40, width_shift_range = 0.2, height_shift_range = 0.2, shear_range = 0.2, zoom_range = 0.2, horizontal_flip = True)

valid_datagen_15 = ImageDataGenerator(rescale = 1./255)


train_generator_15 = train_datagen_15.flow_from_directory(directory="/content/output/train",
                                                    subset="training",
                                                    batch_size=128,
                                                    shuffle=True,
                                                    class_mode="categorical",
                                                    target_size=(64,64),
                                                    seed=42)



valid_generator_15 = valid_datagen_15.flow_from_directory(directory="/content/output/val",
                                                  batch_size=128,
                                                  shuffle=True,
                                                  class_mode="categorical",
                                                  target_size=(64,64),
                                                  seed=42)
X_train, y_train = train_generator_15.next()
#Input Layer
baseline_model_15 = Sequential()

baseline_model_15.add(Conv2D(filters=128, kernel_size=(3, 3), activation='relu', padding='valid', input_shape=X_train.shape[1:]))
baseline_model_15.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_15.add(Conv2D(filters=256, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_15.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_15.add(Conv2D(filters=512, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_15.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

baseline_model_15.add(Conv2D(filters=1024, kernel_size=(3, 3), activation='relu', padding='valid'))
baseline_model_15.add(MaxPooling2D(pool_size=(2, 2), strides=(2,2)))

# MLP - input layer:
baseline_model_15.add(Flatten())
# MLP - hidden layer:
baseline_model_15.add(Dense(2048, activation='relu',kernel_constraint=maxnorm(3)))
baseline_model_15.add(Dropout(0.3))



# MLP - output layer:
baseline_model_15.add(Dense(y_train.shape[1], activation='softmax'))

# Check built model:
baseline_model_15.summary()
opt_15 = RMSprop(lr=0.001)

baseline_model_15.compile(loss='categorical_crossentropy',
              optimizer=opt_15,
              metrics=['acc'])
X_val, y_val = valid_generator_15.next()
early_stop = EarlyStopping(patience=30, monitor='val_loss', mode='min', restore_best_weights=True)


history_baseline_model_15 = baseline_model_15.fit_generator(train_generator_15,
                              steps_per_epoch=320, #steps_per_epoch,
                              epochs=100,
                              validation_data=valid_generator_15,
                              validation_steps=32, #validation_steps,
                              callbacks=[early_stop],
                              shuffle= True
                             )

baseline_model_15.save('food_baseline_model_15.h5')<jupyter_output>/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1844: UserWarning: `Model.fit_generator` is deprecated and will be removed in a future version. Please use `Model.fit`, which supports generators.
  warnings.warn('`Model.fit_generator` is deprecated and '<jupyter_text>3. Evaluating the best Baseline Model  3.1. Model 12<jupyter_code>test_datagen = ImageDataGenerator(rescale = 1./255)
test_generator=test_datagen.flow_from_directory(directory="/content/output/test/", 
                                                  batch_size=64,
                                                  shuffle=False, #Shuffle was changed to false in order to ensure that the images were predicted in the correct order
                                                  class_mode="categorical",
                                                  target_size=(64,64),
                                                  seed=42)

test_dir = "/content/output/test/"
#Load the best model 
Best_Model = load_model('/content/drive/MyDrive/EDSA/food_baseline_model_12.h5')
#https://stackoverflow.com/questions/53929819/generating-confusion-matrix-in-keras-for-multiclass-classification


predictions = Best_Model.predict_generator(test_generator)

y_pred = np.argmax(predictions, axis=1)

true_classes = test_generator.classes

class_labels = list(test_generator.class_indices.keys())   

print(class_labels)

print(confusion_matrix(test_generator.classes, y_pred))

report = classification_report(true_classes, y_pred, target_names=class_labels)
print(report)<jupyter_output>/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:1905: UserWarning: `Model.predict_generator` is deprecated and will be removed in a future version. Please use `Model.predict`, which supports generators.
  warnings.warn('`Model.predict_generator` is deprecated and '
{'fraction_non_alphanumeric': 0.10605554285312274, 'fraction_numerical': 0.040593066816750796, 'mean_word_length': 2.115677571373774, 'pattern_counts': {'":': 0, '<': 66, '<?xml version=': 0, '>': 66, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 363, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '21', 'dir': 'jupyter-structured-clean-dedup', 'id': '93337', 'license': 'MIT', 'n_tokens_mistral': 17536, 'n_tokens_neox': 15754, 'n_words': 2498, 'path': 'Baseline_Model_Development.ipynb', 'repo_name': 'MPCaiado/DLNN-Food-101', 'size': '56862'}