{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Import required dependencies","metadata":{"id":"hYB8Aq8NYbFl"}},{"cell_type":"code","source":"import os\n\nimport numpy as np\nimport pandas as pd\nimport matplotlib.image as mpimg\n\nfrom zipfile import ZipFile\nfrom os import listdir, walk\nfrom os.path import isfile, join\nfrom tensorflow.keras import Input, Model\nfrom tensorflow.keras.applications import ResNet101V2\nfrom tensorflow.keras.applications.imagenet_utils import preprocess_input\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array\nfrom tensorflow.keras.layers import GlobalAveragePooling2D, Dense\nfrom tensorflow.keras.optimizers import Adam","metadata":{"id":"yoPGB38MYdJe","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Preprocessing","metadata":{"id":"xo0DwSJOP-nk"}},{"cell_type":"markdown","source":"## Rescaling and centering the image","metadata":{"id":"tCVR8frMYy3F"}},{"cell_type":"code","source":"IMG_SIZE = 224","metadata":{"id":"2bM-ySTLZOo7","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"datagen = ImageDataGenerator(\n        samplewise_center=True,\n        rescale=1/255.)","metadata":{"id":"dZWoBajmPvBG","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Create data generator","metadata":{"id":"4GI4qIWhY1CD"}},{"cell_type":"code","source":"train_it = datagen.flow_from_directory('../input/dlai5-bad-apples/train/train', \n                                       target_size=(IMG_SIZE, IMG_SIZE), \n                                       color_mode='rgb', \n                                       class_mode=\"categorical\")","metadata":{"id":"okmVK2AqQHII","outputId":"59ffc259-141f-4522-9c5f-8866e3acebc2","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_it = datagen.flow_from_directory('../input/dlai5-bad-apples/test/test', \n                                       target_size=(IMG_SIZE, IMG_SIZE), \n                                       color_mode='rgb', \n                                       class_mode=\"categorical\")","metadata":{"id":"qkB7-tZ2AzBg","outputId":"3b51be25-b53d-4067-c367-18f0725623b5","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Modeling","metadata":{"id":"yI0NXR8FM22J"}},{"cell_type":"markdown","source":"## Choosing base model and freeze it","metadata":{"id":"wbbFK-zCYfJQ"}},{"cell_type":"code","source":"base_model = ResNet101V2(\n    weights='imagenet',\n    input_shape=(IMG_SIZE, IMG_SIZE, 3),\n    include_top=False)\n\nbase_model.trainable = False","metadata":{"id":"Syu9xcdRMuau","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Add new custom layer","metadata":{"id":"wz-sxeZ4Yjfm"}},{"cell_type":"code","source":"inputs = Input(shape=(IMG_SIZE, IMG_SIZE, 3))\n\nx = base_model(inputs, training=False)\nx = GlobalAveragePooling2D()(x)\n\noutputs = Dense(len(train_it.class_indices), activation = 'softmax')(x)\n\nmodel = Model(inputs, outputs)","metadata":{"id":"dAbeKRVpPT7k","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"id":"NFVvNYEiPbaT","outputId":"48d6db3e-f4cf-4d5d-e30f-52c4f6bbd0d4","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Compile a model","metadata":{"id":"3Xu393dCYnIs"}},{"cell_type":"code","source":"model.compile(loss = 'categorical_crossentropy' , optimizer='adam', metrics = [\"accuracy\"])","metadata":{"id":"M__kjTKtPe-x","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Training","metadata":{"id":"wLyd94SWY5n_"}},{"cell_type":"code","source":"epochs = 20\n\nhistory = model.fit(\n    train_it,\n    epochs=epochs,\n    validation_data=valid_it,\n)","metadata":{"id":"YzYiRkQCQvag","outputId":"64d1372e-4297-4b16-9a3f-87642a4c05d4","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Fine-tuning","metadata":{"id":"yaCd5HdUIuNl"}},{"cell_type":"markdown","source":"### Unfreeze some layers","metadata":{"id":"Qv8ZrCemaVHm"}},{"cell_type":"code","source":"base_model.trainable = True\n\nfine_tune_at = 100\n\nfor layer in base_model.layers[:fine_tune_at]:\n  layer.trainable =  False","metadata":{"id":"dphpv6G2IvvX","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(loss = 'categorical_crossentropy' , optimizer=Adam(learning_rate=0.001/10), metrics = [\"accuracy\"])","metadata":{"id":"NjGeEyi8I7KQ","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = 10\nhistory = model.fit(\n    train_it,\n    epochs=epochs,\n    validation_data=valid_it,\n)","metadata":{"id":"e2_JmId7JimC","outputId":"222b0b71-9c17-42de-e5cc-c5ff52aee5e4","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Save model","metadata":{"id":"oRZyWMFoaj6v"}},{"cell_type":"code","source":"model.save('resnet_fine_tuned.h5')","metadata":{"id":"pY0tQKtedsyj","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save('dlai5_resnet_fine_tuned')","metadata":{"id":"pelx3Nx3Q4OM","outputId":"52ecb766-481d-4f5c-b445-381110b7a00f","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"zf = ZipFile(\"model_resnet_fine_tuned.zip\", \"w\")\nfor dirname, subdirs, files in walk(\"dlai5_resnet_fine_tuned\"):\n    zf.write(dirname)\n    for filename in files:\n        zf.write(os.path.join(dirname, filename))\nzf.close()","metadata":{"id":"uS_WFufxeU-i","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prediction","metadata":{"id":"h5k-FtF3aoYv"}},{"cell_type":"code","source":"files = [f for f in listdir('../input/dlai5-bad-apples/validation/validation') if isfile(join('../input/dlai5-bad-apples/validation/validation', f))]","metadata":{"id":"mn5c3OxJgbBm","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"result_dict = {\n    'ID': [],\n    'Code': [],\n}\n\nfor file in files:\n  image = load_img(f'../input/dlai5-bad-apples/validation/validation/{file}', target_size=(IMG_SIZE, IMG_SIZE))\n  image = img_to_array(image)\n  image = image.reshape(1, IMG_SIZE, IMG_SIZE, 3)\n  image = image / 255\n\n  pred = np.argmax(model.predict(image)) + 1\n  result_dict['ID'].append(file)\n  result_dict['Code'].append(pred)","metadata":{"id":"VTNyqXcog3ba","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.DataFrame.from_dict(result_dict)\ndf.to_csv('result_resnet_fine_tuned.csv', index=False)","metadata":{"id":"O6_hdGlHjKym","trusted":true},"execution_count":null,"outputs":[]}]}