{"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 2021 - FGVC8","metadata":{}},{"cell_type":"markdown","source":"A competição teve por objetivo encontrar doenças que acometem plantas, mais especificamente folhas de macieiras, através de imagens RGB de alta qualidade.","metadata":{}},{"cell_type":"markdown","source":"A métrica de avaliação utilizada na competição é a F1 Score, definida como a média harmônica entre a precisão e a sensibilidade.","metadata":{}},{"cell_type":"markdown","source":"### Importando pacotes","metadata":{}},{"cell_type":"code","source":"import keras\nimport numpy as np\nimport tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras import layers\nfrom tensorflow.keras import models\nimport tensorflow_hub as hub\nfrom tensorflow.keras.models import load_model\nimport tensorflow_addons as tfa\nimport json\nfrom keras.models import Sequential\nfrom keras.layers import Conv2D, MaxPool2D, Flatten, Dense, Dropout, BatchNormalization\nimport pandas as pd\npd.set_option('display.max_columns', None)\nimport os\nimport matplotlib.pyplot as plt\n%matplotlib inline\nimport seaborn as sns\nsns.set(style=\"whitegrid\")\nfrom PIL import Image\nimport warnings\nwarnings.filterwarnings('ignore')\nfrom sklearn.model_selection import train_test_split","metadata":{"execution":{"iopub.status.busy":"2022-10-25T01:14:08.243321Z","iopub.execute_input":"2022-10-25T01:14:08.243843Z","iopub.status.idle":"2022-10-25T01:14:17.123500Z","shell.execute_reply.started":"2022-10-25T01:14:08.243741Z","shell.execute_reply":"2022-10-25T01:14:17.122143Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Carregando os dados","metadata":{}},{"cell_type":"code","source":"data_path = '../input/plant-pathology-2021-fgvc8'\nlabels_file_path = os.path.join(data_path, 'train.csv')\ntrain_images_path = os.path.join(data_path, 'train_images')\ntest_images_path = os.path.join(data_path, 'test_images')\nsubmission = pd.read_csv('../input/plant-pathology-2021-fgvc8/sample_submission.csv')\ntrain_df = pd.read_csv(labels_file_path)\ntrain_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:57:09.180612Z","iopub.execute_input":"2022-10-25T00:57:09.180970Z","iopub.status.idle":"2022-10-25T00:57:09.208381Z","shell.execute_reply.started":"2022-10-25T00:57:09.180938Z","shell.execute_reply":"2022-10-25T00:57:09.207247Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels=np.zeros((18632,6))\nlabels=pd.DataFrame(columns=[\"healthy\",\"scab\",\"frog_eye_leaf_spot\",\n                             \"complex\",\"rust\",\"powdery_mildew\"],data=labels)\nfor i in range(train_df.shape[0]):\n    full_lab=train_df.loc[i,\"labels\"]\n    for j in range(6):\n        lab=labels.columns[j]\n        if lab in full_lab:\n            labels.loc[i,lab]=1\n\n","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:57:11.280950Z","iopub.execute_input":"2022-10-25T00:57:11.281322Z","iopub.status.idle":"2022-10-25T00:57:12.864827Z","shell.execute_reply.started":"2022-10-25T00:57:11.281290Z","shell.execute_reply":"2022-10-25T00:57:12.863858Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Análise Exploratória","metadata":{}},{"cell_type":"markdown","source":"Possuímos então 18632 imagens no total","metadata":{}},{"cell_type":"code","source":"train_df.shape","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:58:25.282240Z","iopub.execute_input":"2022-10-25T00:58:25.283281Z","iopub.status.idle":"2022-10-25T00:58:25.290429Z","shell.execute_reply.started":"2022-10-25T00:58:25.283227Z","shell.execute_reply":"2022-10-25T00:58:25.289315Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df['labels'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:58:26.372930Z","iopub.execute_input":"2022-10-25T00:58:26.373297Z","iopub.status.idle":"2022-10-25T00:58:26.384268Z","shell.execute_reply.started":"2022-10-25T00:58:26.373268Z","shell.execute_reply":"2022-10-25T00:58:26.383107Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Possuímos então 5 diferentes tipos de doença:\n\n- Scab\n- Frogeye leaf spot\n- Rust\n- Complex\n- Powdery mildew\n\nAlgumas combinações entre elas existem, como Scab com Frogeye Leaf Spot","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(15,12))\nlabelz = sns.barplot(train_df.labels.value_counts().index,train_df.labels.value_counts(),palette=\"turbo\")\nfor item in labelz.get_xticklabels():\n    item.set_rotation(90)","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:58:39.439977Z","iopub.execute_input":"2022-10-25T00:58:39.440712Z","iopub.status.idle":"2022-10-25T00:58:39.760962Z","shell.execute_reply.started":"2022-10-25T00:58:39.440672Z","shell.execute_reply":"2022-10-25T00:58:39.760035Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualizando as imagens","metadata":{}},{"cell_type":"code","source":"def show_image(class_name = 'healthy', examples=2):\n    image_list = train_df[train_df['labels'] == class_name]['image'].sample(frac=1)[:examples].to_list()\n    plt.figure(figsize=(20,10))\n    for i, img in enumerate(image_list):\n        full_path = os.path.join(train_images_path, img)\n        img = Image.open(full_path)\n        plt.subplot(1 ,examples, i%examples +1)\n        plt.axis('off')\n        plt.imshow(img)\n        plt.title(class_name)\n","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:58:46.058304Z","iopub.execute_input":"2022-10-25T00:58:46.058654Z","iopub.status.idle":"2022-10-25T00:58:46.066955Z","shell.execute_reply.started":"2022-10-25T00:58:46.058625Z","shell.execute_reply":"2022-10-25T00:58:46.065830Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Healthy","metadata":{}},{"cell_type":"code","source":"show_image('healthy', examples = 3)","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:59:18.307954Z","iopub.execute_input":"2022-10-25T00:59:18.308928Z","iopub.status.idle":"2022-10-25T00:59:22.838246Z","shell.execute_reply.started":"2022-10-25T00:59:18.308886Z","shell.execute_reply":"2022-10-25T00:59:22.837040Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Scab","metadata":{}},{"cell_type":"code","source":"show_image('scab', examples = 3)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Rust","metadata":{}},{"cell_type":"code","source":"show_image('rust', examples = 3)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Complex","metadata":{}},{"cell_type":"code","source":"show_image('complex', examples = 3)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Frogeye Leaf Spot","metadata":{}},{"cell_type":"code","source":"show_image('frog_eye_leaf_spot', examples = 3)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Powdery Mildew","metadata":{}},{"cell_type":"code","source":"show_image('powdery_mildew', examples = 3)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Pré-Processamento","metadata":{}},{"cell_type":"code","source":"labels.index = train_df.index\ntrain_df.head()\ntrain_df.drop(\"labels\",axis=1,inplace=True)\n","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:41:14.290840Z","iopub.execute_input":"2022-10-25T00:41:14.291219Z","iopub.status.idle":"2022-10-25T00:41:14.301518Z","shell.execute_reply.started":"2022-10-25T00:41:14.291185Z","shell.execute_reply":"2022-10-25T00:41:14.298603Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data=pd.concat([train_df,labels],axis=1)","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:41:14.937495Z","iopub.execute_input":"2022-10-25T00:41:14.938029Z","iopub.status.idle":"2022-10-25T00:41:14.944651Z","shell.execute_reply.started":"2022-10-25T00:41:14.937990Z","shell.execute_reply":"2022-10-25T00:41:14.943570Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_datagen = ImageDataGenerator(rescale = 1./255.,\n                                   samplewise_center=True, \n                                   samplewise_std_normalization=True,\n                                   validation_split = 0.2)","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:41:16.099463Z","iopub.execute_input":"2022-10-25T00:41:16.100149Z","iopub.status.idle":"2022-10-25T00:41:16.105719Z","shell.execute_reply.started":"2022-10-25T00:41:16.100091Z","shell.execute_reply":"2022-10-25T00:41:16.104795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_datagen = ImageDataGenerator(rescale = 1./255.,\n                                   samplewise_center=True, \n                                   samplewise_std_normalization=True,\n                                   validation_split = 0.2)\n\ntrain_generator = train_datagen.flow_from_dataframe(dataframe = data,\n                                                   directory = '../input/resized-plant2021/img_sz_256',\n                                                   target_size = (256,256),\n                                                   x_col = 'image',\n                                                   y_col = list(labels.columns),\n                                                   batch_size = 32,\n                                                   color_mode = 'rgb',\n                                                   class_mode = 'raw',\n                                                   subset = 'training')\n\ntest_generator = train_datagen.flow_from_dataframe(dataframe = data,\n                                                 directory = '../input/resized-plant2021/img_sz_256',\n                                                 target_size = (256,256),\n                                                 x_col = 'image',\n                                                 y_col = list(labels.columns),\n                                                 batch_size = 32,\n                                                 color_mode = 'rgb',\n                                                 class_mode = 'raw',\n                                                 subset = 'validation')","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:41:16.960408Z","iopub.execute_input":"2022-10-25T00:41:16.961046Z","iopub.status.idle":"2022-10-25T00:41:43.157489Z","shell.execute_reply.started":"2022-10-25T00:41:16.961005Z","shell.execute_reply":"2022-10-25T00:41:43.156422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# TensorFlow Hub","metadata":{}},{"cell_type":"markdown","source":"#### O TF Hub é um repositório de modelos pré-treinados com diversos propósitos: áudio, imagens, vídeos e texto.","metadata":{}},{"cell_type":"markdown","source":"A rede utilizada neste exemplo, EfficientNet V2 21k L, pode ser encontrada em: https://tfhub.dev/google/collections/efficientnet_v2/1\n","metadata":{}},{"cell_type":"markdown","source":"# Carregando Modelo e Pesos","metadata":{}},{"cell_type":"code","source":"weights_v2 = \"../input/efficientnetv2model/EfficientNet_V2.h5\"\nhub_url = \"../input/efficientnetv2-tfhub-weight-files/tfhub_models/efficientnetv2-l-21k-ft1k/feature_vector\"","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:42:22.193992Z","iopub.execute_input":"2022-10-25T00:42:22.194382Z","iopub.status.idle":"2022-10-25T00:42:22.199685Z","shell.execute_reply.started":"2022-10-25T00:42:22.194350Z","shell.execute_reply":"2022-10-25T00:42:22.198529Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_v2():\n    model = tf.keras.Sequential([\n            tf.keras.layers.InputLayer(input_shape = [256, 256, 3]),\n            hub.KerasLayer(hub_url, trainable = False),\n            Dropout(0.35, name = \"top_dropout\"),\n            Dense(6, activation = 'sigmoid')\n        ])\n    model.build((256, 256, 3))\n    return model","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:46:02.588827Z","iopub.execute_input":"2022-10-25T00:46:02.589227Z","iopub.status.idle":"2022-10-25T00:46:02.595146Z","shell.execute_reply.started":"2022-10-25T00:46:02.589193Z","shell.execute_reply":"2022-10-25T00:46:02.594169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_v2 = load_v2()\nmodel_v2.load_weights(weights_v2)","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:46:04.235212Z","iopub.execute_input":"2022-10-25T00:46:04.235939Z","iopub.status.idle":"2022-10-25T00:46:29.015005Z","shell.execute_reply.started":"2022-10-25T00:46:04.235896Z","shell.execute_reply":"2022-10-25T00:46:29.013890Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_v2.summary()","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:46:29.017793Z","iopub.execute_input":"2022-10-25T00:46:29.018192Z","iopub.status.idle":"2022-10-25T00:46:29.050013Z","shell.execute_reply.started":"2022-10-25T00:46:29.018155Z","shell.execute_reply":"2022-10-25T00:46:29.049070Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_v2.compile(optimizer= tf.keras.optimizers.Adam(learning_rate=0.001),\n                loss=tfa.losses.SigmoidFocalCrossEntropy(),\n                metrics=[tf.keras.metrics.AUC(multi_label=True), \n                         tfa.metrics.F1Score(num_classes=6, average='micro')])","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:46:34.286797Z","iopub.execute_input":"2022-10-25T00:46:34.287397Z","iopub.status.idle":"2022-10-25T00:46:34.305713Z","shell.execute_reply.started":"2022-10-25T00:46:34.287361Z","shell.execute_reply":"2022-10-25T00:46:34.304481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Treinando apenas a camada criada","metadata":{}},{"cell_type":"code","source":"history = model_v2.fit(train_generator, validation_data=test_generator, epochs=5)","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:46:35.953343Z","iopub.execute_input":"2022-10-25T00:46:35.953793Z","iopub.status.idle":"2022-10-25T00:54:19.839250Z","shell.execute_reply.started":"2022-10-25T00:46:35.953755Z","shell.execute_reply":"2022-10-25T00:54:19.836633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Gerando submissão","metadata":{}},{"cell_type":"code","source":"test_datagen = ImageDataGenerator(\n    rescale = 1./255\n)\nINPUT_SIZE = (256,256,3)\ntest_generator =  test_datagen.flow_from_dataframe(\n    submission,\n    directory=\"../input/plant-pathology-2021-fgvc8/test_images\",\n    x_col='image',\n    y_col=None,\n    class_mode=None,\n    target_size=INPUT_SIZE[:2]\n)","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:38:18.874934Z","iopub.status.idle":"2022-10-25T00:38:18.875354Z","shell.execute_reply.started":"2022-10-25T00:38:18.875114Z","shell.execute_reply":"2022-10-25T00:38:18.875136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = model_v2.predict(test_generator) \npredtest = []\nlabeltest = []\npossible = [\"healthy\",\"scab\",\"frog_eye_leaf_spot\",\n            \"complex\",\"rust\",\"powdery_mildew\"]\n\n\nfor row in preds:\n    placeholder = 0\n    for cell in row:\n        if cell >= placeholder:\n            placeholder = cell\n    predtest.append(np.where(preds == placeholder)[1][0].astype(int))\nfor index in predtest:\n    labeltest.append(possible[index])","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:38:18.876849Z","iopub.status.idle":"2022-10-25T00:38:18.877213Z","shell.execute_reply.started":"2022-10-25T00:38:18.877023Z","shell.execute_reply":"2022-10-25T00:38:18.877046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission['labels'] = labeltest\nsubmission.head()","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:38:18.878985Z","iopub.status.idle":"2022-10-25T00:38:18.879686Z","shell.execute_reply.started":"2022-10-25T00:38:18.879482Z","shell.execute_reply":"2022-10-25T00:38:18.879506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2022-10-25T00:38:18.881506Z","iopub.execute_input":"2022-10-25T00:38:18.882601Z","iopub.status.idle":"2022-10-25T00:38:18.898574Z","shell.execute_reply.started":"2022-10-25T00:38:18.882569Z","shell.execute_reply":"2022-10-25T00:38:18.897165Z"},"trusted":true},"execution_count":null,"outputs":[]}]}