<jupyter_start><jupyter_text>Projeto 14: Rede Neural ConvolucionalClassificação de gatos e cachorros Etapa 01: Importação das Bibliotecas<jupyter_code>import torch
import torch.nn as nn
from torch import optim
from torchvision import datasets  # Acessar os datasets instalados no pytorch
import torchvision.transforms as transforms  # Transformações e carregamento das imagens
import zipfile  # Descompactação de um arquivo
torch.manual_seed(123)<jupyter_output><empty_output><jupyter_text>Etapa 02: Construção do Modelo<jupyter_code># in_channels = 3 -> imagens coloridas, canal R G B
# output = (input - filter + 1) / stride
classificador = nn.Sequential(nn.Conv2d(in_channels = 3, out_channels = 32, kernel_size = 3),
                              nn.ReLU(),
                              nn.BatchNorm2d(num_features = 32),
                              # (64 - 3 + 1) / 1
                              nn.MaxPool2d(kernel_size = 2),  # Divide pela metade
                              # 31 x 31 
                              nn.Conv2d(32, 32, 3),
                              nn.ReLU(),
                              nn.BatchNorm2d(32),
                              # (31 - 3 + 1) / 1 = 29x29p
                              nn.MaxPool2d(2),
                              # 14x14p
                              nn.Flatten(),
                              # 6272 -> 128 -> 128 -> 1
                              nn.Linear(in_features = 14*14*32, out_features = 128),
                              nn.ReLU(),
                              nn.Dropout(0.2),
                              nn.Linear(128, 128),
                              nn.ReLU(),
                              nn.Dropout(0.2),
                              nn.Linear(128, 1),
                              nn.Sigmoid())  
criterion = nn.BCELoss()
optimizer = optim.Adam(classificador.parameters())<jupyter_output><empty_output><jupyter_text>Etapa 03: Base de dados<jupyter_code># Importar arquivos do google drive
from google.colab import drive
drive.mount('/content/gdrive')
# Acessar a base de dados no google drive e extrair o arquivo .zip
path = '/content/gdrive/MyDrive/Deep Learning/Bases/dataset.zip'
zip_object = zipfile.ZipFile(file = path, mode = 'r')
zip_object.extractall('./')
zip_object.close()
data_dir_train = '/content/dataset/training_set'
data_dir_test = '/content/dataset/test_set'
# Transformador para a base de dados de treinamento
transform_train = transforms.Compose(
    [
     transforms.Resize([64, 64]),  # Redimensionamento das imagens, padronização 
     transforms.RandomHorizontalFlip(),  # Transformações na horizontal da imagem (alinhamento horizontal)
     transforms.RandomAffine(degrees=7, translate = (0, 0.07), shear = 0.2, scale = (1, 1.2)),
     transforms.ToTensor()  # Tranforma para o formato de tensor
    ]
)
# Transformador para a base de dados de teste
transform_test = transforms.Compose(
    [
     transforms.Resize([64, 64]),  # Redimensionamento das imagens, padronização 
     transforms.ToTensor()  # Tranforma para o formato de tensor
    ]
)
train_dataset = datasets.ImageFolder(data_dir_train, transform = transform_train)
train_dataset
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size = 32, shuffle = True)
test_dataset = datasets.ImageFolder(data_dir_test, transform = transform_test)
test_dataset
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size = 32, shuffle = True)<jupyter_output><empty_output><jupyter_text>Etapa 04: Treinamento do Modelo<jupyter_code>device = torch.device('cuda') if torch.cuda.is_available() else torch.device('cpu')
device
classificador.to(device)
def training_loop(loader, epoch):
    running_loss = 0.  # Calcular o erro 
    running_accuracy = 0.  # Calcular a taxa de acerto

    for i, data in enumerate(loader):
        inputs, labels = data 
        inputs, labels = inputs.to(device), labels.to(device)

        optimizer.zero_grad()  # Zerando o gradiente
        outputs = classificador(inputs)  # Classificação (respostas -> retorna um valor apenas)

        loss = criterion(outputs, labels.float().view(*outputs.shape))  # Erro
        loss.backward()  # Backpropagation

        optimizer.step()  # Atualização dos pesos

        running_loss += loss.item()  # Acumulo do erro (somatório do running loss)

        predicted = torch.tensor([1 if output > 0.5 else 0 for output in outputs]).to(device)  # Percorre a lista de outputs classificando em 0 ou 1

        equals = predicted == labels.view(*predicted.shape)  # Verifica se o valor previsto é igual ao que está no label

        accuracy = torch.mean(equals.float())
        running_accuracy += accuracy

        # Imprimindo os dados referentes a esse loop
        print('\rÉpoca {:3d} - Loop {:3d} de {:3d}: perda {:03.2f} - precisão {:03.2f}'.format(epoch +1,
                                                                                               i + 1,
                                                                                               len(loader),
                                                                                               loss,
                                                                                               accuracy), end = '\r')
        
    # Imprimindo os dados referentes a época
    print('\rÉPOCA {:3d} FINALIZADA: perda {:.5f} - precisão {:.5f}'.format(epoch + 1,
                                                                            running_loss/len(loader),
                                                                            running_accuracy/len(loader)))
for epoch in range(10):
    print('Treinando...')
    training_loop(train_loader, epoch)
    classificador.eval()  # Modo de avaliação
    print('Validando...')
    training_loop(test_loader, epoch)
    classificador.train()<jupyter_output>Treinando...
ÉPOCA   1 FINALIZADA: perda 0.65273 - precisão 0.62650
Validando...
ÉPOCA   1 FINALIZADA: perda 0.65694 - precisão 0.61133
Treinando...
ÉPOCA   2 FINALIZADA: perda 0.57850 - precisão 0.70800
Validando...
ÉPOCA   2 FINALIZADA: perda 0.55756 - precisão 0.71777
Treinando...
ÉPOCA   3 FINALIZADA: perda 0.53349 - precisão 0.73400
Validando...
ÉPOCA   3 FINALIZADA: perda 0.50779 - precisão 0.74609
Treinando...
ÉPOCA   4 FINALIZADA: perda 0.52343 - precisão 0.74725
Validando...
ÉPOCA   4 FINALIZADA: perda 0.46025 - precisão 0.78613
Treinando...
ÉPOCA   5 FINALIZADA: perda 0.49453 - precisão 0.75925
Validando...
ÉPOCA   5 FINALIZADA: perda 0.38096 - precisão 0.82715
Treinando...
ÉPOCA   6 FINALIZADA: perda 0.47134 - precisão 0.76925
Validando...
ÉPOCA   6 FINALIZADA: perda 0.27227 - precisão 0.89648
Treinando...
ÉPOCA   7 FINALIZADA: perda 0.47022 - precisão 0.78525
Validando...
ÉPOCA   7 FINALIZADA: perda 0.21595 - precisão 0.92285
Treinando...
ÉPOCA   8 FINALIZADA: perda 0.44742[...]<jupyter_text>Etapa 05: Avaliação do Modelo<jupyter_code>def classificar_imagem(fname):
    from PIL import Image  # Biblioteca para visualização de imagens em python
    import matplotlib.pyplot as plt 
    imagem_teste = Image.open(data_dir_test + '/' + fname)
    plt.imshow(imagem_teste)

    import numpy as np 
    # Ajuste das imagens passadas como teste
    imagem_teste = imagem_teste.resize((64, 64))
    imagem_teste = np.array(imagem_teste.getdata()).reshape(*imagem_teste.size, 3)
    imagem_teste = imagem_teste / 255
    imagem_teste = imagem_teste.transpose(2, 0, 1)
    imagem_teste = torch.tensor(imagem_teste, dtype=torch.float).view(-1, *imagem_teste.shape)

    classificador.eval()
    imagem_teste = imagem_teste.to(device)
    output = classificador.forward(imagem_teste)

    if (output > 0.5):
        output = 1
    else:
        output = 0
    
    print('Previsão: ', output)

    idx_to_class = {value: key for key, value in test_dataset.class_to_idx.items()}

    return idx_to_class[output]

imagem = '/gato/cat.3500.jpg'
classificar_imagem(imagem)
imagem = '/cachorro/dog.3502.jpg'
classificar_imagem(imagem)<jupyter_output>Previsão:  0
{'fraction_non_alphanumeric': 0.09698329593617552, 'fraction_numerical': 0.04425330341560708, 'mean_word_length': 2.153694968553459, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 24, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '584729', 'license': 'MIT', 'n_tokens_mistral': 2828, 'n_tokens_neox': 2527, 'n_words': 613, 'path': 'Projeto_14.ipynb', 'repo_name': 'Paulo-vitorCS/DeepLearning', 'size': '8022'}