{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceType":"competition","sourceId":3004,"databundleVersionId":861823}],"dockerImageVersionId":29928,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# Introdução","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**Resumo:**\n\nO exemplo aqui desenvolvido tem como objetivo apresentar conceitos iniciais de implementação de redes neurais com python e tensorflow/keras. Esse modelo apresenta um modelo MLP básico que pode ser expandido mudando o número de neurônios e camadas. Em adaptações mais avançadas, pode-se estudar possibilidade de otimização de hyperparâmetros e outras técnincas como aumento de dados.\n\n**Não é objetivo nosso desenvolver e otimizar o modelo de classificação**. O exemplo tem objetivo meramente didático.\n\n---\n\n**Para saber mais:**\n* [Palestras e cursos do Ocean](http://www.oceanbrasil.com/)\n* François Chollet. Deep Learning with Python. Manning Publications, 2017.\n* Ian Goodfellow and Yoshua Bengio and Aaron Courville. [Deep Learning](https://www.deeplearningbook.org/). MIT Press, 2016.","metadata":{}},{"cell_type":"markdown","source":"# Bibliotecas e Dados","metadata":{}},{"cell_type":"code","source":"# Bibliotecas necessárias\n# Manipulação de dados\nimport pandas as pd\n# Redes Neurais\nfrom tensorflow import keras\nfrom tensorflow.keras.datasets import mnist\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, Dropout\nfrom tensorflow.keras.optimizers import RMSprop\n# Plot\nimport matplotlib.pyplot as plt\n#%matplotlib inline\n# Avaliação\nfrom sklearn.metrics import classification_report, confusion_matrix","metadata":{"ExecuteTime":{"end_time":"2019-01-16T20:39:41.500258Z","start_time":"2019-01-16T20:39:39.261856Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Lendo o dataset Kaggle\ntrain = pd.read_csv(\"../input/digit-recognizer/train.csv\")\n# Analisando o dataset\nprint(\"Quantidade de elementos de treino: {}\". format(len(train)))\nprint(train.head())","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Separando x_train e y_train\nY = train[\"label\"]\nX = train.drop(labels = [\"label\"],axis = 1)# Só as colunas pixel<nro>","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(Y[100])","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Numtendi nada!\n# Bora ver com matplotlib\nplt.imshow(X.values[100].reshape(28,28), cmap=plt.cm.binary)\nplt.show()","metadata":{"ExecuteTime":{"end_time":"2019-01-08T20:49:47.144492Z","start_time":"2019-01-08T20:49:47.016025Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Transformando a imagem 2d em um numpy array (imagem 28*28 = 784 pixels)\nx = X.values.reshape(42000, 784)\n\n#Normalizando para valores entre 0 e 1\nx = x.astype('float32')\nx /= 255\n\nprint(x[0])","metadata":{"ExecuteTime":{"end_time":"2019-01-08T20:49:57.425537Z","start_time":"2019-01-08T20:49:57.272377Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Vamos ajustar o formato da saida\nnum_classes = 10\n\n# Convertendo para um vetor de saida com 10 dimensoes\n# ex. 8 => [0,0,0,0,0,0,0,0,1,0]\ny = keras.utils.to_categorical(Y, num_classes)\nprint(y[100])","metadata":{"ExecuteTime":{"end_time":"2019-01-08T20:50:48.007428Z","start_time":"2019-01-08T20:50:47.986527Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Separando uma parte para treino (90%) e outra para validação (10%)\nfrom sklearn.model_selection import train_test_split\nx_train, x_val, y_train, y_val = train_test_split(x, y, test_size = 0.1, random_state=9)\nprint('Qtde de treino: {}'.format(len(x_train)))\nprint('Qtde de validação: {}'.format(len(x_val)))","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Criando e treinando o Modelo","metadata":{}},{"cell_type":"code","source":"# Criando o modelo Sequential\n# Sequential: Modelo Keras de ir adicionando camadas (como um lego)\n# Dense: Camada onde todas as entradas estão conectadas em cada neurônio (totalmente conectada)\n# Dropout: Controle de Overfit. Desconecta percentual de neurônios aleatoriamente.\n\nmodel = Sequential()\n# Camada com 30 neurônios\nmodel.add(Dense(30, activation='relu', input_shape=(784,)))\n# Controle de Overfit\nmodel.add(Dropout(0.2))\n# Camada de 20 neurônios\nmodel.add(Dense(20, activation='relu'))\n# Camada de classificação final, com 1 neurônio para cada classe de saída. Softmax divide a probabilidade de cada classe.\nmodel.add(Dense(num_classes, activation='softmax'))\n\nmodel.summary()","metadata":{"ExecuteTime":{"end_time":"2019-01-08T21:38:00.233865Z","start_time":"2019-01-08T21:38:00.15079Z"},"scrolled":true,"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Compila o modelo\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=RMSprop(),\n              metrics=['accuracy'])","metadata":{"ExecuteTime":{"end_time":"2019-01-08T21:33:17.184644Z","start_time":"2019-01-08T21:33:17.129141Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Treina com os parte dos dados\nbatch_size = 32\nepochs = 10\nhistory = model.fit(x_train, y_train,\n                    batch_size=batch_size,\n                    epochs=epochs,\n                    verbose=1,\n                    validation_data=(x_val, y_val))","metadata":{"ExecuteTime":{"end_time":"2019-01-08T21:36:15.501168Z","start_time":"2019-01-08T21:33:19.322895Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Vamos ver como foi o treino?\n\nfig, ax = plt.subplots(1,2, figsize=(16,8))\nax[0].plot(history.history['loss'], color='b', label=\"Training loss\")\nax[0].plot(history.history['val_loss'], color='r', label=\"validation loss\",axes =ax[0])\nlegend = ax[0].legend(loc='best', shadow=True)\n\nax[1].plot(history.history['accuracy'], color='b', label=\"Training accuracy\")\nax[1].plot(history.history['val_accuracy'], color='r',label=\"Validation accuracy\")\nlegend = ax[1].legend(loc='best', shadow=True)","metadata":{"ExecuteTime":{"end_time":"2019-01-08T21:36:20.243921Z","start_time":"2019-01-08T21:36:20.064201Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Testa\nscore = model.evaluate(x_val, y_val, verbose=0)\nprint('Test loss:', score[0])\nprint('Test accuracy:', score[1])","metadata":{"ExecuteTime":{"end_time":"2019-01-08T21:36:39.779842Z","start_time":"2019-01-08T21:36:38.946173Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Testando uma entrada qualquer\nprint(y_train[10])\nprint(model.predict(x_train[10].reshape((1,784))))\nprint(model.predict_classes(x_train[10].reshape((1,784))))","metadata":{"ExecuteTime":{"end_time":"2019-01-08T21:06:04.363715Z","start_time":"2019-01-08T21:06:04.27849Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Avaliando o Modelo","metadata":{}},{"cell_type":"code","source":"# Vendo alguns reports\n# Usando sklearn\nimport numpy as np\n\n# Classificando toda base de teste\ny_pred = model.predict_classes(x_val)\n# voltando pro formato de classes\ny_test_c = np.argmax(y_val, axis=1)\ntarget_names = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']","metadata":{"ExecuteTime":{"end_time":"2019-01-08T21:24:57.7654Z","start_time":"2019-01-08T21:24:57.220867Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import seaborn as sns\n\n#Confusion Matrix\ncm = confusion_matrix(y_test_c, y_pred)\n\n# Plotar a matriz de confusão com seaborn\nplt.figure(figsize=(10, 7))  # Definir o tamanho da figura\nsns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=target_names, yticklabels=target_names)\n\n# Configurações adicionais para os eixos\nplt.xlabel('Predicted')\nplt.ylabel('True')\nplt.title('Confusion Matrix')\n\nplt.show()\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print('Classification Report')\nprint(classification_report(y_test_c, y_pred, target_names=target_names))","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Gerando Saída (Competição Kaggle)","metadata":{}},{"cell_type":"markdown","source":"Esse dataset é usado em uma competição tutorial do Kaggle. Caso você queira submeter resultados dos seus modelos, basta gerar as predições dos dados de testes em um arquivo e fazer upload em: ","metadata":{}},{"cell_type":"code","source":"# Gerando saída para dataset de teste\n\n#Carrega dataset de teste\ntest = pd.read_csv(\"../input/digit-recognizer/test.csv\")\nprint(\"Qtde de testes: {}\".format(len(test)))\n# Bota no formato numpy e normaliza\nx_test = test.values.reshape(len(test),784)\nx_test = x_test.astype('float32')\nx_test /= 255\n\n# Faz classificação para dataset de teste\ny_pred = model.predict_classes(x_test)\n\n# Verficando algum exemplo\ni = 0\nplt.imshow(test.values[i].reshape(28,28), cmap=plt.cm.binary)\nplt.show()\nprint('Previsto: {}'.format(y_pred[i]))\n\n# Botando no formato de saída (competição Kaggle)\nresults = pd.Series(y_pred,name=\"Label\")\nsubmission = pd.concat([pd.Series(range(1,len(y_pred)+1),name = \"ImageId\"),results],axis = 1)\nprint(submission.head(10))\n#Salvando Arquivo\nsubmission.to_csv(\"mlp_mnist_v1.csv\",index=False)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}