VGG16 выводит более 25 тыс. Функций в классификатор. Я считаю, что это слишком много для t-SNE. Рекомендуется добавить новый слой nn.Linear
, чтобы уменьшить это число. Таким образом, t-SNE может работать лучше. Кроме того, я бы порекомендовал вам два разных способа получения функций из модели:
1) Лучший способ получить его независимо от модели - использовать метод register_forward_hook
. Вы можете найти блокнот здесь с примером.
2) Если вы не хотите использовать реестр, я бы предложил этот. После загрузки вашей модели вы можете использовать следующий класс для извлечения функций:
class FeatNet (nn.Module):
def __init__(self, vgg):
super(FeatNet, self).__init__()
self.features = nn.Sequential(*list(vgg.children())[:-1]))
def forward(self, img):
return self.features(img)
Теперь вам просто нужно позвонить FeatNet(img)
, чтобы получить функции.
Чтобы включить средство понижения возможностей, как я предлагал ранее, вам необходимо переобучить вашу модель, выполнив что-то вроде:
class FeatNet (nn.Module):
def __init__(self, vgg):
super(FeatNet, self).__init__()
self.features = nn.Sequential(*list(vgg.children())[:-1]))
self.feat_reducer = nn.Sequential(
nn.Linear(25088, 1024),
nn.BatchNorm1d(1024),
nn.ReLU()
)
self.classifier = nn.Linear(1024, 14)
def forward(self, img):
x = self.features(img)
x_r = self.feat_reducer(x)
return self.classifier(x_r)
Затем вы можете запустить модель, возвращающую x_r
, то есть , уменьшенные черты. Как я уже говорил, 25 тыс. Функций слишком много для t-SNE. Другой способ уменьшить это число - использовать PCA вместо nn.Linear
. В этом случае вы отправляете функции 25k в PCA, а затем обучаете t-SNE, используя выходные данные PCA. Я предпочитаю использовать nn.Linear
, но вам нужно проверить, какой из них вы получите лучший результат.
Надеюсь, это поможет вам.