<jupyter_start><jupyter_text>facial keypoints detector<jupyter_code>%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from os import path as opath
import os
import sys
import seaborn as sns
from PIL import Image
import errno
sns.set(style="whitegrid", color_codes=True)

# add utils into PYTHONPATH
module_path = os.path.abspath(os.path.join('..'))
if module_path not in sys.path:
    sys.path.append(module_path)
    
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import ModelCheckpoint

from utils import get_batches, get_accuracy
# ENV settings
DATA_PATH = 'data/'
MODEL_PATH = 'models/'
%mkdir -p $MODEL_PATH

TRAIN_PATH = opath.join(DATA_PATH, 'train')
TEST_PATH = opath.join(DATA_PATH, 'test')
VALID_PATH = opath.join(DATA_PATH, 'valid')<jupyter_output><empty_output><jupyter_text>Downloading data<jupyter_code>%mkdir -p $DATA_PATH
%pwd
%cd $DATA_PATH
%pwd
!kg download -c facial-keypoints-detector
%ls
%cd ..
%pwd<jupyter_output>/home/ansible/workspace/kaggle_fun/facial_keypoints_detector/data
downloading https://www.kaggle.com/c/facial-keypoints-detector/download/train.csv

train.csv 100% |#####################################| Time: 0:00:01  20.0 MiB/s

downloading https://www.kaggle.com/c/facial-keypoints-detector/download/test.csv

test.csv 100% |######################################| Time: 0:00:00  13.6 MiB/s

downloading https://www.kaggle.com/c/facial-keypoints-detector/download/train_identity.csv

train_identity.csv 100% |############################| Time: 0:00:00  62.8 KiB/s

test.csv  train.csv  train_identity.csv
/home/ansible/workspace/kaggle_fun/facial_keypoints_detector<jupyter_text>Preprocess data<jupyter_code>def convert_pixels(pix_str):
    return np.array([int(p) for p in pix_str.split(' ')], 'uint8').reshape((48, 48))


def load_data():
    df = pd.read_csv(opath.join(DATA_PATH, 'train.csv'), converters={'Pixels': convert_pixels})
    return df

data = load_data()
def decode_label(df):
    df = df.copy()
    df.loc[df['Emotion'] == 0, 'Emotion'] = 'anger'
    df.loc[df['Emotion'] == 1, 'Emotion'] = 'disgust'
    df.loc[df['Emotion'] == 2, 'Emotion'] = 'fear'
    df.loc[df['Emotion'] == 3, 'Emotion'] = 'happy'
    df.loc[df['Emotion'] == 4, 'Emotion'] = 'sad'
    df.loc[df['Emotion'] == 5, 'Emotion'] = 'surprise'
    df.loc[df['Emotion'] == 6, 'Emotion'] = 'neutral'
    return df
decoded_data = decode_label(data)
remove_neutral_data = decoded_data[decoded_data['Emotion'] == 'neutral'].sample(700)
remove_happy_data = decoded_data[decoded_data['Emotion'] == 'happy'].sample(300)
transformed_data = decoded_data.drop((remove_happy_data+remove_neutral_data).index)
test_data = transformed_data.sample(frac=0.1)
transformed_data = transformed_data.drop(test_data.index)
valid_data = transformed_data.sample(frac=0.2)
train_data = transformed_data.drop(valid_data.index)
def mkdir(path):
    try:
        os.makedirs(path)
    except OSError as exception:
        if exception.errno != errno.EEXIST:
            raise
            
            
def save_img_files(df, base):
    sub_path = opath.join(DATA_PATH, base)
    for idx, row in df.iterrows():
        category_path = opath.join(sub_path, row['Emotion'])
        mkdir(category_path)
        Image.fromarray(row['Pixels']).save(opath.join(category_path, '{}.png'.format(idx)), 'png')
save_img_files(test_data, 'test')
save_img_files(valid_data, 'valid')
save_img_files(train_data, 'train')<jupyter_output><empty_output><jupyter_text>Vanilla model<jupyter_code>def get_bench_model():
    model = Sequential()
    model.add(Conv2D(16, 3, activation='relu', padding='same', input_shape=(3, 48, 48)))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    model.add(Conv2D(32, 3, activation='relu', padding='same',))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    model.add(Conv2D(64, 3, activation='relu', padding='same',))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    model.add(Flatten())
    model.add(Dropout(0.5))
    model.add(Dense(7, activation='softmax'))
    return model

bench_model = get_bench_model()
bench_model.summary()
bench_model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
train_datagen = ImageDataGenerator(rescale=1./255, rotation_range=90)
valid_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator()
batch_size = 32
bench_weights_path = opath.join(MODEL_PATH, 'bench.weights.best.hdf5')

checkpointer = ModelCheckpoint(filepath=bench_weights_path, verbose=1, save_best_only=True)

train_batches = get_batches(TRAIN_PATH, train_datagen, (48, 48))
valid_batches = get_batches(VALID_PATH, valid_datagen, (48, 48))

bench_model.fit_generator(train_batches, steps_per_epoch=train_batches.samples//batch_size, 
                          validation_data=valid_batches, validation_steps=valid_batches.samples//batch_size,
                          callbacks=[checkpointer],  epochs=30)

bench_model.load_weights(bench_weights_path)
test_batches = get_batches(TEST_PATH, test_datagen, (48, 48))

print "benchmark model get accuary {}%".format(get_accuracy(bench_model, test_batches))<jupyter_output>Found 318 images belonging to 7 classes.
benchmark model get accuary 0.487421383835%<jupyter_text>VGG16 finetune  top layer<jupyter_code>from utils.vgg16 import get_model
vgg_model = get_model()

vgg_model.pop()
for layer in vgg_model.layers:
    layer.trainable = False

vgg_model.add(Dense(7, activation='softmax'))

vgg_model.summary()
vgg_model.compile(optimizer='RMSprop', loss='categorical_crossentropy', metrics=['accuracy'])
train_datagen = ImageDataGenerator()
valid_datagen = ImageDataGenerator()
test_datagen = ImageDataGenerator()
top_weights_path = opath.join(MODEL_PATH, 'vgg_tune_top.weights.best.hdf5')
checkpointer = ModelCheckpoint(filepath=top_weights_path, verbose=1, save_best_only=True)

train_batches = get_batches(TRAIN_PATH, train_datagen)
valid_batches = get_batches(VALID_PATH, valid_datagen)

vgg_model.fit_generator(train_batches, steps_per_epoch=train_batches.samples//train_batches.batch_size,
                          validation_data=valid_batches, validation_steps=valid_batches.samples//valid_batches.batch_size,
                          callbacks=[checkpointer],  epochs=20, verbose=1)

vgg_model.load_weights(top_weights_path)
test_batches = get_batches(TEST_PATH, test_datagen, (224, 224))

print "vgg16 model finetune top layer get accuary {}%".format(get_accuracy(vgg_model, test_batches))<jupyter_output>Found 318 images belonging to 7 classes.
vgg16 model finetune top layer get accuary 0.619496855908%<jupyter_text>all dense layer<jupyter_code>for idx, layer in enumerate(vgg_model.layers):
    print idx, layer.name
for layer in vgg_model.layers[:33]:
    layer.trainable = False
for layer in vgg_model.layers[33:]:
    layer.trainable = True
from keras.optimizers import Adam, SGD
optmizer = SGD(0.001, 0.9, 0.0001, True)
vgg_model.compile(optimizer=optmizer, loss='categorical_crossentropy', metrics=['accuracy'])
dense_weights_path = opath.join(MODEL_PATH, 'vgg_tune_dense.weights.best.hdf5')
checkpointer = ModelCheckpoint(filepath=dense_weights_path, verbose=1, save_best_only=True)

train_batches = get_batches(TRAIN_PATH, train_datagen)
valid_batches = get_batches(VALID_PATH, valid_datagen)

vgg_model.fit_generator(train_batches, steps_per_epoch=train_batches.samples//train_batches.batch_size,
                          validation_data=valid_batches, validation_steps=valid_batches.samples//valid_batches.batch_size,
                          callbacks=[checkpointer],  epochs=5, verbose=1)

vgg_model.load_weights(dense_weights_path)
test_batches = get_batches(TEST_PATH, test_datagen, (224, 224))

print "vgg16 model finetune dense layer get accuary {}%".format(get_accuracy(vgg_model, test_batches))<jupyter_output>Found 318 images belonging to 7 classes.
vgg16 model finetune dense layer get accuary 0.751572325545%<jupyter_text>tune conv<jupyter_code>for layer in vgg_model.layers[:25]:
    layer.trainable = False
for layer in vgg_model.layers[25:]:
    layer.trainable = True

optmizer = SGD(0.0001, 0.9, 0.00001, True)
vgg_model.compile(optimizer=optmizer, loss='categorical_crossentropy', metrics=['accuracy'])
conv_weights_path = opath.join(MODEL_PATH, 'vgg_tune_conv.weights.best.hdf5')
checkpointer = ModelCheckpoint(filepath=conv_weights_path, verbose=1, save_best_only=True)

train_batches = get_batches(TRAIN_PATH, train_datagen)
valid_batches = get_batches(VALID_PATH, valid_datagen)

vgg_model.fit_generator(train_batches, steps_per_epoch=train_batches.samples//train_batches.batch_size,
                          validation_data=valid_batches, validation_steps=valid_batches.samples//valid_batches.batch_size,
                          callbacks=[checkpointer],  epochs=5, verbose=1)
vgg_model.load_weights(conv_weights_path)
test_batches = get_batches(TEST_PATH, test_datagen, (224, 224))

print "vgg16 model finetune conv layer get accuary {}%".format(get_accuracy(vgg_model, test_batches))<jupyter_output>Found 318 images belonging to 7 classes.
vgg16 model finetune conv layer get accuary 0.779874212337%
{'fraction_non_alphanumeric': 0.13037388212477105, 'fraction_numerical': 0.02887619868548648, 'mean_word_length': 5.780131482834186, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 24, 'https://': 3, 'lorem ipsum': 0, 'www.': 3, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '192310', 'license': 'MIT', 'n_tokens_mistral': 3481, 'n_tokens_neox': 3271, 'n_words': 574, 'path': 'facial_keypoints_detector/main.ipynb', 'repo_name': 'zeroohub/kaggle_fun', 'size': '9281'}