{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# LB 0.486\n# simple cnn\n\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.applications import resnet50\nfrom keras import models\nfrom keras import layers\nfrom keras import optimizers\nfrom keras.engine.topology import Input\nfrom keras.callbacks import ModelCheckpoint, CSVLogger, TensorBoard\n\nimport os\nimport matplotlib.pyplot as plt\nimport pandas as pd\nimport numpy as np\n\nimport argparse\n\n# settings\nbase_dir='../input'\nmodel_base_dir = 'models'\ntest_dir = os.path.join(base_dir, 'test')\ntrain_dir=os.path.join(base_dir, 'train')\nvalidation_dir=os.path.join(base_dir, 'validation')\n# paramater\nbatch_size=32\nSEED=1470\nepochs=50\ninput_size = 224\n\ndef split_with_class_count(df, validation_split=0.1, class_count=1):\n    df = pd.read_csv(os.path.join(base_dir, 'train.csv'))\n    df = df[df.Id != 'new_whale']\n    classes = df['Id'].unique()\n    df['count'] = df.groupby('Id')['Id'].transform('count')\n    fdf = df[df['count'] >= class_count]\n    val_classes = fdf['Id'].unique()\n    train_df = pd.DataFrame(columns=fdf.columns)\n    validation_df = pd.DataFrame(columns=fdf.columns)\n    for val_class in val_classes:\n      class_df = fdf[fdf.Id == val_class]\n      validation = class_df.sample(frac=validation_split, random_state=SEED)\n      validation_df = pd.concat([validation_df, validation]) \n      train = class_df.drop(validation.index)\n      train_df = pd.concat([train_df, train]) \n    train_df = train_df.drop('count', axis=1)\n    train_df = train_df.reset_index()\n    validation_df = validation_df.drop('count', axis=1)\n    validation_df = validation_df.reset_index()\n    return train_df, validation_df, classes.tolist()\n\ndef load_data():\n    df = pd.read_csv(os.path.join(base_dir, 'train.csv'))\n    df = df[df.Id != 'new_whale'] # without new_whale\n    train_df, validation_df, classes = split_with_class_count(df, validation_split=0.01, class_count=50)\n    datagen = ImageDataGenerator(\n        rescale=1./255,\n        horizontal_flip=True,\n        rotation_range=30,\n        width_shift_range=0.2,\n        height_shift_range=0.2,\n        shear_range=0.2,\n        brightness_range=[0.7, 1.0],\n    )\n    train_generator = datagen.flow_from_dataframe(\n        dataframe=df,\n        directory=train_dir,\n        x_col='Image',\n        y_col='Id',\n        target_size=(input_size, input_size),\n        batch_size=batch_size,\n        classes=classes,\n        seed=SEED,\n    )\n    datagen = ImageDataGenerator(\n        rescale=1./255,\n    )\n    val_generator = datagen.flow_from_dataframe(\n        dataframe=validation_df,\n        directory=train_dir,\n        x_col='Image',\n        y_col='Id', \n        target_size=(input_size, input_size),\n        batch_size=20,\n        classes=classes,\n        seed=SEED,\n    )\n    return train_generator, val_generator\n","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true,"scrolled":false},"cell_type":"code","source":"from keras import regularizers\nclass ModelV7():\n    def __init__(self):\n        self.name = 'v7'\n    def get_model(self):\n        conv_base = resnet50.ResNet50(weights='imagenet',\n                                      include_top=False,\n                                      input_shape=(input_size, input_size, 3))\n        for layer in conv_base.layers[:]:\n            if 'BatchNormalization' in str(layer):\n                layer.trainable = True\n            else:\n                layer.trainable = False\n        main_input = conv_base.input\n        embedding = conv_base.output\n        x = layers.GlobalMaxPooling2D()(embedding)\n        x = layers.Dropout(0.5)(x)\n        x = layers.Dense(4096, activation='relu', kernel_regularizer=regularizers.l2(0.01))(x)\n        x = layers.BatchNormalization()(x)\n        x = layers.Dropout(0.5)(x)\n        x = layers.Dense(5004, activation='softmax')(x)\n        model = models.Model(inputs=[main_input], outputs=[x])\n        model.compile(\n            loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])\n        return model\n\ndef load_classes():\n    train_generator, val_generator = load_data()\n    return np.array([c for c, v in train_generator.class_indices.items()])\n\ndef load_test_data():\n    datagen = ImageDataGenerator(\n        rescale=1./255,\n    )\n    test_generator = datagen.flow_from_dataframe(\n        pd.DataFrame(os.listdir(test_dir),columns=['filename']),\n        test_dir,\n        target_size=(input_size, input_size),\n        batch_size=1,\n        class_mode=None,\n        shuffle=False,\n        seed=SEED,\n    )\n\n    if len(test_generator) == 0:\n        print('Train data not found')\n        exit()\n    return test_generator\n\ndef predict(model, generator):\n    kth = 5\n    generator.reset()\n    pred = model.predict_generator(generator, steps=len(generator), verbose=1)\n    classes = load_classes()\n    classify_index = np.argpartition(-pred, kth)[:, :kth]\n    classify_value = pred[np.arange(pred.shape[0])[:, None], classify_index]\n    best_5_pred = np.zeros((len(classify_index), 5))\n    best_5_class = np.zeros((len(classify_index), 5), dtype='int32')\n    for i, p in enumerate(classify_value):\n        sort_index = np.argsort(p)[::-1]\n        best_5_pred[i] = (p[sort_index])\n        best_5_class[i] = (classify_index[i][sort_index])\n    # create output\n    submit = pd.DataFrame(columns=['Image', 'Id'])\n    for i, p in enumerate(best_5_pred):\n        submit_classes = []\n        if p[0] < 0.55:\n            submit_classes.append('new_whale')\n            submit_classes.extend(classes[best_5_class[i]][0:4])\n        elif p[1] < 0.4 :\n            submit_classes.extend(classes[best_5_class[i]][0:1])\n            submit_classes.append('new_whale')\n            submit_classes.extend(classes[best_5_class[i]][1:4])\n        elif p[2] < 0.1 :\n            submit_classes.extend(classes[best_5_class[i]][0:2])\n            submit_classes.append('new_whale')\n            submit_classes.extend(classes[best_5_class[i]][2:4])\n        elif p[3] < 0.05 :\n            submit_classes.extend(classes[best_5_class[i]][0:3])\n            submit_classes.append('new_whale')\n            submit_classes.extend(classes[best_5_class[i]][3:4])\n        else:\n            submit_classes.extend(classes[best_5_class[i]])\n        classes_text = ' '.join(submit_classes)\n        submit = submit.append(pd.Series(np.array([generator.filenames[i], classes_text]), index=submit.columns), ignore_index=True)\n    return submit\n\n\nif __name__ == '__main__':\n        epochs = 25\n        train_generator, val_generator = load_data()\n        steps_per_epochs = len(train_generator)\n        model_wrapper = ModelV7()\n        model = model_wrapper.get_model()\n        model.summary()\n\n        model_dir = os.path.join(model_base_dir, 'without_whale' + model_wrapper.name)\n\n        os.makedirs(model_dir, exist_ok=True)\n\n        model_checkpoint_path = os.path.join(model_dir, '{epoch:02d}-{loss:.2f}-{val_loss:.2f}.hdf5')\n        model_checkpoint = ModelCheckpoint(model_checkpoint_path, monitor='val_acc', verbose=1, save_best_only=True)\n        tensor_board = TensorBoard(log_dir=os.path.join(model_dir))\n        history = model.fit_generator(\n            train_generator,\n            steps_per_epoch=steps_per_epochs,\n            epochs=epochs,\n            validation_data=val_generator,\n            validation_steps=50,\n        )\n\n        # load test data\n        test_generator = load_test_data()\n        # predict\n        submit = predict(model, test_generator)\n        submit.to_csv('submit4.csv', index=False)\n\n        ","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}