How can I extract intermediate layer output from loaded CNN model?

has anyone used this package? torch-intermediate-layer-getter · PyPI

Hey guys, I want to achieve the same using the C++ front-end, but no “register_forward_hook” is available in libtorch.

Libtorch’s documentation is hard to interpret for a newbie like me. Can somebody help??

@ptrblck, Hi, I have a matrix operation that changes the values of output from lets say 2nd conv layer of VGG16 during forward pass of training which leads to my model not converging. Is there any way I can address this issue so that even after matrix operation in the forward pass, my models reaches sufficient level of accuracy?

I don’t fully understand the issue. Did you add this “matrix operation”? If so, could you just remove it again?

@ptrblck
Yes, I’m adding this operation. And I can remove it as well, but my usecase wants me to add this operation for some reason in the forward pass, but if I add it directly without training, there is a huge drop in accuracy so I was just wondering if I train the model having this operating being included, but the model doesnt seem to converge. Below code shows the operator as matrix operation.

def train(self, head, bottleneck, avgpool, tail, operator):
head = head.to(self.device)
bottleneck = bottleneck.to(self.device)
tail = tail.to(self.device)
avgpool = avgpool.to(self.device)
torch.autograd.set_detect_anomaly(True)
for epoch in range(self.num_epochs):
for i, (imgs , labels) in enumerate(self.train_loader):
imgs = imgs.to(self.device)
labels = labels.to(self.device)

            labels_hat = head(imgs)
            labels_hat_sk = operator.operate(labels_hat)
            labels_hat_sk = self.remove_nan_values(labels_hat_sk)
            labels_hat_sk = labels_hat_sk.to(self.device)
            #print(labels_hat_sk.shape)
            
            labels_hat = bottleneck(labels_hat_sk)
            
            labels_hat = avgpool(labels_hat)
            labels_hat_flat = labels_hat.view(self.batch_size, -1)
            #print(labels_hat_flat.shape)
            
            labels_hat = tail(labels_hat_flat)
            n_corrects = (labels_hat.argmax(axis=1)==labels).sum().item()
            loss_value = self.criterion(labels_hat, labels)
            loss_value.backward()
            self.optimizer.step()
            self.optimizer.zero_grad()
            if (i+1) % 250 == 0:
                print(f'epoch {epoch+1}/{self.num_epochs}, step: {i+1}/{self.n_total_step}: loss = {loss_value:.5f}, acc = {100*(n_corrects/labels.size(0)):.2f}%')
        print()

I don’t know what the operation does, but since it’s breaking the convergence you should consider removing it or at least check why your use case apparently wants you to add it.

Basically, the operator does some random projections and I want to evaluate their impact on model performance. Thats the reason I need perform training to evaluate its impact! I just want to know what steps should I take or make changes so that my model converges even after these projections.

You could play around with some hyperparameters of the training, such as the learning rate etc., but the current evaluation shows a catastrophic impact of this approach as it doesn’t let the model converge anymore.

You can think of this operator as an encoder and decoder, so encoder encodes the intermediate output of a layer and then decoder decodes it so that we pass it as an input to the next layer. But this mechanism has a negative impact on the training accuracy, is there any way I can make my model converge even after this bottleneck of encoding and decoding?