{"cells":[{"metadata":{},"cell_type":"markdown","source":"# 아이디어 적용을 위한 기본 모델\n* 다양한 테스트의 적용 가능성을 실험하기 위하여 속도가 빠른 MobileNet을 활용한 모델을 사용합니다\n* 공통 모델의 기본점수를 바탕으로 각종 아이디어를 적용하여 점수 향상에 유효한지를 검토하기 위한 용도로 사용됩니다"},{"metadata":{"trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd \nimport os\nprint(os.listdir(\"../input\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import gc\nimport os\nimport warnings\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm\n\nfrom keras import backend as K\nwarnings.filterwarnings(action='ignore')\n\nK.image_data_format()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"DATA_PATH = '../input'\nos.listdir(DATA_PATH)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"TRAIN_IMG_PATH = os.path.join(DATA_PATH,'train')\nTEST_IMG_PATH = os.path.join(DATA_PATH,'test')\n\ndf_train = pd.read_csv(os.path.join(DATA_PATH, 'train.csv'))\ndf_test = pd.read_csv(os.path.join(DATA_PATH, 'test.csv'))\ndf_class=pd.read_csv(os.path.join(DATA_PATH, 'class.csv'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train.shape, df_test.shape, df_class.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_train.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if set(list(df_train.img_file)) == set(os.listdir(TRAIN_IMG_PATH)):\n    print(\"ok\")\nelse : \n    print(\"is null\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if set(list(df_test.img_file)) == set(os.listdir(TEST_IMG_PATH)):\n    print(\"ok\")\nelse : \n    print(\"is null\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Number of Train Data : {}\".format(df_train.shape[0]))\nprint(\"Number of Test Data : {}\".format(df_test.shape[0]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_class.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Number of Target : {}\".format(df_class.shape[0]))\nprint(\"Varierty of Train Data Target : {}\".format(df_train['class'].nunique()))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cntEachClass = df_train['class'].value_counts(ascending=False)\nprint(\"class of most count : {}\".format(cntEachClass.index[0]))\nprint(\"num of most count : {}\".format(cntEachClass[cntEachClass.index[0]]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"class of least count : {}\".format(cntEachClass.index[-1]))\nprint(\"num of least count : {}\".format(cntEachClass[cntEachClass.index[-1]]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Mean : {}\".format(cntEachClass.mean()))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import PIL\nfrom PIL import ImageDraw\n\ntmp_imgs = df_train['img_file'][100:104]\nplt.figure(figsize=(12,20))\n\nfor num, f_name in enumerate(tmp_imgs):\n    img = PIL.Image.open(os.path.join(TRAIN_IMG_PATH, f_name))\n    plt.subplot(5,2, num+1)\n    plt.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def draw_rect(drawcontext, pos, outline=None, width=0):\n    (x1, y1) = (pos[0], pos[1])\n    (x2, y2) = (pos[2], pos[3])\n    points = (x1,y1), (x2,y1), (x2,y2), (x1,y2), (x1,y1)\n    drawcontext.line(points, fill=outline, width=width)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def make_boxing_img(img_name):\n    if img_name.split('_')[0] == \"train\":\n        PATH = TRAIN_IMG_PATH\n        data = df_train\n    elif img_name.split('_')[0] == \"test\":\n        PATH = TEST_IMG_PATH\n        data = df_test\n    \n    img = PIL.Image.open(os.path.join(PATH, img_name))\n    pos = data.loc[data[\"img_file\"] == img_name, \\\n                  ['bbox_x1','bbox_y1','bbox_x2','bbox_y2']].values.reshape(-1)\n    draw = ImageDraw.Draw(img)\n    draw_rect(draw, pos, outline='red',width=10)\n    \n    return img","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"f_name = \"train_00102.jpg\"\n\nplt.figure(figsize=(12,10))\nplt.subplot(1,2,1)\n\norigin_img = PIL.Image.open(os.path.join(TRAIN_IMG_PATH, f_name))\nplt.imshow(origin_img)\n\nplt.subplot(1,2,2)\nboxing = make_boxing_img(f_name)\nplt.imshow(boxing)\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Cropping"},{"metadata":{"trusted":true},"cell_type":"code","source":"def crop_boxing_img(img_name, margin=16):\n    if img_name.split('_')[0] == \"train\":\n        PATH = TRAIN_IMG_PATH\n        data = df_train\n    elif img_name.split('_')[0] == \"test\":\n        PATH = TEST_IMG_PATH\n        data = df_test\n        \n    img = PIL.Image.open(os.path.join(PATH, img_name))\n    pos = data.loc[data[\"img_file\"] == img_name, ['bbox_x1','bbox_y1','bbox_x2','bbox_y2']].values.reshape(-1)\n    \n    width , height = img.size\n    x1 = max(0, pos[0] - margin)\n    y1 = max(0, pos[1] - margin)\n    x2 = min(pos[2] + margin, width)\n    y2 = min(pos[3] + margin, height)\n    \n    if abs(pos[2] - pos[0]) > width or abs(pos[3] - pos[1]) > height:\n        print(f'{img_name} is wrong bounding box, img size : {img.size}, bbox_x1 : {pos[0]}, bbox_x2 : {pos[2]}, bbox_y1 : {pos[1]}, bbox_y2 : {pos[3]}')\n        \n        return img\n    return img.crop((x1,y1,x2,y2)).resize((224,224))              ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"TRAIN_CROP_PATH = \"./train_crop\"\nTEST_CROP_PATH = \"./test_crop\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!mkdir {TRAIN_CROP_PATH}\n!mkdir {TEST_CROP_PATH}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# for train img\nfor i, row in df_train.iterrows():\n    PATH = TRAIN_CROP_PATH\n    cropped = crop_boxing_img(row['img_file'])\n    cropped.save(os.path.join(PATH, row['img_file']))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# for test img\nfor i, row in df_test.iterrows():\n    PATH = TEST_CROP_PATH\n    cropped = crop_boxing_img(row['img_file'])\n    cropped.save(os.path.join(PATH, row['img_file']))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tmp_imgs = df_train['img_file'][100:102]\nplt.figure(figsize=(12,10))\n\nfor num, f_name in enumerate(tmp_imgs):\n    img = PIL.Image.open(os.path.join(TRAIN_IMG_PATH, f_name))\n    plt.subplot(2, 2, 2*num +1)\n    plt.title(f_name)\n    plt.imshow(img)\n    plt.axis('off')\n    \n    \n    img_crop = PIL.Image.open(os.path.join(TRAIN_CROP_PATH, f_name))\n    plt.subplot(2, 2, 2*num +2)\n    plt.title(f_name + ' cropped')\n    plt.imshow(img_crop)\n    plt.axis('off')\n    print(\"Size of Original image : {}\\nSize of image after cropping : {}\".format(img.size,img_crop.size)) # crop된 후 image의 size","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tmp_imgs = df_test['img_file'][100:102]\nplt.figure(figsize=(12,10))\n\nfor num, f_name in enumerate(tmp_imgs):\n    img = PIL.Image.open(os.path.join(TEST_IMG_PATH, f_name))\n    plt.subplot(2, 2, 2*num +1)\n    plt.title(f_name)\n    plt.imshow(img)\n    plt.axis('off')\n    \n    \n    img_crop = PIL.Image.open(os.path.join(TEST_CROP_PATH, f_name))\n    plt.subplot(2, 2, 2*num +2)\n    plt.title(f_name + ' cropped')\n    plt.imshow(img_crop)\n    plt.axis('off')\n    print(\"Size of Original image : {}\\nSize of image after cropping : {}\".format(img.size,img_crop.size)) # crop된 후 image의 size","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\ndf_train['class'] = df_train['class'].astype('str')\n\ndf_train = df_train[['img_file','class']]\ndf_test = df_test[['img_file']]\n\nits = np.arange(df_train.shape[0])\ntrain_idx, val_idx = train_test_split(its, train_size = 0.8, random_state=42)\n\nX_train = df_train.iloc[train_idx, :]\nX_val = df_train.iloc[val_idx, :]\n\nprint(X_train.shape, X_val.shape, df_test.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications.mobilenet import MobileNet, preprocess_input\nfrom keras.preprocessing.image import ImageDataGenerator\n\nimg_size = (224, 224)\nnb_train_samples = len(X_train)\nnb_validation_samples = len(X_val)\nnb_test_samples = len(df_test)\nepochs = 12\nbatch_size = 32\n\ntrain_datagen = ImageDataGenerator(\n    horizontal_flip = True,\n    vertical_flip = False,\n    zoom_range = 0.1,\n    preprocessing_function = preprocess_input)\n\nval_datagen = ImageDataGenerator(\n    preprocessing_function=preprocess_input)\ntest_datagen = ImageDataGenerator(\n    preprocessing_function=preprocess_input)\n\ntrain_generator = train_datagen.flow_from_dataframe(\n    dataframe = X_train,\n    directory = TRAIN_CROP_PATH,\n    x_col = 'img_file',\n    y_col = 'class',\n    target_size = img_size,\n    color_mode = 'rgb',\n    class_mode = 'categorical',\n    batch_size=batch_size,\n    seed = 42\n)\n\nvalidation_generator = val_datagen.flow_from_dataframe(\n    dataframe = X_val,\n    directory = TRAIN_CROP_PATH,\n    x_col = 'img_file',\n    y_col = 'class',\n    target_size = img_size,\n    color_mode = 'rgb',\n    class_mode = 'categorical',\n    batch_size=batch_size,\n    shuffle=False\n)\n\ntest_generator = test_datagen.flow_from_dataframe(\n    dataframe = df_test,\n    directory = TEST_CROP_PATH,\n    x_col = 'img_file',\n    y_col = None,\n    target_size = img_size,\n    color_mode = 'rgb',\n    class_mode = None,\n    batch_size=batch_size,\n    shuffle=False\n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# apply mobilenet"},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.models import Sequential, Model\nfrom keras.layers import Dense, Dropout, Flatten, Activation, Conv2D, GlobalAveragePooling2D","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"mobilenetmodel = MobileNet(weights='imagenet', input_shape = (224,224,3), include_top = False)\nmodel = Sequential()\nmodel.add(mobilenetmodel)\nmodel.add(GlobalAveragePooling2D())\nmodel.add(Dense(196, activation='softmax', kernel_initializer='he_normal'))\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Use f1_score"},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras import backend as K\n\ndef recall_m(y_true, y_pred):\n        true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))\n        possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))\n        recall = true_positives / (possible_positives + K.epsilon())\n        return recall\n\ndef precision_m(y_true, y_pred):\n        true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))\n        predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1)))\n        precision = true_positives / (predicted_positives + K.epsilon())\n        return precision\n    \ndef f1_m(y_true, y_pred):\n    precision = precision_m(y_true, y_pred)\n    recall = recall_m(y_true, y_pred)\n    return 2*((precision*recall)/(precision+recall+K.epsilon()))\n\nmodel.compile(optimizer='adam', loss='categorical_crossentropy', metrics=[f1_m])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def get_steps(num_samples, batch_size):\n    if (num_samples % batch_size)>0:\n        return (num_samples // batch_size) + 1\n    else :\n        return num_samples // batch_size","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# save bestweight"},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\nfrom keras.callbacks import ModelCheckpoint, EarlyStopping, ReduceLROnPlateau\n\nfilepath = \"best_weight.h5\"\n\nmc = ModelCheckpoint(filepath = filepath, monitor = 'val_f1_m', verbose = 1, save_best_only=True, mode = 'max')\ncallbackList = [mc]\n\nhistory = model.fit_generator(\n    train_generator,\n    steps_per_epoch = get_steps(nb_train_samples, batch_size),\n    epochs = epochs,\n    validation_data = validation_generator,\n    validation_steps = get_steps(nb_validation_samples, batch_size),\n    callbacks = callbackList\n)\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(history.history['f1_m'])\nplt.plot(history.history['val_f1_m'])\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Use best weights"},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\ntest_generator.reset()\nmodel.load_weights('best_weight.h5')\nprediction = model.predict_generator(\n    generator = test_generator,\n    steps = get_steps(nb_test_samples, batch_size),\n    verbose=1\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"prediction","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_generator.class_indices","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predicted_class_indices = np.argmax(prediction, axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = (train_generator.class_indices)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dict((v,k) for k,v in labels.items())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = dict((v,k) for k,v in labels.items())\npredictions = [labels[k] for k in predicted_class_indices]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = pd.read_csv(os.path.join(DATA_PATH, 'sample_submission.csv'))\nsubmission['class'] = predictions\nsubmission.to_csv(\"submission.csv\", index=False)\nsubmission.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!rm -rf {TRAIN_CROP_PATH}\n!rm -rf {TEST_CROP_PATH}","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}