weights.077-0.2208.hdf5 138/138 [==============================] - 431s - loss: 0.1374 - acc: 0.9874 - val_loss: 0.2208 - val_acc: 0.9326

In [1]:
import os, random, glob, pickle, collections, math, json, time
import numpy as np
import pandas as pd
from __future__ import division
from __future__ import print_function
from PIL import Image
from sklearn.model_selection import train_test_split
from sklearn.metrics import log_loss
from sklearn.preprocessing import LabelEncoder

import matplotlib.pyplot as plt
%matplotlib inline 

from keras.models import Sequential, Model, load_model
from keras.layers import GlobalAveragePooling2D, Flatten, Dropout, Dense, LeakyReLU
from keras.optimizers import Adam
from keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau, TensorBoard
from keras.preprocessing.image import ImageDataGenerator
from keras.utils import np_utils
from keras.preprocessing import image
from keras import backend as K
K.set_image_dim_ordering('tf')


Using TensorFlow backend.

In [144]:
TEST_DIR = '../RFCN/JPEGImages/'
RFCN_MODEL = 'resnet101_rfcn_ohem_iter_30000'
CROP_MODEL = 'resnet50_FT38_Hybrid_wNoF'
if os.getcwd().split('/')[-1] != CROP_MODEL:
    print('WRONG CROP_MODEL DIR!!!')
CHECKPOINT_DIR = './checkpoint/'
if not os.path.exists(CHECKPOINT_DIR):
    os.mkdir(CHECKPOINT_DIR)
LOG_DIR = './log/'
if not os.path.exists(LOG_DIR):
    os.mkdir(LOG_DIR)
OUTPUT_DIR = './output/'
if not os.path.exists(OUTPUT_DIR):
    os.mkdir(OUTPUT_DIR)
FISH_CLASSES = ['NoF', 'ALB', 'BET', 'DOL', 'LAG', 'OTHER', 'SHARK', 'YFT']
CONF_THRESH = 0.8
ROWS = 224
COLS = 224
BATCHSIZE = 128
LEARNINGRATE = 1e-4

def featurewise_center(x):
    mean = np.mean(x, axis=0, keepdims=True)
    mean = np.mean(mean, axis=(1,2), keepdims=True)
    x_centered = x - mean
    return x_centered    

def featurewise_mean(x):
    mean = np.mean(x, axis=0)
    mean = np.mean(mean, axis=(0,1))
    return mean

def preprocess_featurewise(x, featurewise_mean):
#     resnet50 image preprocessing
#     'RGB'->'BGR'
    x = x[:, :, ::-1]
    x -= np.reshape(featurewise_mean, [1, 1, 3])
    return x

def load_img(path, bbox, target_size=None):
    img = Image.open(path)
#     img = img.convert('RGB')
    cropped = img.crop((bbox[0],bbox[1],bbox[2],bbox[3]))
    width_cropped, height_cropped = cropped.size
    if height_cropped > width_cropped: cropped = cropped.transpose(method=2)
    image_name = 'temp_{:f}.jpg'.format(time.time())
    cropped.save(image_name)
    cropped = Image.open(image_name)   
    if target_size:
        cropped = cropped.resize((target_size[1], target_size[0]), Image.BILINEAR)
    os.remove(image_name)
    return cropped

def get_best_model(checkpoint_dir = CHECKPOINT_DIR):
    files = glob.glob(checkpoint_dir+'*')
    val_losses = [float(f.split('-')[-1][:-5]) for f in files]
    index = val_losses.index(min(val_losses))
    print('Loading model from checkpoint file ' + files[index])
    model = load_model(files[index])
    model_name = files[index].split('/')[-1]
    print('Loading model Done!')
    return (model, model_name)

def data_from_df(df):
    X = np.ndarray((df.shape[0], ROWS, COLS, 3), dtype=np.uint8)
    y = np.zeros((df.shape[0], len(FISH_CLASSES)), dtype=K.floatx())
    i = 0
    for index,row in df.iterrows():
        image_file = row['image_file']
        fish = row['crop_class']
        bbox = [row['xmin'],row['ymin'],row['xmax'],row['ymax']]
        cropped = load_img(TEST_DIR+image_file,bbox,target_size=(ROWS,COLS))
        X[i] = np.asarray(cropped)
        y[i,FISH_CLASSES.index(fish)] = 1
        i += 1
    return (X, y)

def data_load(name):
    file_name = 'data_'+name+'_{}_{}.pickle'.format(ROWS, COLS)
    if os.path.exists(OUTPUT_DIR+file_name):
        print ('Loading from file '+file_name)
        with open(OUTPUT_DIR+file_name, 'rb') as f:
            data = pickle.load(f)
        X = data['X']
        y = data['y']
    else:
        print ('Generating file '+file_name)
        
        if name=='train' or name=='valid': 
            df = GTbbox_df[GTbbox_df['split']==name]
        elif name=='all':
            df = GTbbox_df
        else:
            print('Invalid name '+name)
    
        X, y = data_from_df(df)

        data = {'X': X,'y': y}
        with open(OUTPUT_DIR+file_name, 'wb') as f:
            pickle.dump(data, f)
    X = X.astype(np.float32)
    X /= 255.
    return (X, y)

In [136]:
# GTbbox_df = ['image_file','image_class','crop_index','crop_class','xmin',''ymin','xmax','ymax','split']

file_name = 'GTbbox_df.pickle'
if os.path.exists(OUTPUT_DIR+file_name):
    print ('Loading from file '+file_name)
    GTbbox_df = pd.read_pickle(OUTPUT_DIR+file_name)
else:
    print ('Generating file '+file_name)       
    GTbbox_df = pd.DataFrame(columns=['image_file','image_class','crop_index','crop_class','xmin','ymin','xmax','ymax'])  

    crop_classes=FISH_CLASSES[:]
    crop_classes.remove('NoF')
    with open("../RFCN/ImageSets/Main/train_test.txt","r") as f:
        train_file_labels = f.readlines()
        
    for c in crop_classes:
        print(c)
        j = json.load(open('../data/BBannotations/{}.json'.format(c), 'r'))
        for l in j: 
            filename = l["filename"]
            head, image_file = os.path.split(filename)
            basename, file_extension = os.path.splitext(image_file)
            for i in range(len(train_file_labels)):
                if train_file_labels[i][:9] == basename:
                    image_class = train_file_labels[i][10:-1]
                    break
            image = Image.open(TEST_DIR+'/'+image_file)
            width_image, height_image = image.size
            for i in range(len(l["annotations"])):
                a = l["annotations"][i]
                xmin = (a["x"])
                ymin = (a["y"])
                width = (a["width"])
                height = (a["height"])
                xmax = xmin + width
                ymax = ymin + height
                assert max(xmin,0)<min(xmax,width_image)
                assert max(ymin,0)<min(ymax,height_image)
                GTbbox_df.loc[len(GTbbox_df)]=[image_file,image_class,i,a["class"],max(xmin,0),max(ymin,0),min(xmax,width_image),min(ymax,height_image)] 
        
    print('NoF')  
    num_NoF = GTbbox_df.shape[0]*3
    RFCN_MODEL = 'resnet101_rfcn_ohem_iter_30000'
    with open('../data/RFCN_detections/detections_full_AGNOSTICnms_'+RFCN_MODEL+'.pkl','rb') as f:
        detections_full_AGNOSTICnms = pickle.load(f) 
    train_detections_full_AGNOSTICnms = detections_full_AGNOSTICnms[1000:]
    with open("../RFCN/ImageSets/Main/test.txt","r") as f:
        test_files = f.readlines()
    train_files = test_files[1000:]
    num_NoF_perIm = int(math.ceil(num_NoF / len(train_detections_full_AGNOSTICnms)))

    for im in range(len(train_files)):
        image_file = train_files[im][:9]+'.jpg'
        for i in range(len(train_file_labels)):
            if train_file_labels[i][:9] == train_files[im][:9]:
                image_class = train_file_labels[i][10:-1]
                break
        image = Image.open(TEST_DIR+image_file)
        width_image, height_image = image.size
        detects_im = train_detections_full_AGNOSTICnms[im]
        detects_im = detects_im[np.where(detects_im[:,4] >= 0.999)]
        np.random.seed(1986)
        bboxes = detects_im[np.random.choice(detects_im.shape[0], num_NoF_perIm, replace=False), :]
        for j in range(bboxes.shape[0]):    
            bbox = bboxes[j]
            xmin = bbox[0]
            ymin = bbox[1]
            xmax = bbox[2]
            ymax = bbox[3]
            assert max(xmin,0)<min(xmax,width_image)
            assert max(ymin,0)<min(ymax,height_image)
            GTbbox_df.loc[len(GTbbox_df)]=[image_file,image_class,j,'NoF',xmin,ymin,xmax,ymax]

#     test_size = GTbbox_df.shape[0]-int(math.ceil(GTbbox_df.shape[0]*0.8/128)*128)
#     train_ind, valid_ind = train_test_split(range(GTbbox_df.shape[0]), test_size=test_size, random_state=1986, stratify=GTbbox_df['crop_class'])
#     GTbbox_df['split'] = ['train' if i in train_ind else 'valid' for i in range(GTbbox_df.shape[0])]
    image_files_df = GTbbox_df[['image_file','image_class']]
    image_files_df.drop_duplicates(inplace = True)
    test_file_nb = image_files_df.shape[0] - int(math.ceil(image_files_df.shape[0]*0.9))
    train_files_df, valid_files_df = train_test_split(image_files_df, test_size=test_file_nb, random_state=1986, stratify=image_files_df.image_class)
    GTbbox_df['split'] = ['train' if image_file in train_files_df.image_file.tolist() else 'valid' for image_file in GTbbox_df.image_file]
#     train2valid_nb = GTbbox_df.loc[GTbbox_df['split']=='train'].shape[0] - int(math.floor(GTbbox_df.loc[GTbbox_df['split']=='train'].shape[0]/128)*128)
#     train_df = GTbbox_df.loc[GTbbox_df['split']=='train']
#     np.random.seed(1986)
#     inds = np.random.choice(train_df.index, train2valid_nb)
#     GTbbox_df.loc[inds, 'split'] = 'valid'

    GTbbox_df.to_pickle(OUTPUT_DIR+file_name)
    print('Done')

# GTbbox_df.loc[(GTbbox_df['image_class']!='NoF') & (GTbbox_df['crop_class']!='NoF') & (GTbbox_df['image_class']!=GTbbox_df['crop_class'])]


Loading from file GTbbox_df.pickle
# train_file_df = GTbbox_df.loc[GTbbox_df['split']=='train',['image_file','image_class']] # train_file_df.drop_duplicates(inplace = True) # train_file_df.groupby('image_class').size() # valid_file_df = GTbbox_df.loc[GTbbox_df['split']=='valid',['image_file','image_class']] # valid_file_df.drop_duplicates(inplace = True) # valid_file_df.groupby('image_class').size() # GTbbox_df.groupby('split').size() # GTbbox_df.loc[GTbbox_df['split']=='train'].groupby('crop_class').size() # GTbbox_df.loc[GTbbox_df['split']=='valid'].groupby('crop_class').size()

In [145]:
#Load data
X_all, y_all = data_load('all')
X_train, y_train = data_load('train')
X_valid, y_valid = data_load('valid')  
print('Loading data done.')

print('all sample ', X_all.shape[0])
print('train sample ', X_train.shape[0])
print('valid sample ', X_valid.shape[0])

print('featurewise mean of X_all is ', featurewise_mean(X_all))
print('featurewise mean of X_train is ', featurewise_mean(X_train))
print('featurewise mean of X_valid is ', featurewise_mean(X_valid))


Generating file data_all_224_224.pickle
Generating file data_train_224_224.pickle
Generating file data_valid_224_224.pickle
Loading data done.
all sample  19479
train sample  17551
valid sample  1928
featurewise mean of X_all is  [ 0.40899828  0.44854766  0.41440123]
featurewise mean of X_train is  [ 0.40807569  0.44782108  0.41385207]
featurewise mean of X_valid is  [ 0.41741633  0.45513189  0.41941798]

In [146]:
# #class weight = n_samples / (n_classes * np.bincount(y))
# class_weight_fish = dict(GTbbox_df.groupby('crop_class').size())
# class_weight = {}
# n_samples = GTbbox_df.shape[0]
# for key,value in class_weight_fish.items():
#         class_weight[CROP_CLASSES.index(key)] = n_samples / (len(CROP_CLASSES)*value)
# class_weight

class_weight_fish = dict(GTbbox_df.groupby('crop_class').size())
class_weight = {}
ref = max(class_weight_fish.values())
for key,value in class_weight_fish.items():
    class_weight[FISH_CLASSES.index(key)] = ref/value
class_weight


Out[146]:
{0: 1.0,
 1: 6.0119379228014322,
 2: 49.372549019607845,
 3: 119.9047619047619,
 4: 143.88571428571427,
 5: 45.369369369369366,
 6: 79.936507936507937,
 7: 18.908635794743429}

In [147]:
#data augmentation

all_mean = featurewise_mean(X_all)
def preprocessing_function(x):
#     resnet50 image preprocessing
#     'RGB'->'BGR'
    x = x[:, :, ::-1]
    x -= np.reshape(all_mean, [1, 1, 3])
    return x

train_datagen = ImageDataGenerator(
    preprocessing_function=preprocessing_function,
    rotation_range=180,
    shear_range=0.2,
    zoom_range=0.1,
    width_shift_range=0.1,
    height_shift_range=0.1,
    horizontal_flip=True,
    vertical_flip=True)
train_generator = train_datagen.flow(X_train, y_train, batch_size=BATCHSIZE, shuffle=True, seed=None)
steps_per_epoch = int(math.ceil(X_train.shape[0]/BATCHSIZE))

X_valid_centered = X_valid - np.reshape(all_mean, [1, 1, 1, 3])

In [148]:
#callbacks

early_stopping = EarlyStopping(monitor='val_loss', min_delta=0, patience=25, verbose=1, mode='auto')        

model_checkpoint = ModelCheckpoint(filepath=CHECKPOINT_DIR+'weights.{epoch:03d}-{val_loss:.4f}.hdf5', monitor='val_loss', verbose=1, save_best_only=True, save_weights_only=False, mode='auto')
        
learningrate_schedule = ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=10, verbose=1, mode='auto', epsilon=0.001, cooldown=0, min_lr=0)

tensorboard = TensorBoard(log_dir=LOG_DIR, histogram_freq=0, write_graph=False, write_images=True)

In [149]:
#Resnet50
#top layer training

from keras.applications.resnet50 import ResNet50

base_model = ResNet50(weights='imagenet', include_top=False)
x = base_model.output
x = GlobalAveragePooling2D()(x)
# x = Dropout(0.5)(x)
predictions = Dense(len(FISH_CLASSES), kernel_initializer='glorot_normal', activation='softmax')(x)

model = Model(inputs=base_model.input, outputs=predictions)

# first: train only the top layers (which were randomly initialized)
for layer in base_model.layers:
    layer.trainable = False

# compile the model (should be done *after* setting layers to non-trainable)
optimizer = Adam(lr=1e-4)
model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])

# train the model on the new data for a few epochs
model.fit_generator(train_generator, steps_per_epoch=steps_per_epoch, epochs=30, verbose=1, 
                    callbacks=[early_stopping, model_checkpoint, learningrate_schedule, tensorboard], 
                    validation_data=(X_valid_centered, y_valid), 
                    class_weight=class_weight, workers=3, pickle_safe=True)


Epoch 1/30
137/138 [============================>.] - ETA: 1s - loss: 11.6847 - acc: 0.4051   Epoch 00000: val_loss improved from inf to 1.12706, saving model to ./checkpoint/weights.000-1.1271.hdf5
138/138 [==============================] - 270s - loss: 11.6530 - acc: 0.4065 - val_loss: 1.1271 - val_acc: 0.7822
Epoch 2/30
137/138 [============================>.] - ETA: 1s - loss: 9.3808 - acc: 0.6062   Epoch 00001: val_loss improved from 1.12706 to 0.93605, saving model to ./checkpoint/weights.001-0.9360.hdf5
138/138 [==============================] - 229s - loss: 9.3838 - acc: 0.6064 - val_loss: 0.9360 - val_acc: 0.7822
Epoch 3/30
137/138 [============================>.] - ETA: 1s - loss: 8.0611 - acc: 0.6702   Epoch 00002: val_loss did not improve
138/138 [==============================] - 231s - loss: 8.0182 - acc: 0.6707 - val_loss: 0.9457 - val_acc: 0.7822
Epoch 4/30
137/138 [============================>.] - ETA: 1s - loss: 7.0647 - acc: 0.6995   Epoch 00003: val_loss did not improve
138/138 [==============================] - 229s - loss: 7.0496 - acc: 0.6997 - val_loss: 0.9910 - val_acc: 0.7822
Epoch 5/30
137/138 [============================>.] - ETA: 1s - loss: 6.7864 - acc: 0.7103  Epoch 00004: val_loss improved from 0.93605 to 0.93380, saving model to ./checkpoint/weights.004-0.9338.hdf5
138/138 [==============================] - 230s - loss: 6.7802 - acc: 0.7101 - val_loss: 0.9338 - val_acc: 0.7832
Epoch 6/30
137/138 [============================>.] - ETA: 1s - loss: 6.3542 - acc: 0.7230  Epoch 00005: val_loss improved from 0.93380 to 0.78918, saving model to ./checkpoint/weights.005-0.7892.hdf5
138/138 [==============================] - 230s - loss: 6.3220 - acc: 0.7212 - val_loss: 0.7892 - val_acc: 0.7837
Epoch 7/30
137/138 [============================>.] - ETA: 1s - loss: 5.6320 - acc: 0.7394  Epoch 00006: val_loss improved from 0.78918 to 0.65079, saving model to ./checkpoint/weights.006-0.6508.hdf5
138/138 [==============================] - 229s - loss: 5.6158 - acc: 0.7397 - val_loss: 0.6508 - val_acc: 0.7951
Epoch 8/30
137/138 [============================>.] - ETA: 1s - loss: 5.7773 - acc: 0.7500  Epoch 00007: val_loss improved from 0.65079 to 0.62098, saving model to ./checkpoint/weights.007-0.6210.hdf5
138/138 [==============================] - 229s - loss: 5.7775 - acc: 0.7502 - val_loss: 0.6210 - val_acc: 0.7941
Epoch 9/30
137/138 [============================>.] - ETA: 1s - loss: 5.4257 - acc: 0.7540  Epoch 00008: val_loss improved from 0.62098 to 0.60951, saving model to ./checkpoint/weights.008-0.6095.hdf5
138/138 [==============================] - 231s - loss: 5.6100 - acc: 0.7528 - val_loss: 0.6095 - val_acc: 0.8024
Epoch 10/30
137/138 [============================>.] - ETA: 1s - loss: 5.3175 - acc: 0.7549  Epoch 00009: val_loss did not improve
138/138 [==============================] - 228s - loss: 5.3166 - acc: 0.7545 - val_loss: 0.6512 - val_acc: 0.7827
Epoch 11/30
137/138 [============================>.] - ETA: 1s - loss: 4.9336 - acc: 0.7800  Epoch 00010: val_loss improved from 0.60951 to 0.58301, saving model to ./checkpoint/weights.010-0.5830.hdf5
138/138 [==============================] - 230s - loss: 4.9376 - acc: 0.7804 - val_loss: 0.5830 - val_acc: 0.8122
Epoch 12/30
137/138 [============================>.] - ETA: 1s - loss: 5.0412 - acc: 0.7703  Epoch 00011: val_loss did not improve
138/138 [==============================] - 228s - loss: 5.0431 - acc: 0.7703 - val_loss: 0.6382 - val_acc: 0.7915
Epoch 13/30
137/138 [============================>.] - ETA: 1s - loss: 4.9123 - acc: 0.7670  Epoch 00012: val_loss improved from 0.58301 to 0.57465, saving model to ./checkpoint/weights.012-0.5746.hdf5
138/138 [==============================] - 228s - loss: 4.8944 - acc: 0.7673 - val_loss: 0.5746 - val_acc: 0.8159
Epoch 14/30
137/138 [============================>.] - ETA: 1s - loss: 4.8248 - acc: 0.7781  Epoch 00013: val_loss did not improve
138/138 [==============================] - 230s - loss: 4.8152 - acc: 0.7780 - val_loss: 0.6046 - val_acc: 0.7910
Epoch 15/30
137/138 [============================>.] - ETA: 1s - loss: 4.5422 - acc: 0.7903  Epoch 00014: val_loss improved from 0.57465 to 0.55122, saving model to ./checkpoint/weights.014-0.5512.hdf5
138/138 [==============================] - 229s - loss: 4.5534 - acc: 0.7902 - val_loss: 0.5512 - val_acc: 0.8174
Epoch 16/30
137/138 [============================>.] - ETA: 1s - loss: 4.3114 - acc: 0.8020  Epoch 00015: val_loss improved from 0.55122 to 0.51650, saving model to ./checkpoint/weights.015-0.5165.hdf5
138/138 [==============================] - 227s - loss: 4.3110 - acc: 0.8016 - val_loss: 0.5165 - val_acc: 0.8397
Epoch 17/30
137/138 [============================>.] - ETA: 1s - loss: 4.5446 - acc: 0.7963  Epoch 00016: val_loss did not improve
138/138 [==============================] - 229s - loss: 4.5460 - acc: 0.7961 - val_loss: 0.5579 - val_acc: 0.8122
Epoch 18/30
137/138 [============================>.] - ETA: 1s - loss: 4.1878 - acc: 0.8030  Epoch 00017: val_loss improved from 0.51650 to 0.50454, saving model to ./checkpoint/weights.017-0.5045.hdf5
138/138 [==============================] - 229s - loss: 4.1794 - acc: 0.8032 - val_loss: 0.5045 - val_acc: 0.8325
Epoch 19/30
137/138 [============================>.] - ETA: 1s - loss: 4.5211 - acc: 0.7901  Epoch 00018: val_loss did not improve
138/138 [==============================] - 227s - loss: 4.5085 - acc: 0.7905 - val_loss: 0.5783 - val_acc: 0.8029
Epoch 20/30
137/138 [============================>.] - ETA: 1s - loss: 4.1299 - acc: 0.8048  Epoch 00019: val_loss did not improve
138/138 [==============================] - 229s - loss: 4.1273 - acc: 0.8047 - val_loss: 0.5234 - val_acc: 0.8309
Epoch 21/30
137/138 [============================>.] - ETA: 1s - loss: 4.1383 - acc: 0.8042  Epoch 00020: val_loss did not improve
138/138 [==============================] - 229s - loss: 4.1391 - acc: 0.8042 - val_loss: 0.5409 - val_acc: 0.8216
Epoch 22/30
137/138 [============================>.] - ETA: 1s - loss: 4.0365 - acc: 0.8087  Epoch 00021: val_loss improved from 0.50454 to 0.49598, saving model to ./checkpoint/weights.021-0.4960.hdf5
138/138 [==============================] - 227s - loss: 4.0474 - acc: 0.8089 - val_loss: 0.4960 - val_acc: 0.8377
Epoch 23/30
137/138 [============================>.] - ETA: 1s - loss: 4.1476 - acc: 0.8081  Epoch 00022: val_loss did not improve
138/138 [==============================] - 230s - loss: 4.1357 - acc: 0.8082 - val_loss: 0.5124 - val_acc: 0.8242
Epoch 24/30
137/138 [============================>.] - ETA: 1s - loss: 3.9443 - acc: 0.8123  Epoch 00023: val_loss did not improve
138/138 [==============================] - 231s - loss: 3.9809 - acc: 0.8112 - val_loss: 0.6153 - val_acc: 0.7863
Epoch 25/30
137/138 [============================>.] - ETA: 1s - loss: 3.8360 - acc: 0.8115  Epoch 00024: val_loss did not improve
138/138 [==============================] - 229s - loss: 3.8420 - acc: 0.8117 - val_loss: 0.5061 - val_acc: 0.8195
Epoch 26/30
137/138 [============================>.] - ETA: 1s - loss: 3.7255 - acc: 0.8177  Epoch 00025: val_loss improved from 0.49598 to 0.48055, saving model to ./checkpoint/weights.025-0.4805.hdf5
138/138 [==============================] - 229s - loss: 3.7374 - acc: 0.8175 - val_loss: 0.4805 - val_acc: 0.8304
Epoch 27/30
137/138 [============================>.] - ETA: 1s - loss: 3.8217 - acc: 0.8122  Epoch 00026: val_loss improved from 0.48055 to 0.46387, saving model to ./checkpoint/weights.026-0.4639.hdf5
138/138 [==============================] - 231s - loss: 3.8101 - acc: 0.8126 - val_loss: 0.4639 - val_acc: 0.8434
Epoch 28/30
137/138 [============================>.] - ETA: 1s - loss: 3.5941 - acc: 0.8327  Epoch 00027: val_loss did not improve
138/138 [==============================] - 228s - loss: 3.5982 - acc: 0.8328 - val_loss: 0.4905 - val_acc: 0.8361
Epoch 29/30
137/138 [============================>.] - ETA: 1s - loss: 3.7363 - acc: 0.8218  Epoch 00028: val_loss did not improve
138/138 [==============================] - 229s - loss: 3.7305 - acc: 0.8220 - val_loss: 0.5137 - val_acc: 0.8299
Epoch 30/30
137/138 [============================>.] - ETA: 1s - loss: 3.6283 - acc: 0.8271  Epoch 00029: val_loss did not improve
138/138 [==============================] - 228s - loss: 3.6356 - acc: 0.8270 - val_loss: 0.4810 - val_acc: 0.8382
Out[149]:
<keras.callbacks.History at 0x7fcd65868b10>

In [150]:
### Resnet50
# fine tuning
# 164 conv5c+top
# 142 conv5+top
# 80 conv4+conv5+top
# 38 conv3+conv4+conv5+top
start_layer = 38

model, model_name = get_best_model()
# print('Loading model from weights.004-0.0565.hdf5')
# model = load_model(CHECHPOINT_DIR+'weights.004-0.0565.hdf5')

for layer in model.layers[:start_layer]:
   layer.trainable = False
for layer in model.layers[start_layer:]:
   layer.trainable = True

# we need to recompile the model for these modifications to take effect
# we use SGD with a low learning rate
optimizer = Adam(lr=1e-5)
model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])

model.fit_generator(train_generator, steps_per_epoch=steps_per_epoch, epochs=300, verbose=1, 
                    callbacks=[early_stopping, model_checkpoint, learningrate_schedule, tensorboard], 
                    validation_data=(X_valid_centered, y_valid), 
                    class_weight=class_weight, workers=3, pickle_safe=True, initial_epoch=27)


Loading model from checkpoint file ./checkpoint/weights.026-0.4639.hdf5
Loading model Done!
Epoch 28/300
137/138 [============================>.] - ETA: 3s - loss: 3.5172 - acc: 0.8290   Epoch 00027: val_loss improved from 0.46387 to 0.43110, saving model to ./checkpoint/weights.027-0.4311.hdf5
138/138 [==============================] - 453s - loss: 3.5080 - acc: 0.8291 - val_loss: 0.4311 - val_acc: 0.8522
Epoch 29/300
137/138 [============================>.] - ETA: 2s - loss: 2.7881 - acc: 0.8609  Epoch 00028: val_loss improved from 0.43110 to 0.38250, saving model to ./checkpoint/weights.028-0.3825.hdf5
138/138 [==============================] - 436s - loss: 2.7787 - acc: 0.8610 - val_loss: 0.3825 - val_acc: 0.8729
Epoch 30/300
137/138 [============================>.] - ETA: 2s - loss: 2.4008 - acc: 0.8836  Epoch 00029: val_loss improved from 0.38250 to 0.36571, saving model to ./checkpoint/weights.029-0.3657.hdf5
138/138 [==============================] - 433s - loss: 2.3915 - acc: 0.8839 - val_loss: 0.3657 - val_acc: 0.8849
Epoch 31/300
137/138 [============================>.] - ETA: 3s - loss: 2.1286 - acc: 0.8940  Epoch 00030: val_loss improved from 0.36571 to 0.31686, saving model to ./checkpoint/weights.030-0.3169.hdf5
138/138 [==============================] - 436s - loss: 2.1316 - acc: 0.8943 - val_loss: 0.3169 - val_acc: 0.9015
Epoch 32/300
137/138 [============================>.] - ETA: 3s - loss: 1.7537 - acc: 0.9082  Epoch 00031: val_loss improved from 0.31686 to 0.30997, saving model to ./checkpoint/weights.031-0.3100.hdf5
138/138 [==============================] - 437s - loss: 1.7502 - acc: 0.9082 - val_loss: 0.3100 - val_acc: 0.9056
Epoch 33/300
137/138 [============================>.] - ETA: 2s - loss: 1.5893 - acc: 0.9177  Epoch 00032: val_loss did not improve
138/138 [==============================] - 434s - loss: 1.5828 - acc: 0.9169 - val_loss: 0.3385 - val_acc: 0.8942
Epoch 34/300
137/138 [============================>.] - ETA: 2s - loss: 1.3868 - acc: 0.9233  Epoch 00033: val_loss improved from 0.30997 to 0.30501, saving model to ./checkpoint/weights.033-0.3050.hdf5
138/138 [==============================] - 434s - loss: 1.3827 - acc: 0.9236 - val_loss: 0.3050 - val_acc: 0.9040
Epoch 35/300
137/138 [============================>.] - ETA: 3s - loss: 1.2600 - acc: 0.9321  Epoch 00034: val_loss improved from 0.30501 to 0.29619, saving model to ./checkpoint/weights.034-0.2962.hdf5
138/138 [==============================] - 436s - loss: 1.2559 - acc: 0.9322 - val_loss: 0.2962 - val_acc: 0.9066
Epoch 36/300
137/138 [============================>.] - ETA: 2s - loss: 1.0788 - acc: 0.9408  Epoch 00035: val_loss improved from 0.29619 to 0.28655, saving model to ./checkpoint/weights.035-0.2865.hdf5
138/138 [==============================] - 435s - loss: 1.0787 - acc: 0.9398 - val_loss: 0.2865 - val_acc: 0.9098
Epoch 37/300
137/138 [============================>.] - ETA: 2s - loss: 1.0888 - acc: 0.9409  Epoch 00036: val_loss improved from 0.28655 to 0.28246, saving model to ./checkpoint/weights.036-0.2825.hdf5
138/138 [==============================] - 434s - loss: 1.0882 - acc: 0.9409 - val_loss: 0.2825 - val_acc: 0.9082
Epoch 38/300
137/138 [============================>.] - ETA: 3s - loss: 0.9256 - acc: 0.9477  Epoch 00037: val_loss improved from 0.28246 to 0.28046, saving model to ./checkpoint/weights.037-0.2805.hdf5
138/138 [==============================] - 437s - loss: 0.9309 - acc: 0.9480 - val_loss: 0.2805 - val_acc: 0.9118
Epoch 39/300
137/138 [============================>.] - ETA: 2s - loss: 0.7517 - acc: 0.9549  Epoch 00038: val_loss did not improve
138/138 [==============================] - 433s - loss: 0.7498 - acc: 0.9550 - val_loss: 0.2869 - val_acc: 0.9108
Epoch 40/300
137/138 [============================>.] - ETA: 2s - loss: 0.8138 - acc: 0.9519  Epoch 00039: val_loss improved from 0.28046 to 0.25453, saving model to ./checkpoint/weights.039-0.2545.hdf5
138/138 [==============================] - 432s - loss: 0.8104 - acc: 0.9520 - val_loss: 0.2545 - val_acc: 0.9206
Epoch 41/300
137/138 [============================>.] - ETA: 3s - loss: 0.7372 - acc: 0.9542  Epoch 00040: val_loss did not improve
138/138 [==============================] - 436s - loss: 0.7370 - acc: 0.9541 - val_loss: 0.2946 - val_acc: 0.9098
Epoch 42/300
137/138 [============================>.] - ETA: 2s - loss: 0.6074 - acc: 0.9616  Epoch 00041: val_loss did not improve
138/138 [==============================] - 431s - loss: 0.6047 - acc: 0.9616 - val_loss: 0.2618 - val_acc: 0.9217
Epoch 43/300
137/138 [============================>.] - ETA: 2s - loss: 0.5953 - acc: 0.9658  Epoch 00042: val_loss improved from 0.25453 to 0.24427, saving model to ./checkpoint/weights.042-0.2443.hdf5
138/138 [==============================] - 434s - loss: 0.5929 - acc: 0.9656 - val_loss: 0.2443 - val_acc: 0.9222
Epoch 44/300
137/138 [============================>.] - ETA: 3s - loss: 0.5569 - acc: 0.9637  Epoch 00043: val_loss did not improve
138/138 [==============================] - 436s - loss: 0.5546 - acc: 0.9638 - val_loss: 0.2692 - val_acc: 0.9160
Epoch 45/300
137/138 [============================>.] - ETA: 2s - loss: 0.4918 - acc: 0.9646  Epoch 00044: val_loss improved from 0.24427 to 0.24104, saving model to ./checkpoint/weights.044-0.2410.hdf5
138/138 [==============================] - 434s - loss: 0.4931 - acc: 0.9646 - val_loss: 0.2410 - val_acc: 0.9243
Epoch 46/300
137/138 [============================>.] - ETA: 2s - loss: 0.4508 - acc: 0.9690  Epoch 00045: val_loss did not improve
138/138 [==============================] - 431s - loss: 0.4511 - acc: 0.9691 - val_loss: 0.2550 - val_acc: 0.9201
Epoch 47/300
137/138 [============================>.] - ETA: 3s - loss: 0.4145 - acc: 0.9705  Epoch 00046: val_loss did not improve
138/138 [==============================] - 436s - loss: 0.4170 - acc: 0.9703 - val_loss: 0.2673 - val_acc: 0.9170
Epoch 48/300
137/138 [============================>.] - ETA: 2s - loss: 0.3704 - acc: 0.9729  Epoch 00047: val_loss did not improve
138/138 [==============================] - 433s - loss: 0.3701 - acc: 0.9729 - val_loss: 0.2487 - val_acc: 0.9206
Epoch 49/300
137/138 [============================>.] - ETA: 2s - loss: 0.3245 - acc: 0.9741  Epoch 00048: val_loss did not improve
138/138 [==============================] - 430s - loss: 0.3302 - acc: 0.9740 - val_loss: 0.2435 - val_acc: 0.9227
Epoch 50/300
137/138 [============================>.] - ETA: 3s - loss: 0.3361 - acc: 0.9758  Epoch 00049: val_loss improved from 0.24104 to 0.23477, saving model to ./checkpoint/weights.049-0.2348.hdf5
138/138 [==============================] - 437s - loss: 0.3416 - acc: 0.9758 - val_loss: 0.2348 - val_acc: 0.9232
Epoch 51/300
137/138 [============================>.] - ETA: 2s - loss: 0.3498 - acc: 0.9742  Epoch 00050: val_loss did not improve
138/138 [==============================] - 434s - loss: 0.3491 - acc: 0.9742 - val_loss: 0.2531 - val_acc: 0.9196
Epoch 52/300
137/138 [============================>.] - ETA: 2s - loss: 0.3261 - acc: 0.9737  Epoch 00051: val_loss improved from 0.23477 to 0.23150, saving model to ./checkpoint/weights.051-0.2315.hdf5
138/138 [==============================] - 432s - loss: 0.3292 - acc: 0.9736 - val_loss: 0.2315 - val_acc: 0.9310
Epoch 53/300
137/138 [============================>.] - ETA: 3s - loss: 0.2619 - acc: 0.9798  Epoch 00052: val_loss did not improve
138/138 [==============================] - 437s - loss: 0.2619 - acc: 0.9797 - val_loss: 0.2339 - val_acc: 0.9284
Epoch 54/300
137/138 [============================>.] - ETA: 2s - loss: 0.2992 - acc: 0.9797  Epoch 00053: val_loss did not improve
138/138 [==============================] - 434s - loss: 0.2986 - acc: 0.9797 - val_loss: 0.2584 - val_acc: 0.9217
Epoch 55/300
137/138 [============================>.] - ETA: 2s - loss: 0.3124 - acc: 0.9748  Epoch 00054: val_loss did not improve
138/138 [==============================] - 431s - loss: 0.3112 - acc: 0.9748 - val_loss: 0.2443 - val_acc: 0.9248
Epoch 56/300
137/138 [============================>.] - ETA: 3s - loss: 0.2254 - acc: 0.9808  Epoch 00055: val_loss did not improve
138/138 [==============================] - 436s - loss: 0.2246 - acc: 0.9810 - val_loss: 0.2420 - val_acc: 0.9243
Epoch 57/300
137/138 [============================>.] - ETA: 2s - loss: 0.2504 - acc: 0.9793  Epoch 00056: val_loss did not improve
138/138 [==============================] - 435s - loss: 0.2488 - acc: 0.9795 - val_loss: 0.2496 - val_acc: 0.9263
Epoch 58/300
137/138 [============================>.] - ETA: 2s - loss: 0.2005 - acc: 0.9834  Epoch 00057: val_loss did not improve
138/138 [==============================] - 434s - loss: 0.2009 - acc: 0.9834 - val_loss: 0.2483 - val_acc: 0.9238
Epoch 59/300
137/138 [============================>.] - ETA: 3s - loss: 0.2049 - acc: 0.9836  Epoch 00058: val_loss did not improve
138/138 [==============================] - 437s - loss: 0.2047 - acc: 0.9835 - val_loss: 0.2382 - val_acc: 0.9274
Epoch 60/300
137/138 [============================>.] - ETA: 2s - loss: 0.1718 - acc: 0.9839  Epoch 00059: val_loss did not improve
138/138 [==============================] - 434s - loss: 0.1720 - acc: 0.9839 - val_loss: 0.2325 - val_acc: 0.9305
Epoch 61/300
137/138 [============================>.] - ETA: 2s - loss: 0.1939 - acc: 0.9823  Epoch 00060: val_loss did not improve
138/138 [==============================] - 431s - loss: 0.1930 - acc: 0.9823 - val_loss: 0.2378 - val_acc: 0.9258
Epoch 62/300
137/138 [============================>.] - ETA: 3s - loss: 0.1859 - acc: 0.9846  Epoch 00061: val_loss did not improve
138/138 [==============================] - 436s - loss: 0.1853 - acc: 0.9846 - val_loss: 0.2610 - val_acc: 0.9248
Epoch 63/300
137/138 [============================>.] - ETA: 2s - loss: 0.2030 - acc: 0.9815  Epoch 00062: val_loss did not improve

Epoch 00062: reducing learning rate to 9.99999974738e-07.
138/138 [==============================] - 436s - loss: 0.2045 - acc: 0.9811 - val_loss: 0.2647 - val_acc: 0.9274
Epoch 64/300
137/138 [============================>.] - ETA: 2s - loss: 0.1923 - acc: 0.9770  Epoch 00063: val_loss did not improve
138/138 [==============================] - 434s - loss: 0.1932 - acc: 0.9770 - val_loss: 0.2471 - val_acc: 0.9238
Epoch 65/300
137/138 [============================>.] - ETA: 3s - loss: 0.1551 - acc: 0.9820  Epoch 00064: val_loss did not improve
138/138 [==============================] - 436s - loss: 0.1545 - acc: 0.9820 - val_loss: 0.2412 - val_acc: 0.9238
Epoch 66/300
137/138 [============================>.] - ETA: 2s - loss: 0.1575 - acc: 0.9825  Epoch 00065: val_loss did not improve
138/138 [==============================] - 431s - loss: 0.1571 - acc: 0.9826 - val_loss: 0.2408 - val_acc: 0.9227
Epoch 67/300
137/138 [============================>.] - ETA: 2s - loss: 0.1401 - acc: 0.9828  Epoch 00066: val_loss did not improve
138/138 [==============================] - 434s - loss: 0.1403 - acc: 0.9829 - val_loss: 0.2331 - val_acc: 0.9243
Epoch 68/300
137/138 [============================>.] - ETA: 3s - loss: 0.1349 - acc: 0.9839  Epoch 00067: val_loss improved from 0.23150 to 0.23102, saving model to ./checkpoint/weights.067-0.2310.hdf5
138/138 [==============================] - 437s - loss: 0.1351 - acc: 0.9839 - val_loss: 0.2310 - val_acc: 0.9274
Epoch 69/300
137/138 [============================>.] - ETA: 2s - loss: 0.1459 - acc: 0.9849  Epoch 00068: val_loss improved from 0.23102 to 0.22594, saving model to ./checkpoint/weights.068-0.2259.hdf5
138/138 [==============================] - 432s - loss: 0.1474 - acc: 0.9848 - val_loss: 0.2259 - val_acc: 0.9284
Epoch 70/300
137/138 [============================>.] - ETA: 2s - loss: 0.1612 - acc: 0.9838  Epoch 00069: val_loss did not improve
138/138 [==============================] - 433s - loss: 0.1604 - acc: 0.9839 - val_loss: 0.2287 - val_acc: 0.9258
Epoch 71/300
137/138 [============================>.] - ETA: 3s - loss: 0.1147 - acc: 0.9874  Epoch 00070: val_loss did not improve
138/138 [==============================] - 436s - loss: 0.1156 - acc: 0.9874 - val_loss: 0.2283 - val_acc: 0.9279
Epoch 72/300
137/138 [============================>.] - ETA: 2s - loss: 0.1441 - acc: 0.9845  Epoch 00071: val_loss did not improve
138/138 [==============================] - 431s - loss: 0.1433 - acc: 0.9846 - val_loss: 0.2292 - val_acc: 0.9279
Epoch 73/300
137/138 [============================>.] - ETA: 2s - loss: 0.1367 - acc: 0.9862  Epoch 00072: val_loss improved from 0.22594 to 0.22403, saving model to ./checkpoint/weights.072-0.2240.hdf5
138/138 [==============================] - 434s - loss: 0.1363 - acc: 0.9862 - val_loss: 0.2240 - val_acc: 0.9289
Epoch 74/300
137/138 [============================>.] - ETA: 2s - loss: 0.1220 - acc: 0.9877  Epoch 00073: val_loss improved from 0.22403 to 0.22365, saving model to ./checkpoint/weights.073-0.2237.hdf5
138/138 [==============================] - 436s - loss: 0.1216 - acc: 0.9878 - val_loss: 0.2237 - val_acc: 0.9289
Epoch 75/300
137/138 [============================>.] - ETA: 2s - loss: 0.1261 - acc: 0.9867  Epoch 00074: val_loss improved from 0.22365 to 0.22308, saving model to ./checkpoint/weights.074-0.2231.hdf5
138/138 [==============================] - 432s - loss: 0.1262 - acc: 0.9867 - val_loss: 0.2231 - val_acc: 0.9310
Epoch 76/300
137/138 [============================>.] - ETA: 2s - loss: 0.1222 - acc: 0.9869  Epoch 00075: val_loss improved from 0.22308 to 0.22139, saving model to ./checkpoint/weights.075-0.2214.hdf5
138/138 [==============================] - 434s - loss: 0.1224 - acc: 0.9868 - val_loss: 0.2214 - val_acc: 0.9305
Epoch 77/300
137/138 [============================>.] - ETA: 3s - loss: 0.1084 - acc: 0.9891  Epoch 00076: val_loss did not improve
138/138 [==============================] - 436s - loss: 0.1084 - acc: 0.9890 - val_loss: 0.2219 - val_acc: 0.9284
Epoch 78/300
137/138 [============================>.] - ETA: 2s - loss: 0.1365 - acc: 0.9875  Epoch 00077: val_loss improved from 0.22139 to 0.22075, saving model to ./checkpoint/weights.077-0.2208.hdf5
138/138 [==============================] - 431s - loss: 0.1374 - acc: 0.9874 - val_loss: 0.2208 - val_acc: 0.9326
Epoch 79/300
137/138 [============================>.] - ETA: 2s - loss: 0.1166 - acc: 0.9880  Epoch 00078: val_loss did not improve
138/138 [==============================] - 433s - loss: 0.1167 - acc: 0.9881 - val_loss: 0.2267 - val_acc: 0.9279
Epoch 80/300
137/138 [============================>.] - ETA: 2s - loss: 0.1095 - acc: 0.9881  Epoch 00079: val_loss did not improve
138/138 [==============================] - 435s - loss: 0.1092 - acc: 0.9881 - val_loss: 0.2265 - val_acc: 0.9295
Epoch 81/300
137/138 [============================>.] - ETA: 2s - loss: 0.1198 - acc: 0.9851  Epoch 00080: val_loss did not improve
138/138 [==============================] - 430s - loss: 0.1194 - acc: 0.9851 - val_loss: 0.2280 - val_acc: 0.9300
Epoch 82/300
137/138 [============================>.] - ETA: 2s - loss: 0.1066 - acc: 0.9890  Epoch 00081: val_loss did not improve
138/138 [==============================] - 433s - loss: 0.1068 - acc: 0.9889 - val_loss: 0.2265 - val_acc: 0.9305
Epoch 83/300
137/138 [============================>.] - ETA: 3s - loss: 0.1101 - acc: 0.9891  Epoch 00082: val_loss did not improve
138/138 [==============================] - 436s - loss: 0.1098 - acc: 0.9891 - val_loss: 0.2246 - val_acc: 0.9295
Epoch 84/300
137/138 [============================>.] - ETA: 2s - loss: 0.1045 - acc: 0.9898  Epoch 00083: val_loss did not improve
138/138 [==============================] - 435s - loss: 0.1169 - acc: 0.9894 - val_loss: 0.2239 - val_acc: 0.9300
Epoch 85/300
137/138 [============================>.] - ETA: 2s - loss: 0.0975 - acc: 0.9887  Epoch 00084: val_loss did not improve
138/138 [==============================] - 433s - loss: 0.0975 - acc: 0.9886 - val_loss: 0.2258 - val_acc: 0.9305
Epoch 86/300
137/138 [============================>.] - ETA: 3s - loss: 0.1182 - acc: 0.9887  Epoch 00085: val_loss did not improve
138/138 [==============================] - 436s - loss: 0.1177 - acc: 0.9887 - val_loss: 0.2220 - val_acc: 0.9305
Epoch 87/300
137/138 [============================>.] - ETA: 2s - loss: 0.1052 - acc: 0.9879  Epoch 00086: val_loss did not improve

Epoch 00086: reducing learning rate to 9.99999997475e-08.
138/138 [==============================] - 434s - loss: 0.1053 - acc: 0.9880 - val_loss: 0.2290 - val_acc: 0.9284
Epoch 88/300
137/138 [============================>.] - ETA: 2s - loss: 0.1106 - acc: 0.9874  Epoch 00087: val_loss did not improve
138/138 [==============================] - 433s - loss: 0.1101 - acc: 0.9875 - val_loss: 0.2272 - val_acc: 0.9284
Epoch 89/300
137/138 [============================>.] - ETA: 3s - loss: 0.1087 - acc: 0.9885  Epoch 00088: val_loss did not improve
138/138 [==============================] - 436s - loss: 0.1081 - acc: 0.9886 - val_loss: 0.2252 - val_acc: 0.9310
Epoch 90/300
137/138 [============================>.] - ETA: 2s - loss: 0.1479 - acc: 0.9892  Epoch 00089: val_loss did not improve
138/138 [==============================] - 432s - loss: 0.1469 - acc: 0.9893 - val_loss: 0.2235 - val_acc: 0.9315
Epoch 91/300
137/138 [============================>.] - ETA: 3s - loss: 0.0966 - acc: 0.9896  Epoch 00090: val_loss did not improve
138/138 [==============================] - 435s - loss: 0.0966 - acc: 0.9896 - val_loss: 0.2234 - val_acc: 0.9310
Epoch 92/300
137/138 [============================>.] - ETA: 3s - loss: 0.1106 - acc: 0.9892  Epoch 00091: val_loss did not improve
138/138 [==============================] - 436s - loss: 0.1103 - acc: 0.9892 - val_loss: 0.2241 - val_acc: 0.9315
Epoch 93/300
137/138 [============================>.] - ETA: 2s - loss: 0.1074 - acc: 0.9874  Epoch 00092: val_loss did not improve
138/138 [==============================] - 431s - loss: 0.1079 - acc: 0.9865 - val_loss: 0.2270 - val_acc: 0.9295
Epoch 94/300
137/138 [============================>.] - ETA: 3s - loss: 0.0961 - acc: 0.9897  Epoch 00093: val_loss did not improve
138/138 [==============================] - 436s - loss: 0.0960 - acc: 0.9898 - val_loss: 0.2270 - val_acc: 0.9300
Epoch 95/300
137/138 [============================>.] - ETA: 3s - loss: 0.0971 - acc: 0.9892  Epoch 00094: val_loss did not improve
138/138 [==============================] - 436s - loss: 0.0973 - acc: 0.9891 - val_loss: 0.2264 - val_acc: 0.9305
Epoch 96/300
137/138 [============================>.] - ETA: 2s - loss: 0.1368 - acc: 0.9890  Epoch 00095: val_loss did not improve
138/138 [==============================] - 434s - loss: 0.1393 - acc: 0.9886 - val_loss: 0.2230 - val_acc: 0.9305
Epoch 97/300
137/138 [============================>.] - ETA: 2s - loss: 0.0932 - acc: 0.9894  Epoch 00096: val_loss did not improve

Epoch 00096: reducing learning rate to 1.00000001169e-08.
138/138 [==============================] - 432s - loss: 0.0934 - acc: 0.9894 - val_loss: 0.2233 - val_acc: 0.9321
Epoch 98/300
137/138 [============================>.] - ETA: 2s - loss: 0.1070 - acc: 0.9876  Epoch 00097: val_loss did not improve
138/138 [==============================] - 435s - loss: 0.1068 - acc: 0.9876 - val_loss: 0.2283 - val_acc: 0.9284
Epoch 99/300
137/138 [============================>.] - ETA: 2s - loss: 0.1166 - acc: 0.9893  Epoch 00098: val_loss did not improve
138/138 [==============================] - 430s - loss: 0.1165 - acc: 0.9894 - val_loss: 0.2261 - val_acc: 0.9300
Epoch 100/300
137/138 [============================>.] - ETA: 2s - loss: 0.1084 - acc: 0.9892  Epoch 00099: val_loss did not improve
138/138 [==============================] - 433s - loss: 0.1087 - acc: 0.9889 - val_loss: 0.2255 - val_acc: 0.9300
Epoch 101/300
137/138 [============================>.] - ETA: 2s - loss: 0.1064 - acc: 0.9885  Epoch 00100: val_loss did not improve
138/138 [==============================] - 435s - loss: 0.1066 - acc: 0.9885 - val_loss: 0.2232 - val_acc: 0.9315
Epoch 102/300
137/138 [============================>.] - ETA: 2s - loss: 0.1102 - acc: 0.9887  Epoch 00101: val_loss did not improve
138/138 [==============================] - 434s - loss: 0.1112 - acc: 0.9888 - val_loss: 0.2249 - val_acc: 0.9300
Epoch 103/300
137/138 [============================>.] - ETA: 2s - loss: 0.1078 - acc: 0.9884  Epoch 00102: val_loss did not improve
138/138 [==============================] - 432s - loss: 0.1082 - acc: 0.9885 - val_loss: 0.2256 - val_acc: 0.9295
Epoch 104/300
137/138 [============================>.] - ETA: 2s - loss: 0.1013 - acc: 0.9897  Epoch 00103: val_loss did not improve
138/138 [==============================] - 435s - loss: 0.1014 - acc: 0.9897 - val_loss: 0.2255 - val_acc: 0.9300
Epoch 00103: early stopping
Out[150]:
<keras.callbacks.History at 0x7fccc383e850>

In [ ]:
#resume training

model, model_name = get_best_model()
# print('Loading model from weights.004-0.0565.hdf5')
# model = load_model(CHECHPOINT_DIR+'weights.004-0.0565.hdf5')

# #try increasing learningrate
# optimizer = Adam(lr=1e-4)
# model.compile(optimizer=optimizer, loss='categorical_crossentropy', metrics=['accuracy'])

model.fit_generator(train_generator, steps_per_epoch=steps_per_epoch, epochs=300, verbose=1, 
                    callbacks=[early_stopping, model_checkpoint, learningrate_schedule, tensorboard], 
                    validation_data=(X_valid_centered, y_valid), 
                    class_weight=class_weight, workers=3, pickle_safe=True, initial_epoch=)

In [49]:
#test prepare

test_model, test_model_name = get_best_model()
# test_model = load_model('./resnet50_FT38_CW_STGTrain/checkpoint/weights.000-0.0327.hdf5')
# test_model_name = 'weights.000-0.0327.hdf5'
# print('test_model_name', test_model_name)

def test_generator(df, mean, datagen = None, batch_size = BATCHSIZE):
    n = df.shape[0]
    batch_index = 0
    while 1:
        current_index = batch_index * batch_size
        if n >= current_index + batch_size:
            current_batch_size = batch_size
            batch_index += 1    
        else:
            current_batch_size = n - current_index
            batch_index = 0        
        batch_df = df[current_index:current_index+current_batch_size]
        batch_x = np.zeros((batch_df.shape[0], ROWS, COLS, 3), dtype=K.floatx())
        i = 0
        for index,row in batch_df.iterrows():
            image_file = row['image_file']
            bbox = [row['xmin'],row['ymin'],row['xmax'],row['ymax']]
            cropped = load_img(TEST_DIR+image_file,bbox,target_size=(ROWS,COLS))
            x = np.asarray(cropped, dtype=K.floatx())
            x /= 255.
            if datagen is not None: x = datagen.random_transform(x)            
            x = preprocess_imagewise(x, mean)
            batch_x[i] = x
            i += 1
        if batch_index%50 == 0: print('batch_index', batch_index)
        yield(batch_x)
        
test_aug_datagen = ImageDataGenerator(
    rotation_range=180,
    shear_range=0.2,
    zoom_range=0.1,
    width_shift_range=0.1,
    height_shift_range=0.1,
    horizontal_flip=True,
    vertical_flip=True)

# train_mean = [0.37698776,  0.41491762,  0.38681713]
train_mean = imagewise_mean(X_train)
print('train_mean:', train_mean.shape)


Loading model from checkpoint file ./resnet50_FT38_Classifier_Rep5/checkpoint/weights.084-0.0739.hdf5
Loading model Done!
train_mean: (224, 224, 3)

In [3]:
test_model_name = 'weights.084-0.0739.hdf5'

In [4]:
#GTbbox_CROPpred_df = ['image_file','crop_index','crop_class','xmin','ymin','xmax','ymax','split'
#                      'NoF', 'ALB', 'BET', 'DOL', 'LAG', 'OTHER', 'SHARK', 'YFT', 'logloss',
#                      'ALB_woNoF', 'BET_woNoF', 'DOL_woNoF', 'LAG_woNoF', 'OTHER_woNoF', 'SHARK_woNoF', 'YFT_woNoF', 'logloss_woNoF']

file_name = 'GTbbox_CROPpred_df_'+test_model_name+'_.pickle'
if os.path.exists(OUTPUT_DIR+file_name):
    print ('Loading from file '+file_name)
    GTbbox_CROPpred_df = pd.read_pickle(OUTPUT_DIR+file_name)
else:
    print ('Generating file '+file_name) 
    nb_augmentation = 1
    if nb_augmentation ==1:
        test_preds = test_model.predict_generator(test_generator(df=GTbbox_df, mean=train_mean), 
                                                  val_samples=GTbbox_df.shape[0], nb_worker=1, pickle_safe=False)
#         test_preds = test_model.predict_generator(test_generator(df=GTbbox_df, mean=train_mean), 
#                                                   steps=int(math.ceil(GTbbox_df.shape[0]/BATCHSIZE)), workers=1, pickle_safe=False)
    else:
        test_preds = np.zeros((GTbbox_df.shape[0], len(FISH_CLASSES)), dtype=K.floatx())
        for idx in range(nb_augmentation):
            print('{}th augmentation for testing ...'.format(idx+1))
            test_preds += test_model.predict_generator(test_generator(df=GTbbox_df, mean=train_mean, datagen=test_aug_datagen), 
                                                       val_samples=GTbbox_df.shape[0], nb_worker=1, pickle_safe=False)
#             test_preds += test_model.predict_generator(test_generator(df=GTbbox_df, mean=train_mean, datagen=test_aug_datagen), 
#                                                        steps=GTbbox_df.shape[0], workers=1, pickle_safe=False)
        test_preds /= nb_augmentation

    CROPpred_df = pd.DataFrame(test_preds, columns=FISH_CLASSES)
    GTbbox_CROPpred_df = pd.concat([GTbbox_df,CROPpred_df], axis=1)
    GTbbox_CROPpred_df['logloss'] = GTbbox_CROPpred_df.apply(lambda row: -math.log(row[row['crop_class']]), axis=1)
    
    for fish in FISH_CLASSES:
        GTbbox_CROPpred_df[fish+'_woNoF'] = GTbbox_CROPpred_df.apply(lambda row: row[fish]/(1-row['NoF']) if fish!='NoF' else np.inf , axis=1)
    GTbbox_CROPpred_df['logloss_woNoF'] = GTbbox_CROPpred_df.apply(lambda row: -math.log(row[row['crop_class']+'_woNoF']), axis=1)
    
    GTbbox_CROPpred_df.to_pickle(OUTPUT_DIR+file_name) 
    
valid_CROPpred_df = GTbbox_CROPpred_df[GTbbox_CROPpred_df['split']=='valid']
crop_valid_woNoF_logloss = valid_CROPpred_df[valid_CROPpred_df['crop_class']!='NoF']['logloss_woNoF'].mean()
print('crop_valid_woNoF_logloss:', crop_valid_woNoF_logloss)


Loading from file GTbbox_CROPpred_df_weights.084-0.0739.hdf5_.pickle
crop_valid_woNoF_logloss: 0.16453690212776534

In [5]:
# print('all loss:', GTbbox_CROPpred_df['logloss'].mean())
# print('all fish loss:', GTbbox_CROPpred_df[GTbbox_CROPpred_df['crop_class']!='NoF']['logloss'].mean())
# print(GTbbox_CROPpred_df.groupby(['crop_class'])['logloss'].mean())
# print('all_woNoF loss:', GTbbox_CROPpred_df[GTbbox_CROPpred_df['crop_class']!='NoF']['logloss_woNoF'].mean())
# print(GTbbox_CROPpred_df[GTbbox_CROPpred_df['crop_class']!='NoF'].groupby(['crop_class'])['logloss_woNoF'].mean())

train_CROPpred_df = GTbbox_CROPpred_df[GTbbox_CROPpred_df['split']=='train']
print('train loss:', train_CROPpred_df['logloss'].mean())
# print('train fish loss:', train_CROPpred_df[train_CROPpred_df['crop_class']!='NoF']['logloss'].mean())
# print(train_CROPpred_df.groupby(['crop_class'])['logloss'].mean())
print('train_woNoF loss:', train_CROPpred_df[train_CROPpred_df['crop_class']!='NoF']['logloss_woNoF'].mean())
print(train_CROPpred_df[train_CROPpred_df['crop_class']!='NoF'].groupby(['crop_class'])['logloss_woNoF'].mean())

valid_CROPpred_df = GTbbox_CROPpred_df[GTbbox_CROPpred_df['split']=='valid']
print('valid loss:', valid_CROPpred_df['logloss'].mean())
# print('valid fish loss:', valid_CROPpred_df[valid_CROPpred_df['crop_class']!='NoF']['logloss'].mean())
# print(valid_CROPpred_df.groupby(['crop_class'])['logloss'].mean())
print('valid_woNoF loss:', valid_CROPpred_df[valid_CROPpred_df['crop_class']!='NoF']['logloss_woNoF'].mean())
print(valid_CROPpred_df[valid_CROPpred_df['crop_class']!='NoF'].groupby(['crop_class'])['logloss_woNoF'].mean())


train loss: 0.03436334160963875
train_woNoF loss: 0.020864595229428972
crop_class
ALB      0.021373
BET      0.019553
DOL      0.000657
LAG      0.000273
OTHER    0.014748
SHARK    0.000621
YFT      0.032967
Name: logloss_woNoF, dtype: float64
valid loss: 0.09322671996697018
valid_woNoF loss: 0.16453690212776534
crop_class
ALB      0.110811
BET      0.327438
DOL      0.523910
LAG      0.004440
OTHER    0.255691
SHARK    0.002541
YFT      0.236282
Name: logloss_woNoF, dtype: float64
fish_loglosses = {} for fish in FISH_CLASSES: fish_loglosses[fish] = GTbbox_CROPpred_df[GTbbox_CROPpred_df['crop_class']==fish]['logloss'] fish_loglosses['ALB'].plot.box()

In [6]:
# RFCNbbox_RFCNpred_df = ['image_class','image_file','crop_index','xmin','ymin','xmax','ymax',
#                          'NoF_RFCN', 'ALB_RFCN', 'BET_RFCN', 'DOL_RFCN',
#                          'LAG_RFCN', 'OTHER_RFCN', 'SHARK_RFCN', 'YFT_RFCN']
# select fish_conf >= CONF_THRESH

file_name = 'RFCNbbox_RFCNpred_df_conf{:.2f}.pickle'.format(CONF_THRESH)
if os.path.exists(OUTPUT_DIR+file_name):
    print ('Loading from file '+file_name)
    RFCNbbox_RFCNpred_df = pd.read_pickle(OUTPUT_DIR+file_name)
else:
    print ('Generating file '+file_name)        
    RFCNbbox_RFCNpred_df = pd.DataFrame(columns=['image_class','image_file','crop_index','xmin','ymin','xmax','ymax',
                                                  'NoF_RFCN', 'ALB_RFCN', 'BET_RFCN', 'DOL_RFCN',
                                                  'LAG_RFCN', 'OTHER_RFCN', 'SHARK_RFCN', 'YFT_RFCN']) 

    with open('../data/RFCN_detections/detections_full_AGNOSTICnms_'+RFCN_MODEL+'.pkl','rb') as f:
        detections_full_AGNOSTICnms = pickle.load(f, encoding='latin1') 
    with open("../RFCN/ImageSets/Main/test.txt","r") as f:
        test_files = f.readlines()
    with open("../RFCN/ImageSets/Main/train_test.txt","r") as f:
        train_file_labels = f.readlines()
    assert len(detections_full_AGNOSTICnms) == len(test_files)
    
    count = np.zeros(len(detections_full_AGNOSTICnms))
    
    for im in range(len(detections_full_AGNOSTICnms)):
        if im%1000 == 0: print(im)
        basename = test_files[im][:9]
        if im<1000:
            image_class = '--'
        else:
            for i in range(len(train_file_labels)):
                if train_file_labels[i][:9] == basename:
                    image_class = train_file_labels[i][10:-1]
                    break
        image = Image.open(TEST_DIR+'/'+basename+'.jpg')
        width_image, height_image = image.size
        
        bboxes = []
        detects_im = detections_full_AGNOSTICnms[im]
        for i in range(len(detects_im)):
            if np.sum(detects_im[i,5:]) >= CONF_THRESH:
#             if np.max(detects_im[i,5:]) >= CONF_THRESH:
                bboxes.append(detects_im[i,:]) 
        count[im] = len(bboxes)
        if len(bboxes) == 0:
            ind = np.argmax(np.sum(detects_im[:,5:], axis=1))
            bboxes.append(detects_im[ind,:])
        bboxes = np.asarray(bboxes)

        for j in range(len(bboxes)):    
            bbox = bboxes[j]
            xmin = bbox[0]
            ymin = bbox[1]
            xmax = bbox[2]
            ymax = bbox[3]
            assert max(xmin,0)<min(xmax,width_image)
            assert max(ymin,0)<min(ymax,height_image)
            RFCNbbox_RFCNpred_df.loc[len(RFCNbbox_RFCNpred_df)]=[image_class,basename+'.jpg',j,max(xmin,0),max(ymin,0),
                                                                   min(xmax,width_image),min(ymax,height_image),
                                                                   bbox[4],bbox[5],bbox[6],bbox[7],bbox[8],bbox[9],bbox[10],bbox[11]]   
    
    RFCNbbox_RFCNpred_df.to_pickle(OUTPUT_DIR+file_name)


Loading from file RFCNbbox_RFCNpred_df_conf0.80.pickle

In [7]:
# RFCNbbox_RFCNpred_CROPpred_HYBRIDpred_df = ['image_class', 'image_file','crop_index','xmin','ymin','xmax','ymax',
#                                    'NoF_RFCN', 'ALB_RFCN', 'BET_RFCN', 'DOL_RFCN',
#                                    'LAG_RFCN', 'OTHER_RFCN', 'SHARK_RFCN', 'YFT_RFCN',
#                                    'NoF_CROP', 'ALB_CROP', 'BET_CROP', 'DOL_CROP',
#                                    'LAG_CROP', 'OTHER_CROP', 'SHARK_CROP', 'YFT_CROP',
#                                    'NoF', 'ALB', 'BET', 'DOL', 'LAG', 'OTHER', 'SHARK', 'YFT']

file_name = 'RFCNbbox_RFCNpred_CROPpred_HYBRIDpred_df_'+test_model_name+'_.pickle'
if os.path.exists(OUTPUT_DIR+file_name):
    print ('Loading from file '+file_name)
    RFCNbbox_RFCNpred_CROPpred_HYBRIDpred_df = pd.read_pickle(OUTPUT_DIR+file_name)
else:
    print ('Generating file '+file_name)  
    nb_augmentation = 1
    if nb_augmentation ==1:
        test_preds = test_model.predict_generator(test_generator(df=RFCNbbox_RFCNpred_df, mean=train_mean), 
                                                  val_samples=RFCNbbox_RFCNpred_df.shape[0], nb_worker=1, pickle_safe=False)
    else:
        test_preds = np.zeros((RFCNbbox_RFCNpred_df.shape[0], len(FISH_CLASSES)), dtype=K.floatx())
        for idx in range(nb_augmentation):
            print('{}th augmentation for testing ...'.format(idx+1))
            test_preds += test_model.predict_generator(test_generator(df=RFCNbbox_RFCNpred_df, mean=train_mean, datagen=test_aug_datagen), 
                                                       val_samples=RFCNbbox_RFCNpred_df.shape[0], nb_worker=1, pickle_safe=False)
        test_preds /= nb_augmentation

    CROPpred_df = pd.DataFrame(test_preds, columns=['NoF_CROP', 'ALB_CROP', 'BET_CROP', 'DOL_CROP', 'LAG_CROP', 'OTHER_CROP', 'SHARK_CROP', 'YFT_CROP'])
    RFCNbbox_RFCNpred_CROPpred_HYBRIDpred_df = pd.concat([RFCNbbox_RFCNpred_df,CROPpred_df], axis=1)
    
    RFCNbbox_RFCNpred_CROPpred_HYBRIDpred_df['NoF'] = RFCNbbox_RFCNpred_CROPpred_HYBRIDpred_df['NoF_RFCN']
    for fish in ['ALB', 'BET', 'DOL', 'LAG', 'OTHER', 'SHARK', 'YFT']:
        RFCNbbox_RFCNpred_CROPpred_HYBRIDpred_df[fish] = RFCNbbox_RFCNpred_CROPpred_HYBRIDpred_df.apply(lambda row: (1-row['NoF_RFCN'])*row[fish+'_CROP']/(1-row['NoF_CROP']), axis=1)

#     for fish in FISH_CLASSES:
#         RFCNbbox_RFCNpred_CROPpred_HYBRIDpred_df[fish] = RFCNbbox_RFCNpred_CROPpred_HYBRIDpred_df[fish+'_CROP']

    RFCNbbox_RFCNpred_CROPpred_HYBRIDpred_df.to_pickle(OUTPUT_DIR+file_name)


Loading from file RFCNbbox_RFCNpred_CROPpred_HYBRIDpred_df_weights.084-0.0739.hdf5_.pickle

In [8]:
# clsMaxAve and hybrid RFCNpred&CROPpred such that RFCNpred for NoF and CROPpred for fish
# test_pred_df = ['logloss','image_class','image_file','NoF', 'ALB', 'BET', 'DOL', 'LAG', 'OTHER', 'SHARK', 'YFT']
# RFCNbbox_RFCNpred_CROPpred_HYBRIDpred_df = ['image_class', 'image_file','crop_index','xmin','ymin','xmax','ymax',
#                                    'NoF_RFCN', 'ALB_RFCN', 'BET_RFCN', 'DOL_RFCN',
#                                    'LAG_RFCN', 'OTHER_RFCN', 'SHARK_RFCN', 'YFT_RFCN',
#                                    'ALB_CROP', 'BET_CROP', 'DOL_CROP',
#                                    'LAG_CROP', 'OTHER_CROP', 'SHARK_CROP', 'YFT_CROP',
#                                    'NoF', 'ALB', 'BET', 'DOL', 'LAG', 'OTHER', 'SHARK', 'YFT']

file_name = 'test_pred_df_Hybrid_'+test_model_name+'_.pickle'
if os.path.exists(OUTPUT_DIR+file_name):
    print ('Loading from file '+file_name)
    test_pred_df = pd.read_pickle(OUTPUT_DIR+file_name)
else:
    print ('Generating file '+file_name)  
    with open("../RFCN/ImageSets/Main/test.txt","r") as f:
        test_files = f.readlines()
    
    test_pred_df = pd.DataFrame(columns=['logloss','image_class','image_file','NoF', 'ALB', 'BET', 'DOL', 'LAG', 'OTHER', 'SHARK', 'YFT'])  
    for j in range(len(test_files)): 
        image_file = test_files[j][:-1]+'.jpg'
        test_pred_im_df = RFCNbbox_RFCNpred_CROPpred_HYBRIDpred_df.loc[RFCNbbox_RFCNpred_CROPpred_HYBRIDpred_df['image_file'] == image_file,
                                                                       ['image_class', 'NoF', 'ALB', 'BET', 'DOL', 'LAG', 'OTHER', 'SHARK', 'YFT']]
        image_class = test_pred_im_df.iloc[0]['image_class']
        test_pred_im_df.drop('image_class', axis=1, inplace=True)
        max_score = test_pred_im_df.max(axis=1)
        max_cls = test_pred_im_df.idxmax(axis=1)
        test_pred_im_df['max_score'] = max_score
        test_pred_im_df['max_cls'] = max_cls
        test_pred_im_df['Count'] = test_pred_im_df.groupby(['max_cls'])['max_cls'].transform('count')
        idx = test_pred_im_df.groupby(['max_cls'])['max_score'].transform(max) == test_pred_im_df['max_score']
        test_pred_im_clsMax_df = test_pred_im_df.loc[idx,['NoF', 'ALB', 'BET', 'DOL', 'LAG', 'OTHER', 'SHARK', 'YFT', 'Count']]
        test_pred_im_clsMax_array = test_pred_im_clsMax_df.values
        pred = np.average(test_pred_im_clsMax_array[:,:-1], axis=0, weights=test_pred_im_clsMax_array[:,-1], returned=False).tolist()
        if image_class!='--':
            ind = FISH_CLASSES.index(image_class)
            logloss = -math.log(pred[ind]) 
        else:
            logloss = np.nan
        test_pred_im_clsMaxAve = [logloss,image_class,image_file]
        test_pred_im_clsMaxAve.extend(pred)
        test_pred_df.loc[len(test_pred_df)]=test_pred_im_clsMaxAve

    test_pred_df.to_pickle(OUTPUT_DIR+file_name) 
    

image_all_logloss = test_pred_df[test_pred_df['image_class']!='--']['logloss'].mean()
print('imag_all_logloss:', image_all_logloss)

# print(test_pred_df[test_pred_df['image_class']!='--'].groupby('image_class')['logloss'].mean())


Loading from file test_pred_df_Hybrid_weights.084-0.0739.hdf5_.pickle
imag_all_logloss: 0.06455932285959344

In [ ]:
#### visualization
# RFCNbbox_RFCNpred_CROPpred_df = ['image_class', 'image_file','crop_index','x_min','y_min','x_max','ymax',
#                                    'NoF_RFCN', 'ALB_RFCN', 'BET_RFCN', 'DOL_RFCN',
#                                    'LAG_RFCN', 'OTHER_RFCN', 'SHARK_RFCN', 'YFT_RFCN'
#                                    'NoF_CROP', 'ALB_CROP', 'BET_CROP', 'DOL_CROP',
#                                    'LAG_CROP', 'OTHER_CROP', 'SHARK_CROP', 'YFT_CROP']
#GTbbox_CROPpred_df = ['image_file','crop_index','crop_class','xmin','ymin','xmax','ymax',
#                      'NoF', 'ALB', 'BET', 'DOL', 'LAG', 'OTHER', 'SHARK', 'YFT', 'logloss']
# test_pred_df = ['logloss','image_class','image_file','NoF', 'ALB', 'BET', 'DOL', 'LAG', 'OTHER', 'SHARK', 'YFT']

for j in range(test_pred_df.shape[0]):
    image_logloss = test_pred_df.iat[j,0]
    image_class = test_pred_df.iat[j,1]
    image_file = test_pred_df.iat[j,2]
    if j<1000 and j%30== 0:
        pass
    else: 
        continue
    im = Image.open('../RFCN/JPEGImages/'+image_file)
    im = np.asarray(im)
    fig, ax = plt.subplots(figsize=(10, 8))
    ax.imshow(im, aspect='equal')
    RFCN_dets = RFCNbbox_RFCNpred_CROPpred_HYBRIDpred_df.loc[RFCNbbox_RFCNpred_CROPpred_HYBRIDpred_df['image_file']==image_file]
    for index,row in RFCN_dets.iterrows():
        bbox = [row['xmin'],row['ymin'],row['xmax'],row['ymax']]
        RFCN = [row['NoF_RFCN'],row['ALB_RFCN'],row['BET_RFCN'],row['DOL_RFCN'],row['LAG_RFCN'],row['OTHER_RFCN'],row['SHARK_RFCN'],row['YFT_RFCN']]
        CROP = [row['NoF'],row['ALB'],row['BET'],row['DOL'],row['LAG'],row['OTHER'],row['SHARK'],row['YFT']]
        score_RFCN = max(RFCN)
        score_CROP = max(CROP)
        index_RFCN = RFCN.index(score_RFCN)
        index_CROP = CROP.index(score_CROP)
        class_RFCN = FISH_CLASSES[index_RFCN]
        class_CROP = FISH_CLASSES[index_CROP]
        ax.add_patch(plt.Rectangle((bbox[0], bbox[1]), bbox[2] - bbox[0], bbox[3] - bbox[1], fill=False, edgecolor='red', linewidth=2))
        ax.text(bbox[0], bbox[1] - 2, 'RFCN_{:s} {:.3f} \nHYBRID_{:s} {:.3f}'.format(class_RFCN, score_RFCN, class_CROP, score_CROP), bbox=dict(facecolor='red', alpha=0.5), fontsize=8, color='white')       
    GT_dets = GTbbox_CROPpred_df.loc[GTbbox_CROPpred_df['image_file']==image_file]
    for index,row in GT_dets.iterrows():
        bbox = [row['xmin'],row['ymin'],row['xmax'],row['ymax']]
        CROP = [row['NoF'],row['ALB'],row['BET'],row['DOL'],row['LAG'],row['OTHER'],row['SHARK'],row['YFT']]
        score_CROP = max(CROP)
        index_CROP = CROP.index(score_CROP)
        class_CROP = FISH_CLASSES[index_CROP]
        ax.add_patch(plt.Rectangle((bbox[0], bbox[1]), bbox[2] - bbox[0], bbox[3] - bbox[1], fill=False, edgecolor='green', linewidth=2))
        ax.text(bbox[0], bbox[3] + 40, 'GT_{:s} \nCROP_{:s} {:.3f}'.format(row['crop_class'], class_CROP, score_CROP), bbox=dict(facecolor='green', alpha=0.5), fontsize=8, color='white')
    ax.set_title(('Image {:s}    FISH {:s}    logloss {}').format(image_file, image_class, image_logloss), fontsize=10) 
    plt.axis('off')
    plt.tight_layout()
    plt.draw()

In [9]:
#temperature
T = 2.5
test_pred_array = test_pred_df[FISH_CLASSES].values
test_pred_T_array = np.exp(np.log(test_pred_array)/T)
test_pred_T_array = test_pred_T_array/np.sum(test_pred_T_array, axis=1, keepdims=True)
test_pred_T_df = pd.DataFrame(test_pred_T_array, columns=FISH_CLASSES)
test_pred_T_df = pd.concat([test_pred_df[['image_class','image_file']],test_pred_T_df], axis=1)

#test submission
submission = test_pred_T_df.loc[:999,['image_file','NoF', 'ALB', 'BET', 'DOL', 'LAG', 'OTHER', 'SHARK', 'YFT']]
submission.rename(columns={'image_file':'image'}, inplace=True)
sub_file = 'RFCN_AGONOSTICnms_'+RFCN_MODEL+'_'+CROP_MODEL+'_'+test_model_name+'_clsMaxAve_conf{:.2f}_cropvalloss{:.4f}_imageallloss{:.4f}_T{}.csv'.format(CONF_THRESH, crop_valid_woNoF_logloss, image_all_logloss, T)
submission.to_csv(sub_file, index=False)
submission.to_csv(OUTPUT_DIR + sub_file, index=False)
print('Done!'+sub_file)


Done!RFCN_AGONOSTICnms_resnet101_rfcn_ohem_iter_30000_resnet50_FT38_Classifier_Rep5_weights.084-0.0739.hdf5_clsMaxAve_conf0.80_cropvalloss0.1645_imageallloss0.0646_T2.5.csv

In [ ]: