Я пытаюсь выполнить регрессию в модели преобразователей зрения и не могу заменить последний уровень классификации слоем регрессии.
class RegressionViT(nn.Module):
def __init__(self, in_features=224 * 224 * 3, num_classes=1, pretrained=True):
super(RegressionViT, self).__init__()
self.vit_b_16 = vit_b_16(pretrained=pretrained)
# Accessing the actual output feature size from vit_b_16
self.regressor = nn.Linear(self.vit_b_16.heads[0].in_features, num_classes * batch_size)
def forward(self, x):
x = self.vit_b_16(x)
x = self.regressor(x)
return x
# Model
model = RegressionViT(num_classes=1)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)
criterion = nn.MSELoss() # Use appropriate loss function for regression
optimizer = optim.Adam(model.parameters(), lr=0.0001)
Я получаю эту ошибку, когда пытаюсь инициализировать и запустить модель
RuntimeError: mat1 and mat2 shapes cannot be multiplied (32x1000 and 768x32)
Проблема в том, что между слоем регрессии и слоем модели vit_b_16 существует несоответствие. Каков был бы правильный способ решения этой проблемы?
Если вы посмотрите исходный код VisionTransformer , то в этом разделе вы заметите, что self.heads
представляет собой последовательный, а не линейный слой. По умолчанию он содержит только один слой head
, соответствующий последнему слою классификации. Чтобы перезаписать этот слой, вы можете сделать:
heads = self.vit_b_16.heads
heads.head = nn.Linear(heads.head.in_features, num_classes)
Теперь я решил эту проблему @Ivan, но есть проблема между последним слоем модели и головой регрессии, которую я добавляю: если я изменю размер последнего слоя, я могу потерять данные.
Что вы подразумеваете под «изменить размер последнего слоя»?
Эта модель vit_b_16 предназначена для классификации, но вместо этого я хочу выполнить регрессию, поэтому я отредактировал последний слой, включив в него головку регрессии, но между последним слоем модели и головкой регрессии, которую я сейчас использую, существует несоответствие.
Непонятно, что вы подразумеваете под «головкой регрессии», в вашем примере у вас есть линейный слой с логитами num_classes x chunk_size.
Таким образом, модель vit_b_16 правильно обучена для целей классификации. Я хочу использовать эту модель для целей вращательной инвариантности. Я хочу удалить последний слой, предназначенный для классификации, и заменить его слоем регрессии.
Тогда у вас будет nn.Linear(heads.head.in_features, 1)
, верно?
Поскольку я получаю пакетные выходные данные из модели vit_b_16, они будут выглядеть как nn.Linear(heads.head.in_features, 1*batch_size)
Это кажется неверным, количество параметров не зависит от размера пакета. Если у вас есть слой, инициализированный как nn.Linear(in_features, 1)
, и входная форма (batch_size, in_features)
, то выходной тензор будет (batch_size, 1)
. Таким образом, out_features
вашего линейного слоя должен быть 1
, а не 1*batch_size
.
это не ошибка, это кусок кода. требуется минимальный воспроизводимый пример. Вы знаете, что делать.