{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":2876405,"sourceType":"datasetVersion","datasetId":1761725},{"sourceId":7051480,"sourceType":"datasetVersion","datasetId":4058245}],"dockerImageVersionId":30587,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# !pip install xlrd;","metadata":{"execution":{"iopub.status.busy":"2023-12-12T16:46:41.220754Z","iopub.execute_input":"2023-12-12T16:46:41.221393Z","iopub.status.idle":"2023-12-12T16:46:41.224824Z","shell.execute_reply.started":"2023-12-12T16:46:41.221360Z","shell.execute_reply":"2023-12-12T16:46:41.224255Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# To ignore warinings\nimport warnings\nwarnings.filterwarnings('ignore')\n\nimport logging\nimport os\n\nos.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'  # FATAL\nlogging.getLogger('tensorflow').setLevel(logging.FATAL)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T16:46:41.225911Z","iopub.execute_input":"2023-12-12T16:46:41.226130Z","iopub.status.idle":"2023-12-12T16:46:41.236944Z","shell.execute_reply.started":"2023-12-12T16:46:41.226107Z","shell.execute_reply":"2023-12-12T16:46:41.236062Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Questão 1\n\nEscreva um programa que leia uma imagem colorida e altere o padrão de cores da seguinte forma:\n\n* Torne o azul 20% mais intenso.\n* Torne o verde 30% menos intenso.\n* Elimine completamente o vermelho.","metadata":{}},{"cell_type":"code","source":"import cv2\nimport numpy as np\nimport requests\nimport urllib\nfrom matplotlib import pyplot as plt\nimport numpy as np\nimport io\n\n# Definir a URL da imagem\nurl = 'https://s1.static.brasilescola.uol.com.br/be/2021/10/araras.jpg'\n\n# Fazer o download da imagem a partir da URL\nimagem_url = requests.get(url)\nimagem_array = np.array(bytearray(imagem_url.content), dtype=np.uint8)\nimagem = cv2.imdecode(imagem_array, -1)\n\n# Dividir a imagem em canais de cores (azul, verde, vermelho)\nazul, verde, vermelho = cv2.split(imagem)\n\n# Ajustar a intensidade das cores conforme as especificações\nazul = np.clip(azul * 1.2, 0, 255).astype(np.uint8)  # Aumentar intensidade do azul em 20%\nverde = np.clip(verde * 0.7, 0, 255).astype(np.uint8)  # Reduzir intensidade do verde em 30%\nvermelho = np.zeros_like(vermelho)  # Eliminar completamente o canal vermelho\n\n# Mesclar os canais de cores de volta em uma imagem\nimagem_alterada = cv2.merge((azul, verde, vermelho))\n\n# Exibir a imagem original e a imagem alterada\nplt.figure(figsize=(10,10))\nplt.subplot(1, 2, 1)\nplt.imshow(cv2.cvtColor(imagem, cv2.COLOR_BGR2RGB))\nplt.title('Imagem Original')\nplt.axis('off')\n\nplt.subplot(1, 2, 2)\nplt.imshow(cv2.cvtColor(imagem_alterada, cv2.COLOR_BGR2RGB))\nplt.title('Imagem Alterada')\nplt.axis('off')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-12T16:46:41.238094Z","iopub.execute_input":"2023-12-12T16:46:41.238429Z","iopub.status.idle":"2023-12-12T16:46:44.298545Z","shell.execute_reply.started":"2023-12-12T16:46:41.238401Z","shell.execute_reply":"2023-12-12T16:46:44.297734Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Questão 2\n\nA partir da rede neural RNA_Perceptron.py implementada em aula, execute 5 treinamentos para a rede:","metadata":{}},{"cell_type":"markdown","source":"## 1. Mostre os pesos finais.","metadata":{}},{"cell_type":"code","source":"# Nome: RNA_Perceptron.py\n# Função: Implementação da uma RNA Perceptron \n# Data: 05/01/2022\n# Autor: RD\n\n# bibliotecas\nimport numpy as np\nimport pandas as pd\nimport random\nfrom sklearn.model_selection import train_test_split\n\n# Base de dados\nBase_Dados= pd.read_excel(\"/kaggle/input/tp3-dados-perceptron/Dados_Perceptron.xls\")\n(nL,nC)= Base_Dados.shape\n\n# Matrizes X e Y\nX= Base_Dados.iloc[:,0:nC-1].values     # numpy array\nX0= X.copy()\nY= Base_Dados.iloc[:,nC-1].values       # numpy array\n\n# Normalizar base de dados\n# range => [0,1]\n# X= (X-minX)/(maxX-minX)\n\n# Normalizar dados\n# Mostrar com e sem a normalização\n# Observar o número de épocas\n\nOrdemX= X.shape\nnCx= OrdemX[1]\n\nfor iC in range(0,nCx):\n    minX= X[:,iC].min()\n    maxX= X[:,iC].max()\n    X[:,iC]= (X[:,iC]-minX)/(maxX-minX)\n\ndef main_loop():\n    # Separação (split) da base de dados em teste e treinamento\n    X_treino,X_teste,Y_treino,Y_teste= train_test_split(X,Y,test_size= 0.25)\n    # random_state= 1\n    #X_tes0= X_teste.copy()\n    # Inicialização dos pesos: W= {teta,w1,w2,w3}\n\n    nW= nCx+1\n    W= np.zeros(nW)\n    for i in range(0,nW):\n        W[i]= random.random() # intervalo [0,1]\n\n    print(\"Pesos iniciais:\", W)\n\n    W0= W.copy()\n    # W[0]= 0.11\n    # W[1]= 0.12\n    # W[2]= 0.13\n    # W[3]= 0.15\n\n    # Parâmetros da rede\n    n_epocas= 100 # 30,100,500,1000\n    taxa_apr= 0.01\n\n    # Algoritmo de aprendizagem da rede (treinamento)\n    # Loop: épocas não erro\n    nY= len(Y_treino)\n    for epoca in range(0,n_epocas):\n        for iY in range(0,nY):\n            # Entrada\n            x= np.append(-1,X_treino[iY,:]) # x=[-1 X1 X2 X3]\n            # Potencial de ativação\n            # u= x[0]*W[0]+x[1]*W[1]+x[2]*W[2]+x[3]*W[3]\n            u= 0\n            for iu in range(0,nCx+1):\n                u=u+x[iu]*W[iu] \n            # Função de ativação\n            if (u>=0):\n                y_est= 1\n            else:\n                y_est= -1\n\n            # Erro\n            y= Y_treino[iY] # saída real\n\n            # Ajuste dos pesos\n            if (y != y_est):\n                W= W+taxa_apr*(y-y_est)*x\n\n    print(\"Pesos finais\", W)\n\n    # Avaliação do treinamento\n    # Percentual de acertos = (número de acertos/número total)*100\n    n_certo= 0\n    for iY in range(0,nY):\n        # Entrada\n        x= np.append(-1,X_treino[iY,:])\n\n        # Potencial de ativação\n        # u= x[0]*W[0]+x[1]*W[1]+x[2]*W[2]+x[3]*W[3]\n        u= 0\n        for iu in range(0,nCx+1):\n            u=u+x[iu]*W[iu] \n\n        # Função de ativação\n        if (u>=0):\n            y_est= 1\n        else:\n            y_est= -1\n\n        # Erro\n        y= Y_treino[iY] # saída real\n        if (y == y_est):\n            n_certo= n_certo+1 # contador de acertos\n    p_certo= (n_certo/nY)*100 # porc(A)= (nA/nT)*100\n    print(f\"Treinamento: {p_certo:.2f}%\")\n\n    # Avaliação da base de dados de teste\n    nY2= len(Y_teste)\n    n_certo2= 0\n\n    for iY in range(0,nY2):\n        # Entrada\n        x= np.append(-1,X_teste[iY,:])\n\n        # Potencial de ativação\n        # u= x[0]*W[0]+x[1]*W[1]+x[2]*W[2]+x[3]*W[3]\n        u= 0\n        for iu in range(0,nCx+1):\n            u=u+x[iu]*W[iu] \n\n        # Função de ativação\n        if (u>=0):\n            y_est= 1\n        else:\n            y_est= -1\n\n        # Erro\n        y= Y_teste[iY]\n        if (y == y_est):\n            n_certo2= n_certo2+1\n\n    p_certo2= (n_certo2/nY2)*100 \n    print(f\"Teste: {p_certo2:.2f}%\")\n    \nfor _ in range(5):\n    print(\"Treinamento nº\", _+1)\n    main_loop()\n    print(\"\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-12-12T16:46:44.299762Z","iopub.execute_input":"2023-12-12T16:46:44.300183Z","iopub.status.idle":"2023-12-12T16:46:45.856190Z","shell.execute_reply.started":"2023-12-12T16:46:44.300134Z","shell.execute_reply":"2023-12-12T16:46:45.855312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**2. Os pesos são os mesmos nos 5 treinamentos? Por quê?** <br><br>\nNão, Os pesos não são os mesmos nos 5 treinamentos. Inicialmente, porque a inicialização dos pesos é feita de forma aleatória. A função random.random() é usada para atribuir valores aleatórios aos pesos. Portanto, em cada treinamento, os pesos são inicializados de forma diferente. Para garantir a repetibilidade dos resultados, deve ser adicionado o parâmetro <code>random.seed</code>. Com a definição do <code>random.seed</code>, ao executar o código, os pesos iniciais sempre serão inicializados com os mesmos valores, garantindo consistentência e repetibilidade. Além disso, como o ajuste dos pesos é baseado nos erros cometidos durante o treinamento, é esperado que os pesos finais sejam diferentes a cada iteração, pois os erros variam a cada iteração. O objetivo é encontrar os pesos que minimizam os erros e maximizam o desempenho do modelo na classificação dos dados. A seguir, a execução do código com a definicação de <code>random.seed</code>.","metadata":{}},{"cell_type":"code","source":"# Nome: RNA_Perceptron.py\n# Função: Implementação da uma RNA Perceptron \n# Data: 05/01/2022\n# Autor: RD\n\n# bibliotecas\nimport numpy as np\nimport pandas as pd\nimport random\nfrom sklearn.model_selection import train_test_split\n\n# Base de dados\nBase_Dados= pd.read_excel(\"/kaggle/input/tp3-dados-perceptron/Dados_Perceptron.xls\")\n(nL,nC)= Base_Dados.shape\n\n# Matrizes X e Y\nX= Base_Dados.iloc[:,0:nC-1].values     # numpy array\nX0= X.copy()\nY= Base_Dados.iloc[:,nC-1].values       # numpy array\n\n# Normalizar base de dados\n# range => [0,1]\n# X= (X-minX)/(maxX-minX)\n\n# Normalizar dados\n# Mostrar com e sem a normalização\n# Observar o número de épocas\n\nOrdemX= X.shape\nnCx= OrdemX[1]\n\nfor iC in range(0,nCx):\n    minX= X[:,iC].min()\n    maxX= X[:,iC].max()\n    X[:,iC]= (X[:,iC]-minX)/(maxX-minX)\n\ndef main_loop():\n    random.seed(42)\n    # Separação (split) da base de dados em teste e treinamento\n    X_treino,X_teste,Y_treino,Y_teste= train_test_split(X,Y,test_size= 0.25)\n    # random_state= 1\n    #X_tes0= X_teste.copy()\n    # Inicialização dos pesos: W= {teta,w1,w2,w3}\n\n    nW= nCx+1\n    W= np.zeros(nW)\n    for i in range(0,nW):\n        W[i]= random.random() # intervalo [0,1]\n\n    print(\"Pesos iniciais:\", W)\n\n    W0= W.copy()\n    # W[0]= 0.11\n    # W[1]= 0.12\n    # W[2]= 0.13\n    # W[3]= 0.15\n\n    # Parâmetros da rede\n    n_epocas= 100 # 30,100,500,1000\n    taxa_apr= 0.01\n\n    # Algoritmo de aprendizagem da rede (treinamento)\n    # Loop: épocas não erro\n    nY= len(Y_treino)\n    for epoca in range(0,n_epocas):\n        for iY in range(0,nY):\n            # Entrada\n            x= np.append(-1,X_treino[iY,:]) # x=[-1 X1 X2 X3]\n            # Potencial de ativação\n            # u= x[0]*W[0]+x[1]*W[1]+x[2]*W[2]+x[3]*W[3]\n            u= 0\n            for iu in range(0,nCx+1):\n                u=u+x[iu]*W[iu] \n            # Função de ativação\n            if (u>=0):\n                y_est= 1\n            else:\n                y_est= -1\n\n            # Erro\n            y= Y_treino[iY] # saída real\n\n            # Ajuste dos pesos\n            if (y != y_est):\n                W= W+taxa_apr*(y-y_est)*x\n\n    print(\"Pesos finais\", W)\n\n    # Avaliação do treinamento\n    # Percentual de acertos = (número de acertos/número total)*100\n    n_certo= 0\n    for iY in range(0,nY):\n        # Entrada\n        x= np.append(-1,X_treino[iY,:])\n\n        # Potencial de ativação\n        # u= x[0]*W[0]+x[1]*W[1]+x[2]*W[2]+x[3]*W[3]\n        u= 0\n        for iu in range(0,nCx+1):\n            u=u+x[iu]*W[iu] \n\n        # Função de ativação\n        if (u>=0):\n            y_est= 1\n        else:\n            y_est= -1\n\n        # Erro\n        y= Y_treino[iY] # saída real\n        if (y == y_est):\n            n_certo= n_certo+1 # contador de acertos\n    p_certo= (n_certo/nY)*100 # porc(A)= (nA/nT)*100\n    print(f\"Treinamento: {p_certo:.2f}%\")\n\n    # Avaliação da base de dados de teste\n    nY2= len(Y_teste)\n    n_certo2= 0\n\n    for iY in range(0,nY2):\n        # Entrada\n        x= np.append(-1,X_teste[iY,:])\n\n        # Potencial de ativação\n        # u= x[0]*W[0]+x[1]*W[1]+x[2]*W[2]+x[3]*W[3]\n        u= 0\n        for iu in range(0,nCx+1):\n            u=u+x[iu]*W[iu] \n\n        # Função de ativação\n        if (u>=0):\n            y_est= 1\n        else:\n            y_est= -1\n\n        # Erro\n        y= Y_teste[iY]\n        if (y == y_est):\n            n_certo2= n_certo2+1\n\n    p_certo2= (n_certo2/nY2)*100 \n    print(f\"Teste: {p_certo2:.2f}%\")\n    \nfor _ in range(5):\n    print(\"Treinamento nº\", _+1)\n    main_loop()\n    print(\"\")","metadata":{"execution":{"iopub.status.busy":"2023-12-12T16:46:45.858102Z","iopub.execute_input":"2023-12-12T16:46:45.858481Z","iopub.status.idle":"2023-12-12T16:46:45.942132Z","shell.execute_reply.started":"2023-12-12T16:46:45.858452Z","shell.execute_reply":"2023-12-12T16:46:45.941368Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**3. O erro no treinamento é igual ao erro no teste. Por quê?** <br><br>\nO erro no treinamento pode não ser igual ao erro no teste por vários motivos, tais como:\n\n* O modelo pode sofrer de overfitting, o que significa que ele se ajustou muito bem aos dados de treinamento, mas não generaliza bem para dados não vistos no treinamento.\n* A divisão dos dados de treinamento e teste pode não ser representativa o suficiente. Se os dados de teste forem muito diferentes dos dados de treinamento, o erro no teste pode ser significativamente diferente do erro no treinamento.\n* O modelo pode não ter aprendido adequadamente os padrões nos dados de treinamento, resultando em um erro maior no teste.","metadata":{}},{"cell_type":"markdown","source":"**4. O que ocorre quando o número de épocas no treinamento passa de 100 para 1000?** <br><br>\nQuando o número de épocas no treinamento passa de 100 para 1000, o modelo tem mais iterações para ajustar os pesos com base nos erros cometidos. Isso pode resultar em uma melhoria na capacidade do modelo de ajustar-se aos dados de treinamento e potencialmente melhorar seu desempenho no teste. No entanto, aumentar o número de épocas também pode levar ao overfitting se o modelo se ajustar demais aos dados de treinamento. Portanto, é importante encontrar um equilíbrio e ajustar o número de épocas com base no desempenho do modelo nos dados de teste. A seguir, a execução do código com 1000 épocas de treinamento.","metadata":{}},{"cell_type":"code","source":"# Nome: RNA_Perceptron.py\n# Função: Implementação da uma RNA Perceptron \n# Data: 05/01/2022\n# Autor: RD\n\n# bibliotecas\nimport numpy as np\nimport pandas as pd\nimport random\nfrom sklearn.model_selection import train_test_split\n\n# Base de dados\nBase_Dados= pd.read_excel(\"/kaggle/input/tp3-dados-perceptron/Dados_Perceptron.xls\")\n(nL,nC)= Base_Dados.shape\n\n# Matrizes X e Y\nX= Base_Dados.iloc[:,0:nC-1].values     # numpy array\nX0= X.copy()\nY= Base_Dados.iloc[:,nC-1].values       # numpy array\n\n# Normalizar base de dados\n# range => [0,1]\n# X= (X-minX)/(maxX-minX)\n\n# Normalizar dados\n# Mostrar com e sem a normalização\n# Observar o número de épocas\n\nOrdemX= X.shape\nnCx= OrdemX[1]\n\nfor iC in range(0,nCx):\n    minX= X[:,iC].min()\n    maxX= X[:,iC].max()\n    X[:,iC]= (X[:,iC]-minX)/(maxX-minX)\n\ndef main_loop():\n    # Separação (split) da base de dados em teste e treinamento\n    X_treino,X_teste,Y_treino,Y_teste= train_test_split(X,Y,test_size= 0.25)\n    # random_state= 1\n    #X_tes0= X_teste.copy()\n    # Inicialização dos pesos: W= {teta,w1,w2,w3}\n\n    nW= nCx+1\n    W= np.zeros(nW)\n    for i in range(0,nW):\n        W[i]= random.random() # intervalo [0,1]\n\n    print(\"Pesos iniciais:\", W)\n\n    W0= W.copy()\n    # W[0]= 0.11\n    # W[1]= 0.12\n    # W[2]= 0.13\n    # W[3]= 0.15\n\n    # Parâmetros da rede\n    n_epocas= 1000 # 30,100,500,1000\n    taxa_apr= 0.01\n\n    # Algoritmo de aprendizagem da rede (treinamento)\n    # Loop: épocas não erro\n    nY= len(Y_treino)\n    for epoca in range(0,n_epocas):\n        for iY in range(0,nY):\n            # Entrada\n            x= np.append(-1,X_treino[iY,:]) # x=[-1 X1 X2 X3]\n            # Potencial de ativação\n            # u= x[0]*W[0]+x[1]*W[1]+x[2]*W[2]+x[3]*W[3]\n            u= 0\n            for iu in range(0,nCx+1):\n                u=u+x[iu]*W[iu] \n            # Função de ativação\n            if (u>=0):\n                y_est= 1\n            else:\n                y_est= -1\n\n            # Erro\n            y= Y_treino[iY] # saída real\n\n            # Ajuste dos pesos\n            if (y != y_est):\n                W= W+taxa_apr*(y-y_est)*x\n\n    print(\"Pesos finais\", W)\n\n    # Avaliação do treinamento\n    # Percentual de acertos = (número de acertos/número total)*100\n    n_certo= 0\n    for iY in range(0,nY):\n        # Entrada\n        x= np.append(-1,X_treino[iY,:])\n\n        # Potencial de ativação\n        # u= x[0]*W[0]+x[1]*W[1]+x[2]*W[2]+x[3]*W[3]\n        u= 0\n        for iu in range(0,nCx+1):\n            u=u+x[iu]*W[iu] \n\n        # Função de ativação\n        if (u>=0):\n            y_est= 1\n        else:\n            y_est= -1\n\n        # Erro\n        y= Y_treino[iY] # saída real\n        if (y == y_est):\n            n_certo= n_certo+1 # contador de acertos\n    p_certo= (n_certo/nY)*100 # porc(A)= (nA/nT)*100\n    print(f\"Treinamento: {p_certo:.2f}%\")\n\n    # Avaliação da base de dados de teste\n    nY2= len(Y_teste)\n    n_certo2= 0\n\n    for iY in range(0,nY2):\n        # Entrada\n        x= np.append(-1,X_teste[iY,:])\n\n        # Potencial de ativação\n        # u= x[0]*W[0]+x[1]*W[1]+x[2]*W[2]+x[3]*W[3]\n        u= 0\n        for iu in range(0,nCx+1):\n            u=u+x[iu]*W[iu] \n\n        # Função de ativação\n        if (u>=0):\n            y_est= 1\n        else:\n            y_est= -1\n\n        # Erro\n        y= Y_teste[iY]\n        if (y == y_est):\n            n_certo2= n_certo2+1\n\n    p_certo2= (n_certo2/nY2)*100 \n    print(f\"Teste: {p_certo2:.2f}%\")\n    \nfor _ in range(5):\n    print(\"Treinamento nº\", _+1)\n    main_loop()\n    print(\"\")","metadata":{"execution":{"iopub.status.busy":"2023-12-12T16:46:45.943191Z","iopub.execute_input":"2023-12-12T16:46:45.943430Z","iopub.status.idle":"2023-12-12T16:46:46.506292Z","shell.execute_reply.started":"2023-12-12T16:46:45.943405Z","shell.execute_reply":"2023-12-12T16:46:46.505430Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Questão 3\n\nImplemente uma rede neural convolucional para a classificação das imagens dos personagens Bart e Homer. A base de dados contendo estas imagens foi apresentada em sala de aula.","metadata":{}},{"cell_type":"code","source":"import os\nimport cv2\nimport numpy as np\nimport seaborn as sns\nimport tensorflow as tf\nfrom sklearn.model_selection import train_test_split\nfrom tensorflow.keras.utils import to_categorical\nfrom tensorflow.keras import layers, models\n\nprint(f'tensorflow version: {tf.__version__}')","metadata":{"execution":{"iopub.status.busy":"2023-12-12T16:46:46.507458Z","iopub.execute_input":"2023-12-12T16:46:46.507734Z","iopub.status.idle":"2023-12-12T16:46:54.763991Z","shell.execute_reply.started":"2023-12-12T16:46:46.507705Z","shell.execute_reply":"2023-12-12T16:46:54.763119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Detect TPU, return appropriate distribution strategy\ntry:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver() \n    print('Running on TPU ', tpu.master())\nexcept ValueError:\n    tpu = None\n\nif tpu:\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    strategy = tf.distribute.experimental.TPUStrategy(tpu)\nelse:\n    strategy = tf.distribute.get_strategy() ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Caminho para o dataset\ndataset_path = '/kaggle/input/neural-networks-homer-and-bart-classification/homer_bart_1'\n\n# Carregar imagens e criar rótulos com base no nome do arquivo\ndef load_images_from_folder(folder):\n    images = [cv2.resize(cv2.imread(os.path.join(folder, filename)), (64, 64))\n              for filename in os.listdir(folder) if cv2.imread(os.path.join(folder, filename)) is not None]\n    labels = [0 if filename.startswith('bart') else 1 for filename in os.listdir(folder)] # Bart=0, Homer=1\n    return np.array(images) / 255.0, np.array(labels)\n\n# Carregar imagens e rótulos\nimages, labels = load_images_from_folder(dataset_path)\n\n# Divisão em conjuntos de treino e teste\nX_train, X_test, y_train, y_test = train_test_split(images, labels, test_size=0.2, random_state=42)\n\n# One-hot encoding\ny_train = to_categorical(y_train)\ny_test = to_categorical(y_test)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T16:47:02.817656Z","iopub.execute_input":"2023-12-12T16:47:02.817906Z","iopub.status.idle":"2023-12-12T16:47:03.478333Z","shell.execute_reply.started":"2023-12-12T16:47:02.817878Z","shell.execute_reply":"2023-12-12T16:47:03.477155Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Criação do modelo\nmodel = models.Sequential([\n    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(64, 64, 3)),\n    layers.MaxPooling2D((2, 2)),\n    layers.Conv2D(64, (3, 3), activation='relu'),\n    layers.MaxPooling2D((2, 2)),\n    layers.Conv2D(64, (3, 3), activation='relu'),\n    layers.Flatten(),\n    layers.Dropout(0.5),\n    layers.Dense(64, activation='relu'),\n    layers.Dense(2, activation='softmax')  # 2 classes\n])\n\n# Compilação o modelo\nmodel.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\n\n# Callbacks - Early Stopping\ncallbacks = [\n    tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3, restore_best_weights=True),\n]","metadata":{"execution":{"iopub.status.busy":"2023-12-12T16:47:03.479443Z","iopub.execute_input":"2023-12-12T16:47:03.479708Z","iopub.status.idle":"2023-12-12T16:47:03.593536Z","shell.execute_reply.started":"2023-12-12T16:47:03.479680Z","shell.execute_reply":"2023-12-12T16:47:03.592584Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Treinar o modelo\nhistory = model.fit(X_train, y_train, epochs=50, validation_data=(X_test, y_test), callbacks=callbacks)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T16:47:03.595837Z","iopub.execute_input":"2023-12-12T16:47:03.596095Z","iopub.status.idle":"2023-12-12T16:47:07.005297Z","shell.execute_reply.started":"2023-12-12T16:47:03.596067Z","shell.execute_reply":"2023-12-12T16:47:07.004212Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Avaliar o modelo\ntest_loss, test_acc = model.evaluate(X_test, y_test, verbose=2)\nprint('\\nTest accuracy:', test_acc)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T16:47:07.006604Z","iopub.execute_input":"2023-12-12T16:47:07.006946Z","iopub.status.idle":"2023-12-12T16:47:07.110417Z","shell.execute_reply.started":"2023-12-12T16:47:07.006910Z","shell.execute_reply":"2023-12-12T16:47:07.109340Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Exibir gráficos de loss e accuracy\nplt.figure(figsize=(12, 4))\n\n# Gráfico de loss\nplt.subplot(1, 2, 1)\nplt.plot(history.history['loss'], label='train')\nplt.plot(history.history['val_loss'], label='test')\nplt.title('Model Loss')\nplt.ylabel('Loss')\nplt.xlabel('Epoch')\nplt.legend()\n\n# Gráfico de accuracy\nplt.subplot(1, 2, 2)\nplt.plot(history.history['accuracy'], label='train')\nplt.plot(history.history['val_accuracy'], label='test')\nplt.title('Model Accuracy')\nplt.ylabel('Accuracy')\nplt.xlabel('Epoch')\nplt.legend()\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-12T16:47:41.076830Z","iopub.execute_input":"2023-12-12T16:47:41.077179Z","iopub.status.idle":"2023-12-12T16:47:41.445869Z","shell.execute_reply.started":"2023-12-12T16:47:41.077135Z","shell.execute_reply":"2023-12-12T16:47:41.444962Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import confusion_matrix\n\n# Prever as classes para o conjunto de teste\ny_pred = np.argmax(model.predict(X_test), axis=1)\n\n# Criar a matriz de confusão\nconf_mat = confusion_matrix(np.argmax(y_test, axis=1), y_pred)\n\n# Exibir a matriz de confusão usando seaborn\nclass_names = ['Bart', 'Homer']\nsns.heatmap(conf_mat, annot=True, fmt='d', cmap='Blues', xticklabels=class_names, yticklabels=class_names)\nplt.xlabel('Predito')\nplt.ylabel('Verdadeiro')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-12T16:47:41.447330Z","iopub.execute_input":"2023-12-12T16:47:41.447608Z","iopub.status.idle":"2023-12-12T16:47:41.717002Z","shell.execute_reply.started":"2023-12-12T16:47:41.447582Z","shell.execute_reply":"2023-12-12T16:47:41.716173Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Exibir algumas imagens do conjunto de teste com as classificações previstas\npredictions = model.predict(X_test)\n\n# Inverter one-hot encoding para obter as classes verdadeiras\ny_test_true = np.argmax(y_test, axis=1)\n\n# Mapear rótulos numéricos de volta para os nomes das classes\nclass_mapping = {0: 'Bart', 1: 'Homer'}\ny_test_true_labels = [class_mapping[label] for label in y_test_true]\n\nnum_rows = 5\nnum_cols = 3\nnum_images = num_rows * num_cols\nplt.figure(figsize=(4 * num_cols, 2.5 * num_rows))\nfor i in range(num_images):\n    plt.subplot(num_rows, 2 * num_cols, 2 * i + 1)\n    plt.xticks([])\n    plt.yticks([])\n    plt.grid(False)\n    plt.imshow(X_test[i][:,:,::-1])\n    predicted_label = np.argmax(predictions[i])\n    true_label = y_test_true_labels[i]\n    if predicted_label == y_test_true[i]:\n        color = 'blue'\n    else:\n        color = 'red'\n    plt.xlabel(f'Predição: {class_mapping[predicted_label]} ({100 * np.max(predictions[i]):2.0f}%)\\n Verdadeiro: {true_label}',\n               color=color)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-12T16:47:41.717957Z","iopub.execute_input":"2023-12-12T16:47:41.718236Z","iopub.status.idle":"2023-12-12T16:47:42.389973Z","shell.execute_reply.started":"2023-12-12T16:47:41.718207Z","shell.execute_reply":"2023-12-12T16:47:42.389157Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Questão 4\n\nImplemente uma rede neural artificial para a classificação de dígitos escritos manualmente. A base de dados é a mnist (apresentada em sala de aula).","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras import layers, models, datasets\nimport matplotlib.pyplot as plt\n\n# Carregar o conjunto de dados MNIST\n(x_train, y_train), (x_test, y_test) = datasets.mnist.load_data()\n\n# Pré-processamento dos dados\nx_train, x_test = x_train / 255.0, x_test / 255.0\n\n# Construir o modelo da rede neural\nmodel = models.Sequential([\n    layers.Flatten(input_shape=(28, 28)),\n    layers.Dense(128, activation='relu'),\n    layers.Dropout(0.2),\n    layers.Dense(10, activation='softmax')\n])\n\n# Compilar o modelo\nmodel.compile(optimizer='adam',\n              loss='sparse_categorical_crossentropy',\n              metrics=['accuracy'])\n\n# Treinar o modelo\nhistory = model.fit(x_train, y_train, epochs=5, validation_data=(x_test, y_test))\n\n# Avaliar o modelo\ntest_loss, test_acc = model.evaluate(x_test, y_test, verbose=2)\nprint('\\nTest accuracy:', test_acc)","metadata":{"execution":{"iopub.status.busy":"2023-12-12T16:47:42.391516Z","iopub.execute_input":"2023-12-12T16:47:42.391774Z","iopub.status.idle":"2023-12-12T16:48:09.641969Z","shell.execute_reply.started":"2023-12-12T16:47:42.391748Z","shell.execute_reply":"2023-12-12T16:48:09.641022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Exibir gráficos de loss e accuracy\nplt.figure(figsize=(12, 4))\n\n# Gráfico de loss\nplt.subplot(1, 2, 1)\nplt.plot(history.history['loss'], label='train')\nplt.plot(history.history['val_loss'], label='test')\nplt.title('Model Loss')\nplt.ylabel('Loss')\nplt.xlabel('Epoch')\nplt.legend()\n\n# Gráfico de accuracy\nplt.subplot(1, 2, 2)\nplt.plot(history.history['accuracy'], label='train')\nplt.plot(history.history['val_accuracy'], label='test')\nplt.title('Model Accuracy')\nplt.ylabel('Accuracy')\nplt.xlabel('Epoch')\nplt.legend()\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-12T16:48:09.643058Z","iopub.execute_input":"2023-12-12T16:48:09.643424Z","iopub.status.idle":"2023-12-12T16:48:09.977269Z","shell.execute_reply.started":"2023-12-12T16:48:09.643381Z","shell.execute_reply":"2023-12-12T16:48:09.976333Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prever as classes para o conjunto de teste\ny_pred = np.argmax(model.predict(x_test), axis=1)\n\n# Criar a matriz de confusão\nconf_mat = confusion_matrix(y_test, y_pred)\n\n# Exibir a matriz de confusão usando seaborn\nsns.heatmap(conf_mat, annot=True, fmt='d', cmap='Blues')\nplt.xlabel('Predito')\nplt.ylabel('Verdadeiro')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-12T16:48:09.978529Z","iopub.execute_input":"2023-12-12T16:48:09.978844Z","iopub.status.idle":"2023-12-12T16:48:10.983538Z","shell.execute_reply.started":"2023-12-12T16:48:09.978812Z","shell.execute_reply":"2023-12-12T16:48:10.982680Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Exibir algumas imagens do conjunto de teste com as classificações previstas\npredictions = model.predict(x_test)\nnum_rows = 5\nnum_cols = 3\nnum_images = num_rows*num_cols\nplt.figure(figsize=(4*num_cols, 2.5*num_rows))\nfor i in range(num_images):\n    plt.subplot(num_rows, 2*num_cols, 2*i+1)\n    plt.xticks([])\n    plt.yticks([])\n    plt.grid(False)\n    plt.imshow(x_test[i], cmap=plt.cm.binary)\n    predicted_label = np.argmax(predictions[i])\n    true_label = y_test[i]\n    if predicted_label == true_label:\n        color = 'blue'\n    else:\n        color = 'red'\n    plt.xlabel(f'Predição: {predicted_label} ({100*np.max(predictions[i]):2.0f}%)\\n Verdadeiro: {true_label}', color=color)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-12T16:48:10.984617Z","iopub.execute_input":"2023-12-12T16:48:10.984904Z","iopub.status.idle":"2023-12-12T16:48:12.058109Z","shell.execute_reply.started":"2023-12-12T16:48:10.984875Z","shell.execute_reply":"2023-12-12T16:48:12.057195Z"},"trusted":true},"execution_count":null,"outputs":[]}]}