<jupyter_start><jupyter_text>Train AttractiveNeta deep learning approach to regress on facial attractivness<jupyter_code>import os
import numpy as np

import tensorflow as tf
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
from tensorflow.keras import Sequential, Model, Input
from tensorflow.keras.layers import Dense
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.utils import multi_gpu_model
from tensorflow.keras.models import load_model
import tensorflow.keras.backend as K

from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, mean_absolute_error

from alt_model_checkpoint.tensorflow import AltModelCheckpoint

import warnings
warnings.filterwarnings('ignore')

import helper
# manually reload single modules if needed
import importlib
importlib.reload(helper)
if tf.version.VERSION < '2.0':
    # TF1.X and older
    config = tf.ConfigProto()
    config.gpu_options.allow_growth = True
    config.log_device_placement = True
    sess = tf.Session(config=config)
    K.set_session(sess)
else:
    # TF2.X and newer
    config = tf.compat.v1.ConfigProto()
    config.gpu_options.allow_growth = True
    config.log_device_placement = True
    sess = tf.compat.v1.Session(config=config)
    tf.compat.v1.keras.backend.set_session(sess)<jupyter_output><empty_output><jupyter_text>DataDataset Project: https://github.com/HCIILAB/SCUT-FBP5500-Database-Release<jupyter_code>helper.download_data()
target_size = (350,350)
X,y = helper.create_dataset(target_size)
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.30, random_state=42)
X_val, X_test, y_val, y_test = train_test_split(X_val, y_val, test_size=1/3, random_state=42)
print(f'train shape: {X_train.shape}, {y_train.shape}\nval shape: {X_val.shape}, {y_val.shape}\ntest shape: {X_test.shape}, {y_test.shape}')
test_val_datagen = ImageDataGenerator()
train_datagen = ImageDataGenerator(horizontal_flip=True,
                                   rotation_range=40,
                                   width_shift_range=0.1,
                                   height_shift_range=0.1,
                                   shear_range=0.2,
                                   zoom_range=0.2,
                                  )
batch_size = 32

train_generator = train_datagen.flow(X_train, y_train, batch_size=batch_size)
val_generator = test_val_datagen.flow(X_val, y_val, batch_size=batch_size)
test_generator = test_val_datagen.flow(X_test, y_test, batch_size=batch_size, shuffle=False)<jupyter_output><empty_output><jupyter_text>Model<jupyter_code>model_name = 'attractiveNet_mnv2'
model_dir = 'models'

model_path= model_dir + '/' + model_name + '.h5'
if not os.path.isdir(model_dir): os.mkdir(model_dir)
basemodel = MobileNetV2(include_top=False, pooling='avg', weights='imagenet')
model = Sequential(name=model_name)
model.add(basemodel)
model.add(Dense(1))<jupyter_output><empty_output><jupyter_text>Training  Stage 1<jupyter_code>epochs = 30
lr=0.001
model.layers[0].trainable = False
model.compile(loss='mean_squared_error', optimizer=Adam(learning_rate=lr))
print(model.summary())

parallel_model = multi_gpu_model(model, gpus=4)
parallel_model.compile(loss='mean_squared_error', optimizer=Adam(learning_rate=lr))
callbacks = [
    EarlyStopping(
        monitor='val_loss',
        min_delta=1e-3,
        patience=7,
        verbose=1,
        ),
    AltModelCheckpoint(
        model_path,
        model,
        monitor='val_loss', 
        verbose=1, 
        save_best_only=True, 
        save_weights_only=False, 
        )
]
history1 = parallel_model.fit(
    train_generator,
    epochs=epochs,
    steps_per_epoch=len(y_train) // batch_size,
    validation_data=val_generator,
    verbose=1,
    callbacks = callbacks,
)
helper.plot_metrics(history1, model_name, 1)<jupyter_output><empty_output><jupyter_text>Stage 2<jupyter_code>epochs = 30
lr=0.0001
model = load_model(model_path)
model.trainable = True
model.compile(loss='mean_squared_error', optimizer=Adam(learning_rate=lr))
print(model.summary())

parallel_model = multi_gpu_model(model, gpus=4)
parallel_model.compile(loss='mean_squared_error', optimizer=Adam(learning_rate=lr))
callbacks = [
    EarlyStopping(
        monitor='val_loss',
        min_delta=1e-3,
        patience=7,
        verbose=1,
        ),
    AltModelCheckpoint(
        model_path,
        model,
        monitor='val_loss', 
        verbose=1, 
        save_best_only=True, 
        save_weights_only=False, 
        )
]
history2 = parallel_model.fit(
    train_generator,
    epochs=epochs,
    steps_per_epoch=len(y_train) // batch_size,
    validation_data=val_generator,
    verbose=1,
    callbacks = callbacks,
)
helper.plot_metrics(history2, model_name, 2)<jupyter_output><empty_output><jupyter_text>Test<jupyter_code>model = load_model(model_path)
prediction = model.predict_generator(test_generator)
RMSE = mean_squared_error(y_test, prediction, squared=False)
MAE = mean_absolute_error(y_test, prediction)
print(f'RMSE: {RMSE}, MAE: {MAE}')<jupyter_output>RMSE: 0.28585716016204066, MAE: 0.21198338088908802
{'fraction_non_alphanumeric': 0.1007427156732051, 'fraction_numerical': 0.02190059036374024, 'mean_word_length': 4.342828077314344, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 24, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '342217', 'license': 'MIT', 'n_tokens_mistral': 1874, 'n_tokens_neox': 1782, 'n_words': 286, 'path': 'train.ipynb', 'repo_name': 'alanwatts36/attractiveness', 'size': '5251'}