Визуализировать вывод модели Vgg16 по графику TSNE? - PullRequest
0 голосов
/ 09 февраля 2020

Мне нужно визуализировать вывод модели Vgg16, которая классифицирует 14 различных классов. Я загружаю обученную модель и заменяю слой классификатора слоем identity (), но он не классифицирует вывод.

Вот фрагмент: количество образцов здесь составляет 1000 изображений.

epoch = 800
PATH = 'vgg16_epoch{}.pth'.format(epoch)
checkpoint = torch.load(PATH)
model.load_state_dict(checkpoint['model_state_dict'])
optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
epoch = checkpoint['epoch']

class Identity(nn.Module):
    def __init__(self):
        super(Identity, self).__init__()

    def forward(self, x):
        return x

model.classifier._modules['6'] = Identity()
model.eval()
logits_list = numpy.empty((0,4096))  
targets = []


with torch.no_grad():
    for step, (t_image, target, classess, image_path) in enumerate(test_loader):

        t_image = t_image.cuda()
        target = target.cuda()
        target = target.data.cpu().numpy()
        targets.append(target)

        logits = model(t_image)
        print(logits.shape)

        logits = logits.data.cpu().numpy()
        print(logits.shape)
        logits_list = numpy.append(logits_list, logits, axis=0)     
        print(logits_list.shape)


tsne = TSNE(n_components=2, verbose=1, perplexity=10, n_iter=1000) 
tsne_results = tsne.fit_transform(logits_list)   

 target_ids = range(len(targets))

plt.scatter(tsne_results[:,0],tsne_results[:,1],c = target_ids ,cmap=plt.cm.get_cmap("jet", 14))
plt.colorbar(ticks=range(14))
plt.legend()
plt.show()

вот что был создан этот сценарий: я не уверен, почему у меня есть все цвета для каждого кластера ! enter image description here

1 Ответ

1 голос
/ 10 февраля 2020

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, но вам нужно проверить, какой из них вы получите лучший результат.

Надеюсь, это поможет вам.

...