Deep Learning

170_Image Classification using Torchvision(3)

elif 2024. 5. 19. 23:06

Continuing from the previous post(169_Image Classification using Torchvision(2)).

 

%%time

base_model, history = train_model(base_model, data_loaders, dataset_sizes, device)

 

 

To make the results easier to interpret, add a visualization function.

 

def plot_training_history(history):
  fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(18, 6))

  ax1.plot(history['train_loss'], label='train loss')
  ax1.plot(history['val_loss'], label='validation loss')

  ax1.xaxis.set_major_locator(MaxNLocator(integer=True))
  ax1.set_ylim([-0.05, 1.05])
  ax1.legend()
  ax1.set_ylabel('Loss')
  ax1.set_xlabel('Epoch')

  ax2.plot(history['train_acc'], label='train accuracy')
  ax2.plot(history['val_acc'], label='validation accuracy')

  ax2.xaxis.set_major_locator(MaxNLocator(integer=True))
  ax2.set_ylim([-0.05, 1.05])
  ax2.legend()

  ax2.set_ylabel('Accuracy')
  ax2.set_xlabel('Epoch')

  fig.suptitle('Training history')
  
plot_training_history(history)

 

The original code is written like this, but the following error occurred.

 

can't convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.

 

The error ocurred because train_acc and val_acc in history were set to cuda. Therefore, I modified the code to move them to cpu for execution.

 

def to_numpy(tensor):
    if isinstance(tensor, torch.Tensor):
        return tensor.cpu().numpy()
    return tensor

def plot_training_history(history):
    train_loss = [to_numpy(x) for x in history['train_loss']]
    val_loss = [to_numpy(x) for x in history['val_loss']]
    train_acc = [to_numpy(x) for x in history['train_acc']]
    val_acc = [to_numpy(x) for x in history['val_acc']]
    
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(18, 6))

    ax1.plot(train_loss, label='train loss')
    ax1.plot(val_loss, label='validation loss')

    ax1.xaxis.set_major_locator(MaxNLocator(integer=True))
    ax1.set_ylim([-0.05, 1.05])
    ax1.legend()
    ax1.set_ylabel('Loss')
    ax1.set_xlabel('Epoch')

    ax2.plot(train_acc, label='train accuracy')
    ax2.plot(val_acc, label='validation accuracy')

    ax2.xaxis.set_major_locator(MaxNLocator(integer=True))
    ax2.set_ylim([-0.05, 1.05])
    ax2.legend()

    ax2.set_ylabel('Accuracy')
    ax2.set_xlabel('Epoch')

    fig.suptitle('Training history')

plot_training_history(history)

 

 

 

The pre-trained model showed high accuracy and low loss even after only 3 epochs.

 

def show_predictions(model, class_names, n_images=6):
  model = model.eval()
  images_handeled = 0
  plt.figure()

  with torch.no_grad():
    for i, (inputs, labels) in enumerate(data_loaders['test']):
      inputs = inputs.to(device)
      labels = labels.to(device)

      outputs = model(inputs)
      _, preds = torch.max(outputs, 1)

      for j in range(inputs.shape[0]):
        images_handeled += 1
        ax = plt.subplot(2, n_images//2, images_handeled)
        ax.set_title(f'predicted: {class_names[preds[j]]}')
        imshow(inputs.cpu().data[j])
        ax.axis('off')

        if images_handeled == n_images:
          return
      
show_predictions(base_model, class_names, n_images=8)

 

The above code defines a function that uses the given model to perform predictions on the test data and visualizes the predicted results. In the first for loop, it iterates through the data in batches using the test data loader, selecting the class index with the highest value in the output as the predicted value. In the second for loop, it iterates through each image within the batch and continues until the specified number of visualized images is reached.

It can be observed that the model accurately predicts even very blurry or obscured parts.

 

def get_predictions(model, data_loader):
  model = model.eval()
  predictions = []
  real_values = []
  with torch.no_grad():
    for inputs, labels in data_loader:
      inputs = inputs.to(device)
      labels = labels.to(device)

      outputs = model(inputs)
      _, preds = torch.max(outputs, 1)
      predictions.extend(preds)
      real_values.extend(labels)
  predictions = torch.as_tensor(predictions).cpu()
  real_values = torch.as_tensor(real_values).cpu()
  return predictions, real_values

y_pred, y_test = get_predictions(base_model, data_loaders['test'])
print(classification_report(y_test, y_pred, target_names=class_names))

 

 

 

The above code defines a function that uses the given model to perform predictions on the data loader and returns the actual and predicted values. Then, it uses this function to make predictions on the test data and prints a report evaluating the model's performance. The report shows that the model is surprisingly accurate. Continued in the next post..

 

ref : Venelin Valkov - Get SH_T Done with PyTorch_ Solve Real-world Machine Learning Problems with Deep Neural Networks in Python-Venelin Valkov (2020)