Exercício – Treinar uma rede neural para classificar com precisão as rochas espaciais em fotos
Agora temos um modelo de IA que incorpora uma rede neural. Fornecemos alguns dados para nosso programa para ensinar a ele as diferentes características de rochas espaciais. O programa tem muitos neurônios e eles estão conectados em uma rede de aprendizado profundo.
Agora, é hora de treinar nosso programa. Vamos usar nossos dados de treinamento da NASA. Vamos adicionar código para ajudar nosso programa a se tornar preciso ao classificar rochas espaciais.
Iterar nos dados e aumentar a precisão
Nesta seção do código, procure a variável epochs
. Essa variável informa ao programa quantas vezes pesquisar associações em recursos. Em nosso exemplo, vamos definir o número inicial de iterações como 5.
Observação
Você pode aumentar o número de iterações para aprimorar ainda mais a precisão do modelo. Tenha em mente que aumentar o número de iterações torna a execução do código mais lenta.
Para treinar nosso modelo, carregamos a entrada da imagem da variável trainloader
que criamos no módulo Analisar imagens de rochas com IA. Os dados são armazenados no dispositivo já selecionado. Chamamos a função optimizer.zero_grad()
para zerar gradientes e evitar o acúmulo de gradientes entre iterações de treinamento.
A entrada da imagem é passada pelo modelo usando a função model.forward(inputs)
, que retorna as probabilidades de log de cada rótulo. A função criterion(logps, labels)
executa as probabilidades de log por meio do critério para obter o grafo de saída. A função loss.backward()
usa o grafo de perda para computar os gradientes. A função optimizer.step()
então atualiza os parâmetros com base no gradiente atual.
Durante o treinamento e o teste, acompanhamos os valores de perda para cada iteração e o lote completo. A cada cinco epochs
, avaliamos o modelo. Usamos a função model.eval()
com a função torch.no_grad()
para desligar partes do modelo que se comportam de modo diferente durante o treinamento versus a avaliação. Usamos esse par de funções para refinar a precisão da previsão sem atualizar os gradientes.
A função torch.exp(logps)
é usada para obter um novo tensor com as probabilidades verdadeiras. A maior probabilidade e classe do novo tensor ao longo de uma determinada dimensão é retornada da função ps.topk(1, dim=1)
. O tensor é remodelado para corresponder à mesma forma que a classe superior.
Por fim, computamos a precisão geral.
Treinar a rede neural
Siga estas etapas para treinar a rede neural em seu modelo de IA.
Volte para o Visual Studio Code e abra o arquivo do Jupyter Notebook. Em nosso exemplo, estamos usando o arquivo ClassifySpaceRockProgram.ipynb.
Verifique se você está executando o kernel correto do Jupyter. Nos cantos superior direito e inferior esquerdo do Visual Studio, altere para o ambiente Anaconda
('myenv')
que você criou antes.Adicione o código a seguir em uma nova célula e depois execute a célula.
# Set the initial number of iterations to search for associations epochs = 5 print_every = 5 # Initialize the loss variables running_loss = 0 train_losses, test_losses = [], [] # Track the current training step, start at 0 steps = 0 # Search for associations in the features for epoch in range(epochs): # Count each epoch epoch += 1 # Load in all of the image inputs and labels from the TRAIN loader for inputs, labels in trainloader: # Count each training step steps += 1 print('Training step ', steps) # Load the inputs and labels to the already selected device inputs, labels = inputs.to(device), labels.to(device) # Zero out gradients to avoid accumulations of gradiants across training iterations optimizer.zero_grad() # Pass the images through the model, return the log probabilities of each label logps = model.forward(inputs) # Run the log probabilities through the criterion to get the output graph loss = criterion(logps, labels) # Use the loss graph to compute gradients loss.backward() # Update the parameters based on the current gradient optimizer.step() # Add the actual loss number to the running loss total running_loss += loss.item() # Every 5 steps, evaluate the model if steps % print_every == 0: # Initialize loss and accuracy test_loss = 0 accuracy = 0 # Start the model evaluation model.eval() # Refine the accuracy of the prediction without updating the gradients with torch.no_grad(): # Load in all of the image inputs and labels from the TEST loader for inputs, labels in testloader: # Load the inputs and labels to the already selected device inputs, labels = inputs.to(device), labels.to(device) # Pass the images through the model, return the log probabilities of each label logps = model.forward(inputs) # Run the log probabilities through the criterion to get the output graph batch_loss = criterion(logps, labels) # Add the actual loss number to the running loss total for the test batch test_loss += batch_loss.item() # Return a new tensor with the true probabilities ps = torch.exp(logps) # Return the largest probability and class of the new tensor along a given dimension top_p, top_class = ps.topk(1, dim=1) # Reshape the tensor to match the same shape as the top class equals = top_class == labels.view(*top_class.shape) # Compute the accuracy and add it to the running accuracy count for the test batch accuracy += torch.mean(equals.type(torch.FloatTensor)).item() # Append the training and testing losses train_losses.append(running_loss/len(trainloader)) test_losses.append(test_loss/len(testloader)) # Display the accuracy of the prediction with 3 digits in the fractional part of the decimal print(f"\n Epoch {epoch}/{epochs}: " f"Train loss: {running_loss/print_every:.3f}.. " f"Test loss: {test_loss/len(testloader):.3f}.. " f"Test accuracy: {accuracy/len(testloader):.3f}\n") # Train the model running_loss = 0 model.train() # After 5 training steps, start the next epoch # Break here in case the trainloader has remaining data break
À medida que o build progride, a saída mostra cada etapa de treinamento e época concluída:
Training step 1 Training step 2 Training step 3 Training step 4 Training step 5 Epoch 1/5: Train loss: 0.550.. Test loss: 0.282.. Test accuracy: 0.902 Training step 6 Training step 7 Training step 8 Training step 9 Training step 10 Epoch 2/5: Train loss: 0.451.. Test loss: 0.311.. Test accuracy: 0.842 Training step 11 Training step 12 Training step 13 ...
Você percebe que a saída de cada época sucessiva demora um pouco mais para ser exibida do que a anterior?
Analisar a saída de treinamento
Depois que cinco épocas forem concluídas, o sistema atingirá nosso limite epoch
.
...
Training step 19
Training step 20
Epoch 4/5: Train loss: 0.216.. Test loss: 0.189.. Test accuracy: 0.906
Training step 21
Training step 22
Training step 23
Training step 24
Training step 25
Epoch 5/5: Train loss: 0.234.. Test loss: 0.175.. Test accuracy: 0.935
A saída mostra a precisão da previsão para cada iteração de época com perdas de treinamento e teste e a precisão do teste.
Aqui estão os resultados de nosso teste com cinco épocas. Seus resultados específicos serão diferentes porque o computador escolhe um conjunto de imagens aleatórias para cada execução de teste. Os resultados revelam a perda de treinamento, a perda de teste e a precisão. Tudo isso depende da imagem escolhida.
Época | Perda de treinamento | Perda de teste | Precisão de teste |
---|---|---|---|
1 | 0,550 | 0,282 | 0,902 |
2 | 0,451 | 0,311 | 0,842 |
3 | 0,342 | 0,233 | 0,902 |
4 | 0,216 | 0,189 | 0,906 |
5 | 0,234 | 0,175 | 0,935 |