{"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":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-06-02T00:47:14.913118Z","iopub.execute_input":"2023-06-02T00:47:14.913583Z","iopub.status.idle":"2023-06-02T00:47:14.922910Z","shell.execute_reply.started":"2023-06-02T00:47:14.913550Z","shell.execute_reply":"2023-06-02T00:47:14.921615Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Bibliotecas Adicionais Necessárias","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nfrom keras.utils.np_utils import to_categorical \nfrom keras.models import Sequential\nfrom keras.layers import Conv2D, Flatten, Dense\nimport matplotlib.pyplot as plt\nfrom keras.optimizers import Adam","metadata":{"execution":{"iopub.status.busy":"2023-06-02T00:47:14.925870Z","iopub.execute_input":"2023-06-02T00:47:14.926227Z","iopub.status.idle":"2023-06-02T00:47:14.935833Z","shell.execute_reply.started":"2023-06-02T00:47:14.926198Z","shell.execute_reply":"2023-06-02T00:47:14.934747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 1. Carregando e Visualizando os Dados","metadata":{}},{"cell_type":"markdown","source":"### 1.1 Dados de Treino","metadata":{}},{"cell_type":"code","source":"# Lendo os dados de treino\ntrain = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')\n# Formato de dados\nrows, columns = train.shape\nprint(f'Os dados de treino possuem {rows} observações com {columns} colunas, onde a primeira coluna representa a label, e as demais 784, representam 1 píxel da imagem cada.')\n#  5 primeiras observações\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2023-06-02T00:47:14.949235Z","iopub.execute_input":"2023-06-02T00:47:14.950223Z","iopub.status.idle":"2023-06-02T00:47:18.261167Z","shell.execute_reply.started":"2023-06-02T00:47:14.950187Z","shell.execute_reply":"2023-06-02T00:47:18.259984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 1.2 Dados de Teste","metadata":{}},{"cell_type":"code","source":"# Lendo os dados de teste\ntest = pd.read_csv('/kaggle/input/digit-recognizer/test.csv')\n# Formato de dados\nrows, columns = test.shape\nprint(f'Os dados de teste possuem {rows} observações com {columns} colunas, onde cada coluna representa 1 píxel da imagem.')\n#  5 primeiras observações\ntest.head()","metadata":{"execution":{"iopub.status.busy":"2023-06-02T00:47:18.263635Z","iopub.execute_input":"2023-06-02T00:47:18.264158Z","iopub.status.idle":"2023-06-02T00:47:20.358539Z","shell.execute_reply.started":"2023-06-02T00:47:18.264118Z","shell.execute_reply":"2023-06-02T00:47:20.357409Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 2. Manipulações Conjuntos de Treino e Teste","metadata":{}},{"cell_type":"markdown","source":"### 2.1 Dividindo dados de Treino","metadata":{}},{"cell_type":"code","source":"# Dividindo Dados de Treino\nX_train = train.drop(labels=['label'], axis=1)\ny_train = train['label']","metadata":{"execution":{"iopub.status.busy":"2023-06-02T00:47:20.359991Z","iopub.execute_input":"2023-06-02T00:47:20.360462Z","iopub.status.idle":"2023-06-02T00:47:20.458702Z","shell.execute_reply.started":"2023-06-02T00:47:20.360422Z","shell.execute_reply":"2023-06-02T00:47:20.457401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 2.2 Pré-processamento dos Dados","metadata":{}},{"cell_type":"markdown","source":"#### 2.2.1 Normalização","metadata":{}},{"cell_type":"markdown","source":"A normalização torna o processo de treinamento da rede mais rápido e eficiente","metadata":{}},{"cell_type":"code","source":"# Normalizando dados \nX_train = X_train / 255.0 \ntest = test / 255.0","metadata":{"execution":{"iopub.status.busy":"2023-06-02T00:47:20.461233Z","iopub.execute_input":"2023-06-02T00:47:20.461826Z","iopub.status.idle":"2023-06-02T00:47:20.578715Z","shell.execute_reply.started":"2023-06-02T00:47:20.461792Z","shell.execute_reply":"2023-06-02T00:47:20.577754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### 2.2.2 Remodelagem","metadata":{}},{"cell_type":"markdown","source":"A modelagem abaixo é necessária para deixar as imagens no tamanho 28x28 e manter apenas um canal de cor, o que leva a imagem ficar em preto e branco. Esta modelagem é fundamental para a melhoria do funcionamento do modelo que será criado","metadata":{}},{"cell_type":"code","source":"# Remodelagem de dados para matriz de 4 dimensões \nX_train = X_train.values.reshape(-1, 28, 28, 1)\ntest = test.values.reshape(-1, 28, 28, 1)","metadata":{"execution":{"iopub.status.busy":"2023-06-02T00:47:20.579682Z","iopub.execute_input":"2023-06-02T00:47:20.579982Z","iopub.status.idle":"2023-06-02T00:47:20.585788Z","shell.execute_reply.started":"2023-06-02T00:47:20.579956Z","shell.execute_reply":"2023-06-02T00:47:20.584761Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### 2.2.3 Codificação","metadata":{}},{"cell_type":"markdown","source":"A codificação realizada consiste na codificação dos rótulos de treinamento aliado a utilização da técnica de one-hot encoding para convertê-los em vetores constituidos por valores binários. Esta codificação é extremamente útil para problemas de classificação","metadata":{}},{"cell_type":"code","source":"# Categorização em 10 dígitos\ny_train = to_categorical(y_train, num_classes=10)","metadata":{"execution":{"iopub.status.busy":"2023-06-02T00:47:20.588062Z","iopub.execute_input":"2023-06-02T00:47:20.589378Z","iopub.status.idle":"2023-06-02T00:47:20.600434Z","shell.execute_reply.started":"2023-06-02T00:47:20.589335Z","shell.execute_reply":"2023-06-02T00:47:20.599308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### 2.2.4 Divisão Dados de Treino e Teste","metadata":{}},{"cell_type":"markdown","source":"Será dividido os dados entre dados para avaliação (não são os mesmos dados de teste) e dados de treino. Esta técnica de não utilizar os dados de teste diretamente durante o treinamento garante uma redução no *overfitting*","metadata":{}},{"cell_type":"markdown","source":"Foram utilizados 80% dos dados para treinamento e 20% para o teste.","metadata":{}},{"cell_type":"code","source":"X_train, X_eval,  y_train, y_eval = train_test_split(X_train, y_train, test_size=0.2, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2023-06-02T00:47:20.601931Z","iopub.execute_input":"2023-06-02T00:47:20.604156Z","iopub.status.idle":"2023-06-02T00:47:21.061175Z","shell.execute_reply.started":"2023-06-02T00:47:20.604124Z","shell.execute_reply":"2023-06-02T00:47:21.059949Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 3. Analisando Exemplos de Imagens","metadata":{}},{"cell_type":"code","source":"# Definir o tamanho da grade\ngrid_size = (5, 6)  # 5 linhas, 6 colunas\n\n# Criar a figura e os subplots\nfig, axes = plt.subplots(*grid_size, figsize=(12, 6))\n\n# Percorrer as 30 primeiras imagens em X_test\nfor i, ax in enumerate(axes.flat):\n    if i < 30:\n        # Obter a imagem atual\n        image = test[i][:,:,0]\n\n        # Exibir a imagem\n        ax.imshow(image, cmap='gray')\n        ax.axis('off')\n\n# Ajustar o espaçamento entre os subplots\nplt.tight_layout()\n\n# Mostrar a figura\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-02T00:59:30.442741Z","iopub.execute_input":"2023-06-02T00:59:30.443159Z","iopub.status.idle":"2023-06-02T00:59:31.542780Z","shell.execute_reply.started":"2023-06-02T00:59:30.443129Z","shell.execute_reply":"2023-06-02T00:59:31.541640Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 4. Criando a Rede Neural","metadata":{}},{"cell_type":"code","source":"# Criando modelo com 4 camadas\nmodel = Sequential()\nmodel.add(Conv2D(16, (3, 3), activation='relu', input_shape=(28, 28, 1)))\nmodel.add(Flatten())\nmodel.add(Dense(64, activation='relu'))\nmodel.add(Dense(10, activation='softmax'))","metadata":{"execution":{"iopub.status.busy":"2023-06-02T00:47:22.683351Z","iopub.execute_input":"2023-06-02T00:47:22.683760Z","iopub.status.idle":"2023-06-02T00:47:22.741516Z","shell.execute_reply.started":"2023-06-02T00:47:22.683727Z","shell.execute_reply":"2023-06-02T00:47:22.740364Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Compilando o modelo\nmodel.compile(optimizer=Adam(), loss='categorical_crossentropy', metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-06-02T00:47:22.745346Z","iopub.execute_input":"2023-06-02T00:47:22.745870Z","iopub.status.idle":"2023-06-02T00:47:22.758243Z","shell.execute_reply.started":"2023-06-02T00:47:22.745836Z","shell.execute_reply":"2023-06-02T00:47:22.757085Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 5. Treinando a Rede Neural","metadata":{}},{"cell_type":"code","source":"# Definindo números de épocas e lotes\nepochs = 15\nbatch_size = 200","metadata":{"execution":{"iopub.status.busy":"2023-06-02T00:47:22.759797Z","iopub.execute_input":"2023-06-02T00:47:22.760133Z","iopub.status.idle":"2023-06-02T00:47:22.768166Z","shell.execute_reply.started":"2023-06-02T00:47:22.760103Z","shell.execute_reply":"2023-06-02T00:47:22.766409Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Treinar o modelo\nhistory = model.fit(X_train, y_train, batch_size=batch_size, epochs=epochs, validation_data=(X_eval, y_eval))\n","metadata":{"execution":{"iopub.status.busy":"2023-06-02T00:47:22.770025Z","iopub.execute_input":"2023-06-02T00:47:22.770419Z","iopub.status.idle":"2023-06-02T00:48:44.585286Z","shell.execute_reply.started":"2023-06-02T00:47:22.770382Z","shell.execute_reply":"2023-06-02T00:48:44.584370Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Avaliar o desempenho do modelo no conjunto de avaliação\ntest_loss, test_acc = model.evaluate(X_eval, y_eval)\nprint(f\"Acurácia no conjunto de teste: {test_acc}\")","metadata":{"execution":{"iopub.status.busy":"2023-06-02T00:48:44.587373Z","iopub.execute_input":"2023-06-02T00:48:44.588218Z","iopub.status.idle":"2023-06-02T00:48:45.824803Z","shell.execute_reply.started":"2023-06-02T00:48:44.588163Z","shell.execute_reply":"2023-06-02T00:48:45.823673Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 6. Criação da Submissão","metadata":{}},{"cell_type":"code","source":"# Fazer previsões no conjunto de teste\npredictions = model.predict(test)\n\n# Converter as probabilidades em rótulos de classe\npredicted_labels = predictions.argmax(axis=1)","metadata":{"execution":{"iopub.status.busy":"2023-06-02T00:57:05.545867Z","iopub.execute_input":"2023-06-02T00:57:05.546318Z","iopub.status.idle":"2023-06-02T00:57:09.345623Z","shell.execute_reply.started":"2023-06-02T00:57:05.546281Z","shell.execute_reply":"2023-06-02T00:57:09.344385Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Cria um DataFrame com os dados de submissão\nsubmission_data = pd.DataFrame({'ImageId': range(1, len(predicted_labels) + 1), 'Label': predicted_labels})\n\n# Salva o DataFrame em um arquivo CSV\nsubmission_data.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2023-06-02T00:57:13.033023Z","iopub.execute_input":"2023-06-02T00:57:13.033457Z","iopub.status.idle":"2023-06-02T00:57:13.108153Z","shell.execute_reply.started":"2023-06-02T00:57:13.033422Z","shell.execute_reply":"2023-06-02T00:57:13.107042Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"**Conclusão: Com a implementação de uma rede neural composta por quatro camadas, foi demonstrado que é viável desenvolver um reconhecedor de dígitos altamente eficiente. A arquitetura utilizada, juntamente com as técnicas de treinamento apropriadas, permitiram alcançar resultados promissores no reconhecimento de dígitos. Esses resultados destacam a capacidade das redes neurais em resolver tarefas complexas, como o reconhecimento de padrões em imagens. A implementação desse modelo de rede neural pode ser aplicada em uma variedade de problemas relacionados ao reconhecimento de dígitos, proporcionando uma solução eficaz e precisa.**","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}