Visualize the output of Vgg16 model by TSNE plot?
I need to visualize the output of Vgg16 model which classify 14 different classes. 
I load the trained model and I did replace the classifier layer with the identity() layer but it doesn't categorize the output. 

Here is the snippet:
the number of samples here is 1000 images.

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()


here is what this script has been produced: I am not sure why I have all colors for each cluster! 


The VGG16 outputs over 25k features to the classifier. I believe it's too much to t-SNE. It's a good idea to include a new nn.Linear layer to reduce this number. So, t-SNE may work better. In addition, I'd recommend you two different ways to get the features from the model:

The best way to get it regardless of the model is by using the register_forward_hook method. You may find a notebook here with an example.

If you don't want to use the register, I'd suggest this one. After loading your model, you may use the following class to extract the features:


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)

Now, you just need to call FeatNet(img) to get the features.
To include the feature reducer, as I suggested before, you need to retrain your model doing something like:
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)

Then, you can run your model returning x_r, that is, the reduced features. As I told you, 25k features are too much for t-SNE. Another method to reduce this number is by using PCA instead of nn.Linear. In this case, you send the 25k features to PCA and then train t-SNE using the PCA's output. I prefer using nn.Linear, but you need to test to check which one you get a better result.
