{"cells":[{"metadata":{"trusted":true},"cell_type":"code","source":"os.listdir('../input/')","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"import gc\nimport os\nimport warnings\n\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n\nfrom keras import backend as K\nK.image_data_format()\n\nwarnings.filterwarnings(action='ignore')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"DATA_PATH = '../input/'\nCROP_PATH = '../3rd-ml-month-car-image-cropping-dataset/'\n\nTRAIN_IMG_PATH = os.path.join(DATA_PATH, 'train')\nTEST_IMG_PATH = os.path.join(DATA_PATH, 'test')\n\nTRAIN_CROP_PATH = os.path.join(CROP_PATH, 'train_crop')\nTEST_CROP_PATH = os.path.join(CROP_PATH, 'test_crop')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"!mkdir {CROP_PATH}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df = pd.read_csv(os.path.join(DATA_PATH, 'train.csv'))\ntest_df = pd.read_csv(os.path.join(DATA_PATH, 'test.csv'))\nclass_df = pd.read_csv(os.path.join(DATA_PATH, 'class.csv'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(train_df.shape)\ntrain_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_df.describe()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(26, 12))\nax = sns.countplot(train_df['class'])\nax.set_xticklabels(ax.get_xticklabels(), rotation=90, ha=\"right\")\nplt.title(\"Number of data per each class\")\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def crop_resize_boxing_img(img_name, margin=16, size=(224, 224)) :\n    if img_name.split('_')[0] == \"train\" :\n        PATH = TRAIN_IMG_PATH\n        data = train_df\n    elif img_name.split('_')[0] == \"test\" :\n        PATH = TEST_IMG_PATH\n        data = test_df\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\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    return img.crop((x1,y1,x2,y2)).resize(size).convert('LA')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from skimage import color\nfrom skimage import io\n\nimg = color.rgb2gray(io.imread(os.path.join(TRAIN_IMG_PATH, f_name)))\nplt.imshow(img, cmap=plt.get_cmap('gray'), vmin=0, vmax=1)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"img = PIL.Image.open(os.path.join(TRAIN_IMG_PATH, f_name)).convert('LA')\nimg","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import PIL\n\nfor i, row in train_df.iterrows():\n    cropped = crop_resize_boxing_img(row['img_file'])\n    cropped.save(f\"{CROP_PATH}/{row['img_file']}\")\n    break","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import PIL\nfrom PIL import ImageDraw\n\ntmp_imgs = train_df['img_file'][20: 30]\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.title(f_name)\n    plt.imshow(img)\n    plt.axis('off')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\ntrain_df['class'] = train_df['class'].astype('str')\n\n# 여기서는 Bounding Box를 쓰지 않을 것임으로 좌표 컬럼 삭제\ntrain_df = train_df[['img_file', 'class']]\ntest_df = test_df[['img_file']]\n\nits = np.arange(train_df.shape[0])\n\ntrain_idx, val_idx = train_test_split(its, train_size=0.8, random_state=43)\n\ntrain_X = train_df.iloc[train_idx, :]\nval_X = train_df.iloc[val_idx, :]\n\nprint(train_X.shape)\nprint(val_X.shape)\nprint(test_df.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.applications.resnet50 import ResNet50, preprocess_input\nfrom keras.preprocessing.image import ImageDataGenerator\n\nimg_size = (224, 224)\nnb_train_samples = len(train_X)\nnb_validation_samples = len(val_X)\nbn_test_samples = len(test_df)\nepochs = 20\nbatch_size = 32\n\ntrain_datagen = ImageDataGenerator(\n    horizontal_flip=True,\n    vertical_flip=False,\n    zoom_range=0.10,\n    rotation_range= 20,\n    fill_mode='nearest',\n    preprocessing_function=preprocess_input\n)\n\nval_datagen = ImageDataGenerator(preprocessing_function=preprocess_input)\ntest_datagen = ImageDataGenerator(preprocessing_function=preprocess_input)\n\n\n# Make Generator\ntrain_generator = train_datagen.flow_from_dataframe(\n    dataframe=train_X,\n    directory=TRAIN_IMG_PATH,\n    x_col='img_file',\n    y_col='class',\n    target_size=img_size,\n    color_mode='grayscale',\n    class_mode='categorical',\n    batch_size=batch_size,\n    seed=42\n)\n\nvalidation_generator = val_datagen.flow_from_dataframe(\n    dataframe=val_X, \n    directory=TRAIN_IMG_PATH,\n    x_col = 'img_file',\n    y_col = 'class',\n    target_size = img_size,\n    color_mode='grayscale',\n    class_mode='categorical',\n    batch_size=batch_size,\n    shuffle=False\n)\n\ntest_generator = test_datagen.flow_from_dataframe(\n    dataframe=test_df,\n    directory=TEST_IMG_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":{"trusted":true},"cell_type":"code","source":"# resNet_model = ResNet50(include_top=False, input_shape = (224,224,3))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.models import Sequential, Model\nfrom keras.layers import Dense, Dropout, Flatten, Activation, Conv2D, GlobalAveragePooling2D\nfrom keras.applications.mobilenet import MobileNet, preprocess_input\n\n# model = Sequential()\n# model.add(resNet_model)\n# model.add(GlobalAveragePooling2D())\n# model.add(Dense(1024, activation='relu'))\n# model.add(Dropout(0.5))\n# model.add(Dense(196, activation='softmax', kernel_initializer='he_normal'))\n# model.summary()\n\nmobilenetModel = MobileNet(weights='imagenet', include_top=False)\n\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":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['acc'])","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":{"trusted":true},"cell_type":"code","source":"%%time\nfrom keras.callbacks import ModelCheckpoint, EarlyStopping\n\nfilepath = \"my_resnet_model_{val_acc:.2f}_{val_loss:.4f}.h5\"\n\nckpt = ModelCheckpoint(filepath, monitor='val_acc', verbose=1, save_best_only=True)\nes = EarlyStopping(monitor='val_acc', min_delta=0, patience=3, verbose=1, mode='auto')\n\ncallbackList = [ckpt]\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)\n\ngc.collect()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"acc = history.history['acc']\nval_acc = history.history['val_acc']\nloss = history.history['loss']\nval_loss = history.history['val_loss']\n\nepochs = range(1, len(acc) + 1)\n\nplt.plot(epochs, acc, 'bo', label='Training Acc')\nplt.plot(epochs, val_acc, 'b', label='Validation Acc')\nplt.title('Training and validation accuracy')\nplt.legend()\nplt.show()\n\nplt.plot(epochs, loss, 'bo', label='Traing loss')\nplt.plot(epochs, val_loss, 'b', label='Validation loss')\nplt.title('Trainging and validation loss')\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}