Vision transformer: Visualize feature maps - python-3.x

I am working on visualizing feature maps of my vision transformer but i am unable to visualize feature maps. When i print model.children() it shows convolution layers but still i cannot verify the if statement.
list(model.children())
Output
[OverlapPatchEmbed(
(proj): Conv2d(3, 64, kernel_size=(7, 7), stride=(4, 4), padding=(3, 3))
(norm): LayerNorm((64,), eps=1e-05, elementwise_affine=True)
),
OverlapPatchEmbed(
(proj): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
(norm): LayerNorm((128,), eps=1e-05, elementwise_affine=True)
),
OverlapPatchEmbed(
(proj): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
(norm): LayerNorm((256,), eps=1e-05, elementwise_affine=True)
),
OverlapPatchEmbed(
(proj): Conv2d(256, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1))
(norm): LayerNorm((512,), eps=1e-05, elementwise_affine=True)
),
ModuleList(
(0): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=64)
(1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=64)
(2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), groups=64)
(3): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), paddin...
I want to access Conv2d and visulize the feature map but i am unable to do so type(model_children[i]) == Conv2d is not True and i have no idea why?
model_children = list(model.children())
# counter to keep count of the conv layers
counter = 0
# append all the conv layers and their respective wights to the list
for i in range(len(model_children)):
if type(model_children[i]) == Conv2d:
counter += 1
model_weights.append(model_children[i].weight)
conv_layers.append(model_children[i])
elif type(model_children[i]) == nn.Sequential:
for j in range(len(model_children[i])):
for child in model_children[i][j].children():
if type(child) == nn.Conv2d:
counter += 1
model_weights.append(child.weight)
conv_layers.append(child)
print(f"Total convolution layers: {counter}")
print("conv_layers")

Actually model_children[i].weight does not contain weight attribute. Inside OverlapPatchEmbed, the proj layer contains Conv2d and Conv2d consists of weight attribute. You can correct it below.
if model_children[i] == model.patch_embed1:
counter += 1
weigh = model_children[i].proj
model_weights.append(weigh.weight)
conv_layers.append(model_children[i].proj)
elif model_children[i] == model.patch_embed2:
counter += 1
weigh = model_children[i].proj
model_weights.append(weigh.weight)
conv_layers.append(model_children[i].proj)

Related

How to change the first conv layer in the resnet 18?

I have a data with 20 class, and I'd like to use pretraied model with a bit of modification.
I know if we want to change the last linear of ResNet18 to categorize 20 calss (instead of 1000); we could write the following:
resnet.fc = nn.linear(512,20)
But I don't know how to access to any other layers? Like the second convolution in Bacic block?
When I call resnet.layer1 it returns:
Sequential(
(0): BasicBlock(
(conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
(1): BasicBlock(
(conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
(relu): ReLU(inplace=True)
(conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
)
)
But how to grab and change conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)?
You can access to the layer (conv2) in sequential number (0) of layer.1 as follow:
from torchvision import datasets, transforms, models
resnet = models.resnet18(pretrained=True)
print(resnet.layer1[0].conv2)
Output:
Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1),
bias=False)

pytorch error: The size of tensor a (56) must match the size of tensor b (28) at non-singleton dimension 3

Using count_ops to calculate FLOPS for a neural network model gives me the error mentioned in the title. I have changed a pretrained model (resnet18) by using assignments. My goal is to calculate the FLOPS for each edited model (to make sure the model is passing inputs).
net = resnet18()
phi = math.pow(math.sqrt(2), 7)
# net.conv1 = nn.Conv2d(math.ceil(phi*3), math.ceil(phi*64), kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
net.conv1 = nn.Conv2d(math.ceil(3), math.ceil(phi*64), kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)
net.bn1 = nn.BatchNorm2d(math.ceil(phi*64), eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
net.relu = nn.ReLU(inplace=True)
net.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
net.layer1[0].conv1 = nn.Conv2d(math.ceil(phi*64), math.ceil(phi*64), kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
.
.
net.layer2[0].conv1 = nn.Conv2d(math.ceil(phi*64), math.ceil(phi*128), kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
.
.
net.layer3[0].conv1 = nn.Conv2d(math.ceil(phi*128), math.ceil(phi*256), kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
.
.
net.layer4[0].conv1 = nn.Conv2d(math.ceil(phi*256), math.ceil(phi*512), kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
.
.
# net.avgpool = Identity()
net.avgpool = nn.AdaptiveAvgPool2d(output_size=(1, 1))
nn.fc = nn.Linear(in_features=math.ceil(phi*512), out_features=1000, bias=True)
The edited model works when I use model.named_parameters(). I am thinking that I messed up by directly assigning layers with new values (I am not sure of the order of parameters for the layers, printing my model seems to be fine, but for the love of god not a single input passes throught the model). Want to know where I messed up in the syntax, because of which my inputs are not passing through the model.
ip = torch.rand(1,3,224,224).to(dev)
count_ops(net, ip) # Count the number of FLOPs

It is possible to get only the names of the parent components in PyTorch model

All pretrained models in Pytorch contain "parent" submodules with predefines names, for example AlexNet contains 3 "parent" submodules: features, avgpool and classifier:
model = torch.hub.load('pytorch/vision:v0.10.0','resnet101',pretrained=True)
AlexNet(
(features): Sequential(
(0): Conv2d(3, 64, kernel_size=(11, 11), stride=(4, 4), padding=(2, 2))
(1): ReLU(inplace=True)
(2): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(3): Conv2d(64, 192, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
(4): ReLU(inplace=True)
(5): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
(6): Conv2d(192, 384, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(7): ReLU(inplace=True)
(8): Conv2d(384, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(9): ReLU(inplace=True)
(10): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(11): ReLU(inplace=True)
(12): MaxPool2d(kernel_size=3, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(avgpool): AdaptiveAvgPool2d(output_size=(6, 6))
(classifier): Sequential(
(0): Dropout(p=0.5, inplace=False)
(1): Linear(in_features=9216, out_features=4096, bias=True)
(2): ReLU(inplace=True)
(3): Dropout(p=0.5, inplace=False)
(4): Linear(in_features=4096, out_features=4096, bias=True)
(5): ReLU(inplace=True)
(6): Linear(in_features=4096, out_features=1, bias=True)
)
)
Is there a method to get only these components' like mo = model.get_subs() # mo=['features','avgpool','classifier']?
You can use this:
import torch
import torchvision.models as models
model = models.alexnet(pretrained=True)
parents = [parent[0] for parent in model.named_children()] # get parents names
print(parents)
Output:
['features', 'avgpool', 'classifier']

Understanding content of pretrained model

from torchvision import models
model = models.vgg16(pretrained=True).features
for i, module in enumerate(model.modules()):
print('-' * 60)
print(type(module))
print(module)
What is 'module' in model.modules() (modules() Returns an iterator over all modules in the network.)? Why torch.nn.modules.container.Sequential is stored along with single layers?
Output:
------------------------------------------------------------
<class 'torch.nn.modules.container.Sequential'>
Sequential(
(0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU(inplace=True)
(2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(3): ReLU(inplace=True)
(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(6): ReLU(inplace=True)
(7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(8): ReLU(inplace=True)
(9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(11): ReLU(inplace=True)
(12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(13): ReLU(inplace=True)
(14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(15): ReLU(inplace=True)
(16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(18): ReLU(inplace=True)
(19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(20): ReLU(inplace=True)
(21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(22): ReLU(inplace=True)
(23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(25): ReLU(inplace=True)
(26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(27): ReLU(inplace=True)
(28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(29): ReLU(inplace=True)
(30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.pooling.MaxPool2d'>
MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.pooling.MaxPool2d'>
MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.pooling.MaxPool2d'>
MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.pooling.MaxPool2d'>
MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.conv.Conv2d'>
Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
------------------------------------------------------------
<class 'torch.nn.modules.activation.ReLU'>
ReLU(inplace=True)
------------------------------------------------------------
<class 'torch.nn.modules.pooling.MaxPool2d'>
MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
nn.Module.modules will return all modules contained inside the model recursively, that includes parent submodules and children submodules that they may have of their own. You can instead use nn.Module.children to get the direct child submodules:
for child in module.children():
print(child)
If you want to investigate with recursion you could do:
def print_children(module, i=0):
if len(list(module.modules())) == 1:
return print(' '*i, module)
for child in module.children():
print_children(child, i+2)

python - tensor : access a value

Given below is the output of VGG16 model. The command VGG16.classifier[6] output shows Linear(in_features=25088, out_features=4096, bias=True) I'm not able to understand how this works. ALso,how can I print the values of linear
VGG(
(features): Sequential(
(0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU(inplace)
(2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(3): ReLU(inplace)
(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(6): ReLU(inplace)
(7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(8): ReLU(inplace)
(9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(11): ReLU(inplace)
(12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(13): ReLU(inplace)
(14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(15): ReLU(inplace)
(16): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(17): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(18): ReLU(inplace)
(19): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(20): ReLU(inplace)
(21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(22): ReLU(inplace)
(23): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
(24): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(25): ReLU(inplace)
(26): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(27): ReLU(inplace)
(28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(29): ReLU(inplace)
(30): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(classifier): Sequential(
(0): Linear(in_features=25088, out_features=4096, bias=True)
(1): ReLU(inplace)
(2): Dropout(p=0.5)
(3): Linear(in_features=4096, out_features=4096, bias=True)
(4): ReLU(inplace)
(5): Dropout(p=0.5)
(6): Linear(in_features=4096, out_features=1000, bias=True)
)
)
VGG16 model is divided into two groups of layers named features and classifier. You can access them as VGG16.features and VGG16.classifier:
>>> VGG16 = torchvision.models.vgg16(pretrained=True)
>>> VGG16.classifier
Sequential(
(0): Linear(in_features=25088, out_features=4096, bias=True)
(1): ReLU(inplace)
(2): Dropout(p=0.5)
(3): Linear(in_features=4096, out_features=4096, bias=True)
(4): ReLU(inplace)
(5): Dropout(p=0.5)
(6): Linear(in_features=4096, out_features=1000, bias=True)
)
Further, you can access each layer of these groups of layers using indices. For example, to access the first layer of classifier portion of model, you can do:
>>> VGG16.classifier[0] # first layer of classifier portion
Linear(in_features=25088, out_features=4096, bias=True)
# and so on...
>>> VGG16.classifier[3] # fourth layer of classifier portion
Linear(in_features=4096, out_features=4096, bias=True)

Resources