Как создать ансамблевую модель для классификации с помощью pytorch, используя обученные модели?

Вопрос или проблема

Я пытаюсь создать ансамблевую модель, состоящую из двух заранее обученных моделей, используя torch, чтобы классифицировать изображение.

Ниже приведен некоторый код, основанный на этом посте.

import timm
import torch
from torch.nn import functional as F

num_classes = 100

model1 = timm.create_model("efficientnet_b0", num_classes=num_classes)
checkpoint1 = torch.load(checkpoint_path1)
model1.load_state_dict(checkpoint1["model"])

model2 = timm.create_model("efficientnet_b2", num_classes=num_classes)
checkpoint2 = torch.load(checkpoint_path2)
model2.load_state_dict(checkpoint2["model"])

class EnsembleModel(nn.Module):
    def __init__(self, modelA, modelB, num_features):
        super().__init__()
        self.modelA = modelA
        self.modelB = modelB
        self.classifier = nn.Linear(2*num_features, num_features)

    def forward(self, x):
        x1 = self.modelA(x)
        x2 = self.modelB(x)
        x = torch.cat((x1, x2), dim=1)
        x = self.classifier(F.relu(x))
        return x

model = EnsembleModel(model1, model2, num_classes)

Общие модели были предварительно обучены на GPU (cuda), и когда я выполняю прогноз из EnsembleModel, я получаю эту ошибку:

RuntimeError: Ожидались все тензоры на одном устройстве, но найдено как минимум два устройства, cpu и cuda:0! (при проверке аргумента для аргумента mat1 в методе wrapper_addmm)

из этой строки:

---> 15         x = self.classifier(F.relu(x))

Честно говоря, я даже не уверен, почему в посте предложили использовать классификатор и комбинировать их с relu.

Какой лучший способ комбинировать такие две модели?

Вот больше информации о трассировке стека, если это полезно:

/tmp/ipykernel_33/4277289726.py in forward(self, x)
     13         x2 = self.modelB(x)
     14         x = torch.cat((x1, x2), dim=1)
---> 15         x = self.classifier(F.relu(x))
     16         return x

в /opt/conda/lib/python3.7/site-packages/torch/nn/modules/module.py in _call_impl(self, *input, **kwargs)
   1049         if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
   1050                 или _global_forward_hooks или _global_forward_pre_hooks):
-> 1051             return forward_call(*input, **kwargs)
   1052         # Не проверять функции, когда используется jit
   1053         полные_обратные_хуки, не_полные_обратные_хуки = [], []

в /opt/conda/lib/python3.7/site-packages/torch/nn/modules/linear.py in forward(self, input)
     94 
     95     def forward(self, input: Tensor) -> Tensor:
---> 96         return F.linear(input, self.weight, self.bias)
     97 
     98     def extra_repr(self) -> str:

в /opt/conda/lib/python3.7/site-packages/torch/nn/functional.py in linear(input, weight, bias)
   1845     if has_torch_function_variadic(input, weight):
   1846         return handle_torch_function(linear, (input, weight), input, weight, bias=bias)
-> 1847     return torch._C._nn.linear(input, weight, bias)
   1848 
   1849 

RuntimeError: Ожидались все тензоры на одном устройстве, но найдено как минимум два устройства, cpu и cuda:0! (при проверке аргумента для аргумента mat1 в методе wrapper_addmm)

Из вашего фрагмента кода, я предполагаю, что ошибка cpu и cuda:0 не относится к вашим двум моделям, а касается входных данных x и self.classifier. Вы можете проверить их местоположение, распечатав их. Затем вы можете переместить тот, который на CPU, на GPU, используя .to(device).

Ответ или решение

Создание ансамблевой модели для классификации с использованием PyTorch

Введение

Ансамблевые модели предоставляют способ объединения нескольких предобученных моделей для повышения точности классификации. В этом руководстве мы рассмотрим, как создать ансамблевую модель, используя библиотеки PyTorch и timm, а также как избежать распространённых ошибок при работе с такими моделями.

Шаг 1: Импорт необходимых библиотек

Прежде всего, необходимо импортировать библиотеки и подготовить предобученные модели.

import timm
import torch
import torch.nn as nn
import torch.nn.functional as F

num_classes = 100

# Загружаем предобученные модели
model1 = timm.create_model("efficientnet_b0", num_classes=num_classes)
checkpoint1 = torch.load(checkpoint_path1)
model1.load_state_dict(checkpoint1["model"])

model2 = timm.create_model("efficientnet_b2", num_classes=num_classes)
checkpoint2 = torch.load(checkpoint_path2)
model2.load_state_dict(checkpoint2["model"])

Шаг 2: Создание ансамблевой модели

Теперь создадим класс EnsembleModel, который будет объединять две модели и осуществлять их совместную работу:

class EnsembleModel(nn.Module):
    def __init__(self, modelA, modelB, num_features):
        super().__init__()
        self.modelA = modelA
        self.modelB = modelB
        self.classifier = nn.Linear(2 * num_features, num_classes)

    def forward(self, x):
        x1 = self.modelA(x)
        x2 = self.modelB(x)
        x = torch.cat((x1, x2), dim=1)  # Объединяем выходы обеих моделей
        x = self.classifier(F.relu(x))    # Проходим через классификатор
        return x

Обратите внимание, что мы используем F.relu, чтобы добавить нелинейность перед подачей данных в классификатор.

Шаг 3: Убедитесь, что данные находятся на одной платформе

Ошибка, которую вы указали, связана с тем, что данные находятся на разных устройствах, например, часть на CPU, а часть на GPU. Чтобы избежать этой ошибки, убедитесь, что все тензоры находятся на одном устройстве. Обычно это устройство GPU, если таковой доступен:

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

# Перемещаем модели на GPU
model1.to(device)
model2.to(device)
ensemble_model = EnsembleModel(model1, model2, num_classes).to(device)

Также не забудьте переместить входные данные на нужное устройство перед обработкой:

# Пример входного изображения
input_image = ...  # Ваше изображение в формате тензора
input_image = input_image.to(device)

# Прогоняем через ансамблевую модель
output = ensemble_model(input_image)

Шаг 4: Вывод

Таким образом, вы создали ансамблевую модель из двух предобученных моделей и скорректировали проблему с несоответствием устройств. Вы можете расширять эту модель и добавлять дополнительные слои, если это необходимо для улучшения производительности.

Заключение

Создание ансамблевой модели — это эффективный способ повысить качество классификации в задачах компьютерного зрения. Важно следить за тем, чтобы все данные и модели находились на одном устройстве, чтобы избежать ошибок времени выполнения. Следуя вышеизложенным рекомендациям, вы сможете успешно настроить и использовать ансамблевую модель для своих нужд.

Если у вас возникнут дополнительные вопросы или проблемы, не стесняйтесь задавать их, и я с радостью помогу вам дальше.

Оцените материал
Добавить комментарий

Капча загружается...