{"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":"### Instalando e importando as bibliotecas necessárias","metadata":{"id":"1XvcaAzr2rjY"}},{"cell_type":"code","source":"import os\nimport gc\nimport re\n\nimport cv2\nimport math\nimport numpy as np\nimport scipy as sp\nimport pandas as pd\n\nimport tensorflow as tf\nfrom IPython.display import SVG\n#import efficientnet.tfkeras as efn\n#from keras.utils import plot_model\nimport tensorflow.keras.layers as L\n#from keras.utils import model_to_dot\nimport tensorflow.keras.backend as K\n#from tensorflow.keras.models import Model\nfrom kaggle_datasets import KaggleDatasets\nfrom tensorflow.keras.applications import DenseNet121\n\nimport seaborn as sns\nfrom tqdm import tqdm\nimport matplotlib.cm as cm\nfrom sklearn import metrics\nimport matplotlib.pyplot as plt\nfrom sklearn.utils import shuffle\nfrom sklearn.model_selection import train_test_split\n\ntqdm.pandas()\nimport plotly.express as px\nimport plotly.graph_objects as go\nimport plotly.figure_factory as ff\nfrom plotly.subplots import make_subplots\n\nnp.random.seed(0)\ntf.random.set_seed(0)\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","id":"y4ElXcLopnKO","outputId":"72756d56-48f2-46c7-d8d0-56ec9fc395ce","execution":{"iopub.status.busy":"2022-07-26T21:38:14.720133Z","iopub.execute_input":"2022-07-26T21:38:14.720904Z","iopub.status.idle":"2022-07-26T21:38:18.396444Z","shell.execute_reply.started":"2022-07-26T21:38:14.720849Z","shell.execute_reply":"2022-07-26T21:38:18.395401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Carregar os dados e definir hiperparâmetros","metadata":{"id":"DyZKLcDg2yRi"}},{"cell_type":"code","source":"EPOCHS = 20\nSAMPLE_LEN = 100\nIMAGE_PATH = \"../input/plant-pathology-2020-fgvc7/images/\"\nTEST_PATH = \"../input/plant-pathology-2020-fgvc7/test.csv\"\nTRAIN_PATH = \"../input/plant-pathology-2020-fgvc7/train.csv\"\nSUB_PATH = \"../input/plant-pathology-2020-fgvc7/sample_submission.csv\"\n\nsub = pd.read_csv(SUB_PATH)\ntest_data = pd.read_csv(TEST_PATH)\ntrain_data = pd.read_csv(TRAIN_PATH)","metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","id":"mneU8D9bpnKS","execution":{"iopub.status.busy":"2022-07-26T21:38:23.629936Z","iopub.execute_input":"2022-07-26T21:38:23.630254Z","iopub.status.idle":"2022-07-26T21:38:23.681569Z","shell.execute_reply.started":"2022-07-26T21:38:23.630225Z","shell.execute_reply":"2022-07-26T21:38:23.680925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data.head()","metadata":{"id":"lSXP0xubpnKW","outputId":"80d177b3-cf7d-4088-90ff-149edfb86295","execution":{"iopub.status.busy":"2022-07-26T21:38:29.403066Z","iopub.execute_input":"2022-07-26T21:38:29.403828Z","iopub.status.idle":"2022-07-26T21:38:29.427968Z","shell.execute_reply.started":"2022-07-26T21:38:29.403793Z","shell.execute_reply":"2022-07-26T21:38:29.427175Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_data.head()","metadata":{"id":"XISwCeBjpnKa","outputId":"61f70add-a4df-452e-feee-f0ffe0dfac14","execution":{"iopub.status.busy":"2022-07-26T21:38:32.166700Z","iopub.execute_input":"2022-07-26T21:38:32.167847Z","iopub.status.idle":"2022-07-26T21:38:32.176787Z","shell.execute_reply.started":"2022-07-26T21:38:32.167803Z","shell.execute_reply":"2022-07-26T21:38:32.176067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Carregar imagens de amostra","metadata":{"id":"O6DgMHJz293K"}},{"cell_type":"code","source":"def load_image(image_id):\n    file_path = image_id + \".jpg\"\n    image = cv2.imread(IMAGE_PATH + file_path)\n    return cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n\ntrain_images = train_data[\"image_id\"][:SAMPLE_LEN].progress_apply(load_image)","metadata":{"id":"uJD4JbtHpnKd","outputId":"afb14520-4a05-4f26-e7bc-96a86b3f478c","execution":{"iopub.status.busy":"2022-07-26T21:38:34.959912Z","iopub.execute_input":"2022-07-26T21:38:34.960679Z","iopub.status.idle":"2022-07-26T21:38:40.067542Z","shell.execute_reply.started":"2022-07-26T21:38:34.960643Z","shell.execute_reply":"2022-07-26T21:38:40.066663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualizar uma folha <a id=\"1.2\"></a>","metadata":{"id":"aI1QC_K-3HjL"}},{"cell_type":"markdown","source":"### Imagem de amostra","metadata":{"id":"UY_1XspN3Afg"}},{"cell_type":"code","source":"fig = px.imshow(cv2.resize(train_images[0], (205, 136)))\nfig.show()","metadata":{"_kg_hide-input":true,"id":"LNXpowwwpnKg","outputId":"7a677746-3d36-4b54-d201-63474cefb493","execution":{"iopub.status.busy":"2022-07-26T21:38:45.123256Z","iopub.execute_input":"2022-07-26T21:38:45.125850Z","iopub.status.idle":"2022-07-26T21:38:46.055382Z","shell.execute_reply.started":"2022-07-26T21:38:45.125808Z","shell.execute_reply":"2022-07-26T21:38:46.052318Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Eu plotei a primeira imagem nos dados de treinamento acima (os valores RGB podem ser vistos passando o mouse sobre a imagem). As partes verdes da imagem têm valores de azul muito baixos, mas, por outro lado, as partes marrons têm valores de azul altos. Isso sugere que as partes verdes (saudáveis) da imagem têm valores de azul baixos, enquanto as partes não saudáveis ​​são mais propensas a ter valores de azul altos. **Isso pode sugerir que o canal azul pode ser a chave para detectar doenças em plantas.**\n","metadata":{"id":"6iwEoQ90WnnA"}},{"cell_type":"markdown","source":"## Distribuições de canais <a id=\"1.3\"></a>","metadata":{"id":"JGNq3QwJ3vs9"}},{"cell_type":"code","source":"red_values = [np.mean(train_images[idx][:, :, 0]) for idx in range(len(train_images))]\ngreen_values = [np.mean(train_images[idx][:, :, 1]) for idx in range(len(train_images))]\nblue_values = [np.mean(train_images[idx][:, :, 2]) for idx in range(len(train_images))]\nvalues = [np.mean(train_images[idx]) for idx in range(len(train_images))]","metadata":{"_kg_hide-input":true,"id":"SKlfmsiR3yVn","execution":{"iopub.status.busy":"2022-07-26T21:38:52.449726Z","iopub.execute_input":"2022-07-26T21:38:52.450385Z","iopub.status.idle":"2022-07-26T21:38:54.217363Z","shell.execute_reply.started":"2022-07-26T21:38:52.450321Z","shell.execute_reply":"2022-07-26T21:38:54.216631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Todos os valores do canal","metadata":{"id":"cluIike23zBw"}},{"cell_type":"code","source":"fig = ff.create_distplot([values], group_labels=[\"Channels\"], colors=[\"purple\"])\nfig.update_layout(showlegend=False, template=\"simple_white\")\nfig.update_layout(title_text=\"Distribuição de valores de canal\")\nfig.data[0].marker.line.color = 'rgb(0, 0, 0)'\nfig.data[0].marker.line.width = 0.5\nfig","metadata":{"_kg_hide-input":true,"id":"Eb32WiwY34At","execution":{"iopub.status.busy":"2022-07-26T21:38:59.290272Z","iopub.execute_input":"2022-07-26T21:38:59.290947Z","iopub.status.idle":"2022-07-26T21:38:59.451004Z","shell.execute_reply.started":"2022-07-26T21:38:59.290905Z","shell.execute_reply":"2022-07-26T21:38:59.450191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Os valores do canal parecem ter uma distribuição aproximadamente normal centrada em torno de 105. A ativação máxima do canal é 255. Isso significa que o valor médio do canal é menor que a metade do valor máximo, o que indica que os canais são ativados minimamente na maioria das vezes.","metadata":{"id":"Xr1kMIFtVAB_"}},{"cell_type":"markdown","source":"### Valores do canal vermelho","metadata":{"id":"utld_a6W37SB"}},{"cell_type":"code","source":"fig = ff.create_distplot([red_values], group_labels=[\"R\"], colors=[\"red\"])\nfig.update_layout(showlegend=False, template=\"simple_white\")\nfig.update_layout(title_text=\"Distribuição dos valores do canal vermelho\")\nfig.data[0].marker.line.color = 'rgb(0, 0, 0)'\nfig.data[0].marker.line.width = 0.5\nfig","metadata":{"_kg_hide-input":true,"id":"jDIqxHgj3_zj","execution":{"iopub.status.busy":"2022-07-26T21:39:07.336065Z","iopub.execute_input":"2022-07-26T21:39:07.337044Z","iopub.status.idle":"2022-07-26T21:39:07.392802Z","shell.execute_reply.started":"2022-07-26T21:39:07.337003Z","shell.execute_reply":"2022-07-26T21:39:07.392185Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Os valores do canal vermelho parecem uma distribuição aproximadamente normal, mas com uma ligeira inclinação para a direita (inclinação positiva). Isso indica que o canal vermelho tende a ser mais concentrado em valores mais baixos, em torno de 100. Há grande variação nos valores médios de vermelho entre as imagens.","metadata":{"id":"r6HLx5fYVDIi"}},{"cell_type":"markdown","source":"### Valores do canal verde","metadata":{"id":"7Gr6JXgg4QAo"}},{"cell_type":"code","source":"fig = ff.create_distplot([green_values], group_labels=[\"G\"], colors=[\"green\"])\nfig.update_layout(showlegend=False, template=\"simple_white\")\nfig.update_layout(title_text=\"Distribuição dos valores do canal verde\")\nfig.data[0].marker.line.color = 'rgb(0, 0, 0)'\nfig.data[0].marker.line.width = 0.5\nfig","metadata":{"_kg_hide-input":true,"id":"75DRD2Jy4Sp-","execution":{"iopub.status.busy":"2022-07-26T21:39:10.736599Z","iopub.execute_input":"2022-07-26T21:39:10.736907Z","iopub.status.idle":"2022-07-26T21:39:10.794711Z","shell.execute_reply.started":"2022-07-26T21:39:10.736880Z","shell.execute_reply":"2022-07-26T21:39:10.793901Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Os valores do canal verde têm uma distribuição mais uniforme do que os valores do canal vermelho, com um pico menor. A distribuição também tem uma inclinação para a esquerda (em contraste com o vermelho) e uma moda maior em torno de 140. Isso indica que o verde é mais pronunciado nestas imagens do que o vermelho, o que faz sentido, pois são imagens de folhas!","metadata":{"id":"nkpWr3JTVTQe"}},{"cell_type":"markdown","source":"### Valores do canal azul","metadata":{"id":"Dqs2zNPC4ZkG"}},{"cell_type":"code","source":"fig = ff.create_distplot([blue_values], group_labels=[\"B\"], colors=[\"blue\"])\nfig.update_layout(showlegend=False, template=\"simple_white\")\nfig.update_layout(title_text=\"Distribuição dos valores do canal azul\")\nfig.data[0].marker.line.color = 'rgb(0, 0, 0)'\nfig.data[0].marker.line.width = 0.5\nfig","metadata":{"_kg_hide-input":true,"id":"03Sp06S54bpy","execution":{"iopub.status.busy":"2022-07-26T21:39:18.543257Z","iopub.execute_input":"2022-07-26T21:39:18.543698Z","iopub.status.idle":"2022-07-26T21:39:18.602785Z","shell.execute_reply.started":"2022-07-26T21:39:18.543665Z","shell.execute_reply":"2022-07-26T21:39:18.601884Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"O canal azul tem a distribuição mais uniforme dos três canais de cores, com inclinação mínima (leve inclinação para a esquerda). O canal azul mostra uma grande variação entre as imagens no conjunto de dados.","metadata":{"id":"L7dmewbgV4Cg"}},{"cell_type":"markdown","source":"### Todos os valores do canal (juntos)","metadata":{"id":"jjFXtVFM4l0w"}},{"cell_type":"code","source":"fig = go.Figure()\n\nfor idx, values in enumerate([red_values, green_values, blue_values]):\n    if idx == 0:\n        color = \"Red\"\n    if idx == 1:\n        color = \"Green\"\n    if idx == 2:\n        color = \"Blue\"\n    fig.add_trace(go.Box(x=[color]*len(values), y=values, name=color, marker=dict(color=color.lower())))\n    \nfig.update_layout(yaxis_title=\"Valor médio\", xaxis_title=\"Canal de cores\",\n                  title=\"Valor médio vs. Canal de cor\", template=\"plotly_white\")","metadata":{"_kg_hide-input":true,"id":"iUJeF2Ae4oUl","execution":{"iopub.status.busy":"2022-07-26T21:39:22.503810Z","iopub.execute_input":"2022-07-26T21:39:22.504379Z","iopub.status.idle":"2022-07-26T21:39:22.572271Z","shell.execute_reply.started":"2022-07-26T21:39:22.504345Z","shell.execute_reply":"2022-07-26T21:39:22.571368Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = ff.create_distplot([red_values, green_values, blue_values],\n                         group_labels=[\"R\", \"G\", \"B\"],\n                         colors=[\"red\", \"green\", \"blue\"])\nfig.update_layout(title_text=\"Distribuição dos valores do canal\", template=\"simple_white\")\nfig.data[0].marker.line.color = 'rgb(0, 0, 0)'\nfig.data[0].marker.line.width = 0.5\nfig.data[1].marker.line.color = 'rgb(0, 0, 0)'\nfig.data[1].marker.line.width = 0.5\nfig.data[2].marker.line.color = 'rgb(0, 0, 0)'\nfig.data[2].marker.line.width = 0.5\nfig","metadata":{"_kg_hide-input":true,"id":"2x8aqxw04o8u","execution":{"iopub.status.busy":"2022-07-26T21:39:28.697810Z","iopub.execute_input":"2022-07-26T21:39:28.698525Z","iopub.status.idle":"2022-07-26T21:39:28.780801Z","shell.execute_reply.started":"2022-07-26T21:39:28.698486Z","shell.execute_reply":"2022-07-26T21:39:28.779958Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"A partir dos gráficos acima, podemos ver claramente quais cores são mais comuns e quais menos comuns nas imagens das folhas. O verde é a cor mais pronunciada, seguida do vermelho e do azul, respectivamente. As distribuições, quando plotadas juntas, parecem ter uma forma semelhante, mas deslocadas horizontalmente.","metadata":{"id":"7tUmWvzYWMSs"}},{"cell_type":"markdown","source":"## Visualize folhas de amostra <a id=\"1.4\"></a>\n\nAgora, visualizarei folhas de amostra pertencentes a diferentes categorias no conjunto de dados.","metadata":{"id":"Ee2qutMw3FTP"}},{"cell_type":"code","source":"def visualize_leaves(cond=[0, 0, 0, 0], cond_cols=[\"healthy\"], is_cond=True):\n    if not is_cond:\n        cols, rows = 3, min([3, len(train_images)//3])\n        fig, ax = plt.subplots(nrows=rows, ncols=cols, figsize=(30, rows*20/3))\n        for col in range(cols):\n            for row in range(rows):\n                ax[row, col].imshow(train_images.loc[train_images.index[-row*3-col-1]])\n        return None\n        \n    cond_0 = \"healthy == {}\".format(cond[0])\n    cond_1 = \"scab == {}\".format(cond[1])\n    cond_2 = \"rust == {}\".format(cond[2])\n    cond_3 = \"multiple_diseases == {}\".format(cond[3])\n    \n    cond_list = []\n    for col in cond_cols:\n        if col == \"healthy\":\n            cond_list.append(cond_0)\n        if col == \"scab\":\n            cond_list.append(cond_1)\n        if col == \"rust\":\n            cond_list.append(cond_2)\n        if col == \"multiple_diseases\":\n            cond_list.append(cond_3)\n    \n    data = train_data.loc[:99]\n    for cond in cond_list:\n        data = data.query(cond)\n        \n    images = train_images.loc[list(data.index)]\n    cols, rows = 3, min([3, len(images)//3])\n    \n    fig, ax = plt.subplots(nrows=rows, ncols=cols, figsize=(30, rows*20/3))\n    for col in range(cols):\n        for row in range(rows):\n            ax[row, col].imshow(images.loc[images.index[row*3+col]])\n    plt.show()","metadata":{"_kg_hide-input":true,"id":"mQagns98pnKt","execution":{"iopub.status.busy":"2022-07-26T21:39:37.168115Z","iopub.execute_input":"2022-07-26T21:39:37.168919Z","iopub.status.idle":"2022-07-26T21:39:37.182730Z","shell.execute_reply.started":"2022-07-26T21:39:37.168875Z","shell.execute_reply":"2022-07-26T21:39:37.181885Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Folhas saudáveis","metadata":{"id":"6YBTzqs53VHW"}},{"cell_type":"code","source":"visualize_leaves(cond=[1, 0, 0, 0], cond_cols=[\"healthy\"])","metadata":{"_kg_hide-input":true,"id":"_Gw1CH7bpnLc","outputId":"81b8d1ed-231f-4008-9508-23df527bbc80","execution":{"iopub.status.busy":"2022-07-26T21:39:42.227991Z","iopub.execute_input":"2022-07-26T21:39:42.228871Z","iopub.status.idle":"2022-07-26T21:39:47.767726Z","shell.execute_reply.started":"2022-07-26T21:39:42.228835Z","shell.execute_reply":"2022-07-26T21:39:47.766632Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Nas imagens acima, podemos ver que as folhas saudáveis são completamente verdes, não apresentam manchas ou cicatrizes marrons/amarelas. As folhas saudáveis não têm crostas ou ferrugem.","metadata":{"id":"v7T9CAFoXt9A"}},{"cell_type":"markdown","source":"### Folhas com crosta","metadata":{"id":"lfWbbGfD5ACD"}},{"cell_type":"code","source":"visualize_leaves(cond=[0, 1, 0, 0], cond_cols=[\"scab\"])","metadata":{"_kg_hide-input":true,"id":"cWTEw_JZpnLj","outputId":"d34b44a9-f00b-4942-bd19-c055347fb186","execution":{"iopub.status.busy":"2022-07-26T21:40:02.344516Z","iopub.execute_input":"2022-07-26T21:40:02.345292Z","iopub.status.idle":"2022-07-26T21:40:07.356147Z","shell.execute_reply.started":"2022-07-26T21:40:02.345252Z","shell.execute_reply":"2022-07-26T21:40:07.354732Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Nas imagens acima, podemos ver que as folhas com “casca” apresentam grandes marcas e manchas marrons em toda a folha. A sarna é definida como \"qualquer uma das várias doenças de plantas causadas por fungos ou bactérias e resultando em manchas semelhantes a crostas em frutas, folhas ou raízes. As manchas causadas por tal doença\". As marcas marrons na folha são um sinal dessas infecções bacterianas/fúngicas. Uma vez diagnosticada, a sarna pode ser tratada usando métodos químicos ou não químicos.","metadata":{"id":"qHR_5GsKYQWz"}},{"cell_type":"markdown","source":"### Folhas com ferrugem\n","metadata":{"id":"1doTwr2S5Dxt"}},{"cell_type":"code","source":"visualize_leaves(cond=[0, 0, 1, 0], cond_cols=[\"rust\"])","metadata":{"_kg_hide-input":true,"id":"Xwn6GVaupnLl","outputId":"e109052f-3742-4212-c3bd-ec8fa82d2f0c","execution":{"iopub.status.busy":"2022-07-26T21:40:37.682617Z","iopub.execute_input":"2022-07-26T21:40:37.683429Z","iopub.status.idle":"2022-07-26T21:40:42.604356Z","shell.execute_reply.started":"2022-07-26T21:40:37.683393Z","shell.execute_reply":"2022-07-26T21:40:42.602932Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Nas imagens acima, podemos ver que as folhas com \"ferrugem\" apresentam várias manchas amarelo-acastanhadas em toda a folha. A ferrugem é definida como \"uma doença, especialmente de cereais e outras gramíneas, caracterizada por pústulas de esporos cor de ferrugem nas lâminas e bainhas das folhas afetadas e causada por qualquer um dos vários fungos da ferrugem\". As manchas amarelas são um sinal de infecção por um tipo especial de fungos chamados \"fungos da ferrugem\". A ferrugem também pode ser tratada com vários métodos químicos e não químicos, uma vez diagnosticada.\n","metadata":{"id":"l_0g20pmZk17"}},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"### Folhas com várias doenças","metadata":{"id":"mKALD2vt5G78"}},{"cell_type":"code","source":"visualize_leaves(cond=[0, 0, 0, 1], cond_cols=[\"multiple_diseases\"])","metadata":{"_kg_hide-input":true,"id":"YQm_lj9TpnLo","outputId":"a0568b08-2df5-4275-ce41-1a461d8e0ebd","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Nas imagens acima, podemos ver que as folhas apresentam sintomas de várias doenças, incluindo marcas marrons e manchas amarelas. Estas plantas têm mais de uma das doenças descritas acima.\n","metadata":{"id":"qyG-NpVDahDN"}},{"cell_type":"markdown","source":"## Visualizar alvos <a id=\"1.5\"></a>\n\nAgora, vou visualizar os rótulos e os dados de destino. **Em todos os gráficos abaixo, o azul representa a condição \"desejada\" ou \"saudável\" e o vermelho representa a condição \"indesejada\" ou \"não saudável\".**","metadata":{"id":"yTFIf7dZ5MNe"}},{"cell_type":"markdown","source":"### Todos os rótulos juntos (plotagem paralela)","metadata":{"id":"rTU7Plrb5R2v"}},{"cell_type":"code","source":"fig = px.parallel_categories(train_data[[\"healthy\", \"scab\", \"rust\", \"multiple_diseases\"]], color=\"healthy\", color_continuous_scale=\"sunset\",\\\n                             title=\"Gráfico de categorias paralelas de alvos\")\nfig","metadata":{"_kg_hide-input":true,"id":"vRDHR4G_pnLs","outputId":"7f935b25-2686-447a-bd57-8cd2429b15d2","execution":{"iopub.status.busy":"2022-07-26T21:41:09.904967Z","iopub.execute_input":"2022-07-26T21:41:09.905723Z","iopub.status.idle":"2022-07-26T21:41:10.022411Z","shell.execute_reply.started":"2022-07-26T21:41:09.905675Z","shell.execute_reply":"2022-07-26T21:41:10.021523Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"No gráfico acima, podemos ver a relação entre todas as quatro categorias. Como esperado, é impossível para uma folha saudável (<code>saudável == 1</code>) ter sarna, ferrugem ou várias doenças. Além disso, cada folha insalubre tem uma sarna, ferrugem ou várias doenças. A frequência de cada combinação pode ser vista passando o mouse sobre o gráfico.","metadata":{"id":"POYx63MXcfcQ"}},{"cell_type":"markdown","source":"### Gráfico de pizza","metadata":{}},{"cell_type":"code","source":"fig = go.Figure([go.Pie(labels=train_data.columns[1:],\n           values=train_data.iloc[:, 1:].sum().values)])\nfig.update_layout(title_text=\"Gráfico de pizza de alvos\", template=\"simple_white\")\nfig.data[0].marker.line.color = 'rgb(0, 0, 0)'\nfig.data[0].marker.line.width = 0.5\nfig.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2022-07-26T21:41:15.324364Z","iopub.execute_input":"2022-07-26T21:41:15.324675Z","iopub.status.idle":"2022-07-26T21:41:15.384028Z","shell.execute_reply.started":"2022-07-26T21:41:15.324644Z","shell.execute_reply":"2022-07-26T21:41:15.383172Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"No gráfico de pizza acima, podemos ver que a maioria das folhas no conjunto de dados não está saudável (71,7%). Apenas 5% das plantas têm múltiplas doenças, e \"ferrugem\" e \"casca\" ocupam aproximadamente um terço da torta cada.","metadata":{}},{"cell_type":"markdown","source":"### Distribuição saudável","metadata":{"id":"kJNU54Yy5WST"}},{"cell_type":"code","source":"train_data[\"Healthy\"] = train_data[\"healthy\"].apply(bool).apply(str)\nfig = px.histogram(train_data, x=\"Healthy\", title=\"Distribuição saudável\", color=\"Healthy\",\\\n            color_discrete_map={\n                \"True\": px.colors.qualitative.Plotly[0],\n                \"False\": px.colors.qualitative.Plotly[1]})\nfig.update_layout(template=\"simple_white\")\nfig.data[0].marker.line.color = 'rgb(0, 0, 0)'\nfig.data[0].marker.line.width = 0.5\nfig.data[1].marker.line.color = 'rgb(0, 0, 0)'\nfig.data[1].marker.line.width = 0.5\nfig","metadata":{"_kg_hide-input":true,"id":"lriYl3yXpnLv","outputId":"08bbe74b-5853-41e2-824e-e58adecfcb6b","execution":{"iopub.status.busy":"2022-07-26T21:41:19.287640Z","iopub.execute_input":"2022-07-26T21:41:19.288235Z","iopub.status.idle":"2022-07-26T21:41:19.441551Z","shell.execute_reply.started":"2022-07-26T21:41:19.288200Z","shell.execute_reply":"2022-07-26T21:41:19.440607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Podemos ver que há mais plantas não saudáveis (<code>saudável == 0</code>) do que saudáveis (<code>saudável == 1</code>). Existem 1305 (72%) plantas não saudáveis e 516 (28%) plantas saudáveis.","metadata":{"id":"qewm9cFSes3y"}},{"cell_type":"markdown","source":"### Distribuição de sarna","metadata":{"id":"wDb-wmeA5ZMa"}},{"cell_type":"code","source":"train_data[\"Scab\"] = train_data[\"scab\"].apply(bool).apply(str)\nfig = px.histogram(train_data, x=\"Scab\", color=\"Scab\", title=\"Distribuição de sarna\",\\\n            color_discrete_map={\n                \"True\": px.colors.qualitative.Plotly[1],\n                \"False\": px.colors.qualitative.Plotly[0]})\nfig.update_layout(template=\"simple_white\")\nfig.data[0].marker.line.color = 'rgb(0, 0, 0)'\nfig.data[0].marker.line.width = 0.5\nfig.data[1].marker.line.color = 'rgb(0, 0, 0)'\nfig.data[1].marker.line.width = 0.5\nfig","metadata":{"_kg_hide-input":true,"id":"AL3UmfaZpnLy","outputId":"61a61499-c8d0-41f5-af0c-8b0dd4bd9b93","execution":{"iopub.status.busy":"2022-07-26T21:41:28.897864Z","iopub.execute_input":"2022-07-26T21:41:28.898550Z","iopub.status.idle":"2022-07-26T21:41:29.019424Z","shell.execute_reply.started":"2022-07-26T21:41:28.898512Z","shell.execute_reply":"2022-07-26T21:41:29.018551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Podemos ver que há mais plantas sem sarna (<code>scab == 0</code>) do que aquelas com sarna (<code>scab == 1</code>). Existem 592 (33%) plantas insalubres e 1229 (67%) plantas sadias.","metadata":{"id":"Q3s0XzhwfOc-"}},{"cell_type":"markdown","source":"### Distribuição de ferrugem","metadata":{"id":"fJ0g_MRy5bQb"}},{"cell_type":"code","source":"train_data[\"Rust\"] = train_data[\"rust\"].apply(bool).apply(str)\nfig = px.histogram(train_data, x=\"Rust\", color=\"Rust\", title=\"Distribuição de ferrugem\",\\\n            color_discrete_map={\n                \"True\": px.colors.qualitative.Plotly[1],\n                \"False\": px.colors.qualitative.Plotly[0]})\nfig.update_layout(template=\"simple_white\")\nfig.data[0].marker.line.color = 'rgb(0, 0, 0)'\nfig.data[0].marker.line.width = 0.5\nfig.data[1].marker.line.color = 'rgb(0, 0, 0)'\nfig.data[1].marker.line.width = 0.5\nfig","metadata":{"_kg_hide-input":true,"id":"EamjMT0JpnL0","outputId":"4d6633ec-c3ff-409f-aa0f-90cb7a690fc0","execution":{"iopub.status.busy":"2022-07-26T21:41:35.991480Z","iopub.execute_input":"2022-07-26T21:41:35.992141Z","iopub.status.idle":"2022-07-26T21:41:36.113004Z","shell.execute_reply.started":"2022-07-26T21:41:35.992102Z","shell.execute_reply":"2022-07-26T21:41:36.112235Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Podemos ver que há mais plantas sem ferrugem (<code>ferrugem == 0</code>) do que com ferrugem (<code>ferrugem == 1</code>). Existem 622 (34%) plantas não saudáveis e 1199 (66%) plantas saudáveis. Podemos ver que a porcentagem de \"insalubridade\" é muito semelhante tanto para ferrugem quanto para crosta.","metadata":{"id":"7EWabO690nSX"}},{"cell_type":"markdown","source":"### Distribuição de várias doenças","metadata":{"id":"S0t3SEpB5dcS"}},{"cell_type":"code","source":"train_data[\"Multiple diseases\"] = train_data[\"multiple_diseases\"].apply(bool).apply(str)\nfig = px.histogram(train_data, x=\"Multiple diseases\", color=\"Multiple diseases\", title=\"Distribuição de várias doenças\",\\\n            color_discrete_map={\n                \"True\": px.colors.qualitative.Plotly[1],\n                \"False\": px.colors.qualitative.Plotly[0]})\nfig.update_layout(template=\"simple_white\")\nfig.data[0].marker.line.color = 'rgb(0, 0, 0)'\nfig.data[0].marker.line.width = 0.5\nfig.data[1].marker.line.color = 'rgb(0, 0, 0)'\nfig.data[1].marker.line.width = 0.5\nfig","metadata":{"_kg_hide-input":true,"id":"9gYSWOl0pnL3","outputId":"29b0bdaf-d509-4436-a98a-628f1818341f","execution":{"iopub.status.busy":"2022-07-26T21:41:40.168931Z","iopub.execute_input":"2022-07-26T21:41:40.169501Z","iopub.status.idle":"2022-07-26T21:41:40.289573Z","shell.execute_reply.started":"2022-07-26T21:41:40.169465Z","shell.execute_reply":"2022-07-26T21:41:40.288736Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Podemos ver que pouquíssimas folhas têm múltiplas doenças (é uma ocorrência muito grande). Existem 91 (5%) plantas insalubres e 1730 (95%) plantas saudáveis.","metadata":{"id":"GDgVIT2p2YrZ"}},{"cell_type":"markdown","source":"# Processamento e aumento de imagem <a id=\"2\"></a>","metadata":{"id":"aiPKQDkh5hF5"}},{"cell_type":"markdown","source":"## Detecção de borda inteligente <a id=\"2.1\"></a>\n\nCanny é um algoritmo popular de detecção de bordas e, como o nome sugere, detecta as bordas dos objetos presentes em uma imagem. Foi desenvolvido por John F. Canny em 1986. O algoritmo envolve várias etapas.\n\n1. **Redução de ruído:** como a detecção de bordas é suscetível a ruídos em uma imagem, removemos o ruído da imagem usando um filtro gaussiano de 5 x 5.\n\n2. **Encontrando o gradiente de intensidade da imagem**: a imagem suavizada é filtrada com um kernel Sobel nas direções horizontal e vertical para obter a primeira derivada na horizontal\n(*G<sub>x</sub>*) e vertical (*G<sub>y</sub>*) instruções. A partir dessas duas imagens, pode-se encontrar o gradiente e a direção da borda para cada pixel:\n\n<center><img src=\"https://i.imgur.com/ntyjTep.png\" width=\"300px\"></center>\n<center><img src=\"https://i.imgur.com/75qDjv6.png\" width=\"260px\"></center>\n\n<br>\n\n3. **Arredondamento:** o gradiente é sempre perpendicular às bordas. Assim, é arredondado para um dos quatro ângulos que representam as direções vertical, horizontal e duas diagonais.\n\n4. **Supressão não máxima:** depois de obter a magnitude e a direção do gradiente, é feita uma varredura completa da imagem para remover quaisquer pixels indesejados que possam não constituir a borda. Para isso, verificamos cada pixel por ser um máximo local em sua vizinhança na direção do gradiente.\n\n5. **Limiar de histerese:** este estágio decide quais partes são bordas e quais não são. Para isso, precisamos de dois valores de limite, *minVal* e *maxVal*. Quaisquer arestas com gradiente de intensidade maior que *maxVal* são consideradas arestas e aquelas menores que *minVal* são consideradas não arestas e descartadas. Aqueles que estão entre esses dois limites são classificados como arestas ou não arestas com base em sua vizinhança. Se estiverem próximos de pixels de “borda segura”, são considerados arestas e, caso contrário, são descartados.\n\nO resultado dessas cinco etapas é um mapa binário bidimensional (0 ou 255) indicando a localização das bordas na imagem. Canny edge é demonstrado abaixo com algumas imagens de folhas:","metadata":{"id":"jC9wp-8N5kU4"}},{"cell_type":"markdown","source":"\n","metadata":{}},{"cell_type":"code","source":"def edge_and_cut(img):\n    emb_img = img.copy()\n    edges = cv2.Canny(img, 100, 200)\n    edge_coors = []\n    for i in range(edges.shape[0]):\n        for j in range(edges.shape[1]):\n            if edges[i][j] != 0:\n                edge_coors.append((i, j))\n    \n    row_min = edge_coors[np.argsort([coor[0] for coor in edge_coors])[0]][0]\n    row_max = edge_coors[np.argsort([coor[0] for coor in edge_coors])[-1]][0]\n    col_min = edge_coors[np.argsort([coor[1] for coor in edge_coors])[0]][1]\n    col_max = edge_coors[np.argsort([coor[1] for coor in edge_coors])[-1]][1]\n    new_img = img[row_min:row_max, col_min:col_max]\n    \n    emb_img[row_min-10:row_min+10, col_min:col_max] = [255, 0, 0]\n    emb_img[row_max-10:row_max+10, col_min:col_max] = [255, 0, 0]\n    emb_img[row_min:row_max, col_min-10:col_min+10] = [255, 0, 0]\n    emb_img[row_min:row_max, col_max-10:col_max+10] = [255, 0, 0]\n    \n    fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(30, 20))\n    ax[0].imshow(img, cmap='gray')\n    ax[0].set_title('Imagem original', fontsize=24)\n    ax[1].imshow(edges, cmap='gray')\n    ax[1].set_title('Canny Edges', fontsize=24)\n    ax[2].imshow(emb_img, cmap='gray')\n    ax[2].set_title('Caixa delimitadora', fontsize=24)\n    plt.show()","metadata":{"_kg_hide-input":true,"id":"uU_iqYaCpnL7","execution":{"iopub.status.busy":"2022-07-26T21:41:47.132768Z","iopub.execute_input":"2022-07-26T21:41:47.133370Z","iopub.status.idle":"2022-07-26T21:41:47.147598Z","shell.execute_reply.started":"2022-07-26T21:41:47.133328Z","shell.execute_reply":"2022-07-26T21:41:47.146980Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"edge_and_cut(train_images[3])\nedge_and_cut(train_images[4])\nedge_and_cut(train_images[5])","metadata":{"_kg_hide-input":true,"id":"bYJ0t9kppnL9","outputId":"a2785c32-9151-4d8d-f837-ec9de9de49bf","execution":{"iopub.status.busy":"2022-07-26T21:41:51.019592Z","iopub.execute_input":"2022-07-26T21:41:51.019920Z","iopub.status.idle":"2022-07-26T21:42:25.159143Z","shell.execute_reply.started":"2022-07-26T21:41:51.019885Z","shell.execute_reply":"2022-07-26T21:42:25.158244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"A segunda coluna de imagens acima contém as bordas do Canny e a terceira coluna contém imagens recortadas. Eu peguei as arestas do Canny e as usei para prever uma caixa delimitadora na qual a folha real está contida. As arestas mais extremas nos quatro cantos da imagem são os vértices da caixa delimitadora. Esta caixa vermelha provavelmente conterá a maior parte, senão toda a folha. Essas arestas e caixas delimitadoras podem ser usadas para construir modelos mais precisos.\n","metadata":{}},{"cell_type":"markdown","source":"## Virando <a id=\"2.2\"></a>\n\nA inversão é uma transformação simples que envolve a troca de índice nos canais de imagem. No lançamento vertical, a ordem das linhas é trocada, enquanto no lançamento vertical, a ordem das linhas é trocada. Vamos supor que *A<sub>ijk</sub>* (de tamanho *(m, n, 3)*) é a imagem que queremos inverter. A inversão horizontal e vertical pode ser representada pelas transformações abaixo:\n\n<center><img src=\"https://i.imgur.com/B9y5apl.png\" width=\"135px\"></center>\n<center><img src=\"https://i.imgur.com/eQ1dyvN.png\" width=\"305px\"></center>\n<center><img src=\"https://i.imgur.com/i30LQgq.png\" width=\"305px\"></center>\n<br>\n\nPodemos ver que a ordem das colunas é trocada no flip horizontal. Enquanto os índices *i* e *k* permanecem os mesmos, o índice *j* se inverte. Considerando que, no lançamento vertical, a ordem das linhas é trocada no lançamento horizontal. Enquanto os índices *j* e *k* permanecem os mesmos, o índice *i* se inverte.\n","metadata":{"id":"Wh0WHTCC5sL_"}},{"cell_type":"code","source":"def invert(img):\n    fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(30, 20))\n    ax[0].imshow(img)\n    ax[0].set_title('Imagem original', fontsize=24)\n    ax[1].imshow(cv2.flip(img, 0))\n    ax[1].set_title('Giro Vertical', fontsize=24)\n    ax[2].imshow(cv2.flip(img, 1))\n    ax[2].set_title('Girto Horizontal', fontsize=24)\n    plt.show()","metadata":{"_kg_hide-input":true,"id":"XPZwEZAepnMA","execution":{"iopub.status.busy":"2022-07-26T21:42:25.169862Z","iopub.execute_input":"2022-07-26T21:42:25.170487Z","iopub.status.idle":"2022-07-26T21:42:25.184257Z","shell.execute_reply.started":"2022-07-26T21:42:25.170446Z","shell.execute_reply":"2022-07-26T21:42:25.183366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"invert(train_images[3])\ninvert(train_images[4])\ninvert(train_images[5])","metadata":{"_kg_hide-input":true,"id":"gaiLRUzopnMD","outputId":"dc8f2538-abb7-4449-f0c9-dedd8a393843","execution":{"iopub.status.busy":"2022-07-26T21:42:28.595250Z","iopub.execute_input":"2022-07-26T21:42:28.595553Z","iopub.status.idle":"2022-07-26T21:42:33.771068Z","shell.execute_reply.started":"2022-07-26T21:42:28.595525Z","shell.execute_reply":"2022-07-26T21:42:33.770418Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Podemos ver que as imagens são simplesmente invertidas. Todos os principais recursos da imagem permanecem os mesmos, mas para um algoritmo de computador, as imagens invertidas parecem completamente diferentes. Essas transformações podem ser usadas para aumento de dados, tornando os modelos mais robustos e precisos.","metadata":{}},{"cell_type":"markdown","source":"## Convolução <a id=\"2.3\"></a>\n\nA convolução é um algoritmo bastante simples que envolve um kernel (uma matriz 2D) que se move sobre toda a imagem, calculando produtos de ponto com cada janela ao longo do caminho. O GIF abaixo demonstra a convolução em ação.\n\n<center><img src=\"https://i.imgur.com/wYUaqR3.gif\" width=\"450px\"></center>\n\nO processo acima pode ser resumido com uma equação, onde *f* é a imagem e *h* é o kernel. As dimensões de *f* são *(m, n)* e o kernel é uma matriz quadrada com dimensões menores que *f*:\n\n<center><img src=\"https://i.imgur.com/9scTOGv.png\" width=\"350px\"></center>\n<br>\n\nNa equação acima, o kernel *h* está se movendo ao longo do comprimento e da largura da imagem. O produto escalar de *h* com uma submatriz ou janela de matriz *f* é obtido a cada passo, daí a dupla soma (linhas e colunas). Abaixo demonstro o efeito da convolução nas imagens das folhas.","metadata":{"id":"PqS2I93A5u_R"}},{"cell_type":"code","source":"def conv(img):\n    fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(20, 20))\n    kernel = np.ones((7, 7), np.float32)/25\n    conv = cv2.filter2D(img, -1, kernel)\n    ax[0].imshow(img)\n    ax[0].set_title('Imagem original', fontsize=24)\n    ax[1].imshow(conv)\n    ax[1].set_title('Imagem Convoluída', fontsize=24)\n    plt.show()","metadata":{"_kg_hide-input":true,"id":"aa81abmWpnMG","execution":{"iopub.status.busy":"2022-07-26T21:42:44.299965Z","iopub.execute_input":"2022-07-26T21:42:44.300421Z","iopub.status.idle":"2022-07-26T21:42:44.307517Z","shell.execute_reply.started":"2022-07-26T21:42:44.300383Z","shell.execute_reply":"2022-07-26T21:42:44.306698Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"conv(train_images[3])\nconv(train_images[4])\nconv(train_images[5])","metadata":{"_kg_hide-input":true,"id":"2rqxzygspnMJ","outputId":"98092ab1-48d2-4ce6-e3a9-0342e31cf91c","execution":{"iopub.status.busy":"2022-07-26T21:42:46.788913Z","iopub.execute_input":"2022-07-26T21:42:46.789351Z","iopub.status.idle":"2022-07-26T21:42:50.420646Z","shell.execute_reply.started":"2022-07-26T21:42:46.789322Z","shell.execute_reply":"2022-07-26T21:42:50.419911Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"O operador de convolução parece ter um efeito aparente de \"sol\" das imagens. Isso também pode servir ao propósito de aumentar os dados, ajudando assim a construir modelos mais robustos e precisos.","metadata":{}},{"cell_type":"markdown","source":"## Desfoque <a id=\"2.4\"></a>\n\nO desfoque é simplesmente a adição de ruído à imagem, resultando em uma imagem menos nítida. O ruído pode ser amostrado de qualquer distribuição de escolha, desde que o conteúdo principal da imagem não se torne invisível. Apenas os detalhes menores ficam ofuscados devido ao desfoque. A transformação de desfoque pode ser representada usando a equação abaixo.\n\n<center><img src=\"https://i.imgur.com/zVM8HCU.png\" width=\"220px\"></center>\n<br>\n\nO exemplo usa uma distribuição gaussiana com média 0 e variância 0,1. Abaixo demonstro o efeito de desfoque em algumas imagens de folhas:","metadata":{"id":"xmmHZzUq5xu8"}},{"cell_type":"code","source":"def blur(img):\n    fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(20, 20))\n    ax[0].imshow(img)\n    ax[0].set_title('Imagem original', fontsize=24)\n    ax[1].imshow(cv2.blur(img, (100, 100)))\n    ax[1].set_title('Imagem desfocada', fontsize=24)\n    plt.show()","metadata":{"_kg_hide-input":true,"id":"OcXTa-cxpnMM","execution":{"iopub.status.busy":"2022-07-26T21:42:54.477472Z","iopub.execute_input":"2022-07-26T21:42:54.478466Z","iopub.status.idle":"2022-07-26T21:42:54.485572Z","shell.execute_reply.started":"2022-07-26T21:42:54.478429Z","shell.execute_reply":"2022-07-26T21:42:54.484767Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"blur(train_images[3])\nblur(train_images[4])\nblur(train_images[5])","metadata":{"_kg_hide-input":true,"id":"aH5qRDdupnMP","outputId":"5b649688-b7e6-419e-d060-ddb09a291e38","execution":{"iopub.status.busy":"2022-07-26T21:42:58.807591Z","iopub.execute_input":"2022-07-26T21:42:58.809027Z","iopub.status.idle":"2022-07-26T21:43:02.334520Z","shell.execute_reply.started":"2022-07-26T21:42:58.808974Z","shell.execute_reply":"2022-07-26T21:43:02.333697Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"A transformação desfoca claramente a imagem removendo recursos detalhados de baixo nível, enquanto mantém os principais recursos de alto nível. Esta é mais uma vez uma ótima maneira de aumentar as imagens e treinar modelos mais robustos.","metadata":{}},{"cell_type":"markdown","source":"# Modelagem <a id=\"3\"></a>","metadata":{"id":"wyfDeAJo6lGL"}},{"cell_type":"markdown","source":"## Preparando o terreno <a id=\"3.1\"></a>\n\nAntes de passarmos para a construção dos modelos, explicarei os principais blocos de construção em modelos de CV pré-treinados. Cada modelo principal do ImageNet tem uma arquitetura diferente, mas cada um tem os blocos de construção comuns: **Conv2D, MaxPool, ReLU**. Já expliquei o mecanismo por trás da convolução na seção anterior, então agora explicarei MaxPool e ReLU.\n\n### MaxPool\n\nO pooling máximo é muito semelhante à convolução, exceto que envolve encontrar o valor máximo em uma janela em vez de encontrar o produto escalar da janela com um kernel. O pooling máximo não requer um kernel e é muito útil para reduzir a dimensionalidade de mapas de recursos convolucionais em CNNs. A imagem abaixo demonstra o funcionamento do MaxPool:\n\n\n<center><img src=\"https://i.imgur.com/rBNMsfi.png\" width=\"400px\"></center>\n<br></br>\n\nO exemplo acima demonstra o pool máximo com um tamanho de janela de *(2, 2)*. Este processo pode ser representado pela equação abaixo:\n<br></br>\n.\n\n<center><img src=\"https://i.imgur.com/FRyMNhI.png\" width=\"650px\"></center>\n<br></br>\n\nNa equação acima, a janela se move pela imagem e o valor máximo em cada janela é calculado. Mais uma vez, esse processo é muito importante para reduzir a complexidade das CNNs, mantendo os recursos.","metadata":{"id":"J5f4-lkS7lKs"}},{"cell_type":"markdown","source":"### ReLU\n\nReLU é uma função de ativação comumente usada em arquiteturas de redes neurais. *ReLU(x)* retorna 0 para *x < 0* e *x* caso contrário. Esta função ajuda a introduzir não linearidade na rede neural, aumentando assim sua capacidade de modelar os dados da imagem. O gráfico e a equação de *ReLU* são:\n\n<center><img src=\"https://i.imgur.com/eiRVQBh.png\" width=\"400px\"></center>\n\n<center><img src=\"https://i.imgur.com/0mBFAH0.png\" width=\"400px\"></center>\n<br></br>\n\n","metadata":{}}]}