{"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":"# **Plant Pathology Analysis with transfer learning(DenseNet 169)**\n* *Data Visualization*\n* *Data Augmentation*\n* *Model training: DenseNet 169*\n* *Prediction*\n* *Submission*","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport numpy as np\nimport os\nimport cv2\nimport pandas as pd\nimport seaborn as sns\nfrom sklearn.metrics import classification_report ","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-04-03T09:00:44.473414Z","iopub.execute_input":"2022-04-03T09:00:44.473877Z","iopub.status.idle":"2022-04-03T09:00:45.390951Z","shell.execute_reply.started":"2022-04-03T09:00:44.473769Z","shell.execute_reply":"2022-04-03T09:00:45.390105Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"^import 하는 부분","metadata":{}},{"cell_type":"code","source":"df=pd.read_csv(\"../input/plant-pathology-2021-fgvc8/train.csv\")\ndf","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:45.392391Z","iopub.execute_input":"2022-04-03T09:00:45.392736Z","iopub.status.idle":"2022-04-03T09:00:45.458992Z","shell.execute_reply.started":"2022-04-03T09:00:45.392701Z","shell.execute_reply":"2022-04-03T09:00:45.458269Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"대회에서 제공하는 파일 읽기","metadata":{}},{"cell_type":"markdown","source":"# *Data Visualization*","metadata":{}},{"cell_type":"markdown","source":"Since each leaves may have more than one disease(e.g.the second leaf in the above image is *scab,frog_eye_leaf_spot,complex*), so it can be a ***multilabel classification***.","metadata":{}},{"cell_type":"code","source":"df['labels'].unique()\n# 1.healthy\n# 2.scab\n# 3.complex\n# 4.rust\n# 5.fog_eye_leaf_spot\n# 6.powdery_mildew","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:45.460677Z","iopub.execute_input":"2022-04-03T09:00:45.461072Z","iopub.status.idle":"2022-04-03T09:00:45.470323Z","shell.execute_reply.started":"2022-04-03T09:00:45.461034Z","shell.execute_reply":"2022-04-03T09:00:45.469397Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['labels']=df['labels'].apply( lambda string: string.split(' ') )\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:45.471954Z","iopub.execute_input":"2022-04-03T09:00:45.47251Z","iopub.status.idle":"2022-04-03T09:00:45.577633Z","shell.execute_reply.started":"2022-04-03T09:00:45.472474Z","shell.execute_reply":"2022-04-03T09:00:45.576813Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import MultiLabelBinarizer\nmlb = MultiLabelBinarizer()\nhot_labels = mlb.fit_transform(df['labels'])\nprint(mlb.classes_)\nprint(hot_labels)","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:45.578825Z","iopub.execute_input":"2022-04-03T09:00:45.579178Z","iopub.status.idle":"2022-04-03T09:00:45.609248Z","shell.execute_reply.started":"2022-04-03T09:00:45.579141Z","shell.execute_reply":"2022-04-03T09:00:45.608507Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"^라벨 이진화","metadata":{}},{"cell_type":"code","source":"df_labels = pd.DataFrame(hot_labels,columns=mlb.classes_,index=df.index)\ndf_labels","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:45.610407Z","iopub.execute_input":"2022-04-03T09:00:45.610742Z","iopub.status.idle":"2022-04-03T09:00:45.623887Z","shell.execute_reply.started":"2022-04-03T09:00:45.610708Z","shell.execute_reply":"2022-04-03T09:00:45.622875Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# *Data Augmentation*\n데이터의 양을 늘리기위해 원본 이미지에 각종 변환을 적용시켜 개수를 증강시키는 기법\n","metadata":{}},{"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\n\ndatagen = ImageDataGenerator(rescale=1/255.0,\n                            rotation_range=5,\n                            zoom_range=0.1,\n                            shear_range=0.05,\n                            horizontal_flip=True,\n                            validation_split=0.2)\n\ntrain_generator = datagen.flow_from_dataframe(\n    df,\n    directory='../input/resized-plant2021/img_sz_256',\n    subset='training',\n    x_col='image',\n    y_col='labels',\n    target_size=(224,224),\n    color_mode='rgb',\n    class_mode='categorical',\n    batch_size=32,\n    shuffle=True,\n    seed=444\n    )\n#'../input/plant-pathology-2021-fgvc8/train_images'\nvalid_generator = datagen.flow_from_dataframe(\n    df,\n    directory='../input/resized-plant2021/img_sz_256',\n    subset='validation',\n    x_col='image',\n    y_col='labels',\n    target_size=(224,224),\n    color_mode='rgb',\n    class_mode='categorical',\n    batch_size=32,\n    shuffle=True,\n    seed=444\n    )","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:45.625361Z","iopub.execute_input":"2022-04-03T09:00:45.626087Z","iopub.status.idle":"2022-04-03T09:00:47.492794Z","shell.execute_reply.started":"2022-04-03T09:00:45.626051Z","shell.execute_reply":"2022-04-03T09:00:47.489144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# *Transfer Learning: DenseNet 169*","metadata":{}},{"cell_type":"code","source":"from tensorflow.keras.applications import InceptionResNetV2\nfrom tensorflow.keras.applications import MobileNetV2\nfrom tensorflow.keras.applications import DenseNet121\nfrom tensorflow.keras.applications import DenseNet169\n\nimport keras\nfrom keras.layers import Dense,Dropout,Flatten\nfrom tensorflow.keras.layers import GlobalAveragePooling2D\nfrom keras.models import Model\nfrom tensorflow.keras.callbacks import EarlyStopping\nimport tensorflow_addons as tfa\n\nweight_path='../input/tf-keras-pretrained-model-weights/No Top/densenet169_weights_tf_dim_ordering_tf_kernels_notop.h5'\nbase_model=DenseNet169(weights=weight_path,include_top=False, input_shape=(224,224,3))\nx=base_model.output\nx=GlobalAveragePooling2D()(x)\nx=Dense(128,activation='relu')(x)\nx=Dropout(0.2)(x)\nx=Dense(64,activation='relu')(x)\npredictions=Dense(6,activation='sigmoid')(x)\n\nmodel=Model(inputs=base_model.input,outputs=predictions)\n\nfor layer in base_model.layers:\n    layer.trainable=False\n","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:47.49376Z","iopub.status.idle":"2022-04-03T09:00:47.494148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"trian the last few layers and the ouput layers first","metadata":{}},{"cell_type":"code","source":"metrics = [       \n        keras.metrics.CategoricalAccuracy(name='accuracy'),\n        keras.metrics.Precision(name='precision'),\n        keras.metrics.Recall(name='recall')\n    ]\n\nf1 = tfa.metrics.F1Score(num_classes=6,average='macro')\nes=EarlyStopping(patience=4,monitor=f1,mode='max',restore_best_weights=True)\n","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:47.495365Z","iopub.status.idle":"2022-04-03T09:00:47.495813Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"freeze the trained layers, then train the second and the third dense block in DenseNet169","metadata":{}},{"cell_type":"code","source":"model.layers[595:]","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:47.497332Z","iopub.status.idle":"2022-04-03T09:00:47.497891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for layer in model.layers[:595]:\n    layer.trainable=False\n\nfor layer in model.layers[143:]:\n    layer.trainable=True\n\nfor layer in model.layers[595:]:\n    layer.trainable=False\n    \nmodel.summary()\n\nmodel.compile(optimizer='adam', loss='binary_crossentropy',metrics=[metrics,f1])\nhistory = model.fit_generator(generator=train_generator,\n                    validation_data=valid_generator,\n                    epochs=200,\n                    steps_per_epoch=train_generator.samples//128,\n                    validation_steps=valid_generator.samples//128,\n                    callbacks=[es])","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:47.49933Z","iopub.status.idle":"2022-04-03T09:00:47.499894Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# 각 평균값 출력\n\narr1 = history.history['loss']\nresult1 = sum(arr1)\nprint(f\"loss_av : {result1 / len(arr1)}\")\n\narr2 = history.history['accuracy']\nresult2 = sum(arr2)\nprint(f\"accuracy_av : {result2 / len(arr2)}\")\n\narr3 = history.history['precision']\nresult3 = sum(arr3)\nprint(f\"precision_av : {result3 / len(arr3)}\")\n\narr4 = history.history['recall']\nresult4 = sum(arr4)\nprint(f\"recall_av : {result4 / len(arr4)}\")","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:47.501173Z","iopub.status.idle":"2022-04-03T09:00:47.501754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# accuracy\nplt.figure(figsize=(15,12))\nplt.rc('font', size=20)   \nepoch_list = list(range(1, len(history.history['accuracy'])+1))\nplt.plot(epoch_list, history.history['accuracy'],label='accuracy')\nplt.xlabel('epoches')\nplt.ylabel('accuracy')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:47.503119Z","iopub.status.idle":"2022-04-03T09:00:47.503665Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# loss\nplt.figure(figsize=(15,12))\nplt.rc('font', size=20)   \nepoch__list = list(range(1,len(history.history['loss'])+1))\nplt.plot(epoch__list, history.history['loss'],label='loss')\nplt.xlabel('epoches')\nplt.ylabel('loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:47.505039Z","iopub.status.idle":"2022-04-03T09:00:47.505604Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# precision\nplt.figure(figsize=(15,12))\nplt.rc('font', size=20)   \nepoch__list = list(range(1,len(history.history['precision'])+1))\nplt.plot(epoch__list, history.history['precision'],label='precision')\nplt.xlabel('epoches')\nplt.ylabel('precision')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:47.506888Z","iopub.status.idle":"2022-04-03T09:00:47.507466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# recall\nplt.figure(figsize=(15,12))\nplt.rc('font', size=20)   \nepoch__list = list(range(1,len(history.history['recall'])+1))\nplt.plot(epoch__list, history.history['recall'],label='recall')\nplt.xlabel('epoches')\nplt.ylabel('recall')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:47.508755Z","iopub.status.idle":"2022-04-03T09:00:47.509325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# f1  score\nplt.figure(figsize=(15,12))\nplt.rc('font', size=20)   \nepoch__list = list(range(1,len(history.history['f1_score'])+1))\nplt.plot(epoch__list, history.history['f1_score'],label='f1_score')\nplt.xlabel('epoches')\nplt.ylabel('f1')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:47.51057Z","iopub.status.idle":"2022-04-03T09:00:47.511148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#model.save('plant_incepresnetv2.h5')","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:47.51246Z","iopub.status.idle":"2022-04-03T09:00:47.513018Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# *Prediction*","metadata":{}},{"cell_type":"code","source":"test_path=\"../input/plant-pathology-2021-fgvc8/sample_submission.csv\"\ntest = pd.read_csv(test_path)\ntest","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:47.514281Z","iopub.status.idle":"2022-04-03T09:00:47.514826Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_data = datagen.flow_from_dataframe(\n    test,\n    directory='../input/plant-pathology-2021-fgvc8/test_images',\n    x_col='image',\n    y_col=None,\n    color_mode='rgb',\n    target_size=(224,224),\n    class_mode=None,\n    shuffle=False\n)\npredictions = model.predict(test_data)\nprint(predictions)\n\nclass_idx=[]\nfor pred in predictions:\n    pred=list(pred)\n    temp=[]\n    for i in pred:\n        if (i>0.4):\n            temp.append(pred.index(i))\n    if (temp!=[]):\n        class_idx.append(temp)\n    else:\n        temp.append(np.argmax(pred))\n        class_idx.append(temp)\nprint(class_idx)","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:47.516333Z","iopub.status.idle":"2022-04-03T09:00:47.517005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_dict = train_generator.class_indices\ndef get_key(val):\n    for key,value in class_dict.items():\n        if (val==value):\n            return key\nprint(class_dict)\n\nsub_pred=[]\nfor img_ in class_idx:\n    img_pred=[]\n    for i in img_:\n        img_pred.append(get_key(i))\n    sub_pred.append( ' '.join(img_pred))\nprint(sub_pred)","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:47.518285Z","iopub.status.idle":"2022-04-03T09:00:47.518857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# *Submission*","metadata":{}},{"cell_type":"code","source":"sub = test[['image']]\nsub['labels']=sub_pred\nsub","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:47.52011Z","iopub.status.idle":"2022-04-03T09:00:47.520663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub.to_csv('submission.csv',index=False)","metadata":{"execution":{"iopub.status.busy":"2022-04-03T09:00:47.521994Z","iopub.status.idle":"2022-04-03T09:00:47.522589Z"},"trusted":true},"execution_count":null,"outputs":[]}]}