Good morning,
I am having an issue finetuning a model, the feature vector changes when it should not!.
I will show two cases, the first one working as expected but not the second one:
Considerations for both cases (for debugging):
- Dataloader outputs images in the same exact order every epoch
- All layers are frozen except the last linear (requires_grad of all layers except the last one = False)
class myLoss():
def __init__(self):
self.crossEntropy = nn.CrossEntropyLoss()
def __call__(self, outputs, targets):
return self.crossEntropy(outputs[0], targets)
def set_parameter_requires_grad(model):
for param in model.parameters():
param.requires_grad = False
First case (obtaining expected result = feature vector does not change over epochs for the same input):
class myModel(nn.Module):
def __init__(self, args):
super(myModel, self).__init__()
self.backbone = nn.Sequential(
nn.Conv2d(3, 6, 5),
nn.ReLU(),
nn.MaxPool2d(2, 2),
nn.Conv2d(6, 16, 5),
nn.ReLU(),
nn.MaxPool2d(2, 2)
)
set_parameter_requires_grad(self.backbone)
self.fc = nn.Linear(13456,2)
def forward(self, x):
batchSize = x.shape[0]
x = self.backbone(x)
feat = x.view(batchSize, -1)
x = F.relu(self.fc(feat))
return x, feat
When printing “feat” the output does not change across epochs, for the same input, feat is the same.
Second case (NOT obtaining expected result = feature vector change over epochs for the same input):
class myModel(nn.Module):
def __init__(self, args):
super(myModel, self).__init__()
model = models.resnet18(pretrained=args.preTrained)
modules=list(model.children())[:-1]
self.backbone = nn.Sequential(*modules)
set_parameter_requires_grad(self.backbone)
self.fc = nn.Linear(512, 2)
def forward(self, x):
feat = self.backbone(x).squeeze()
x = self.fc(feat)
return x, feat
I am instantiating the model as:
featureExtractor = backbone(self.args)
net = myModel(self.args, featureExtractor)
output, feat = net(input)
print(feat)
In this case, when printing “feat” the output, it does change across epochs, for the same input, feat varies…
I have built a function that checks if the weights (before the last fc) has changed, the function indicates that the weights have not changed… however, the feat changes…
if epoch==0:
self.first_net = copy.deepcopy(net)
else:
for param in zip(self.first_net.named_parameters(), net.parameters()):
p1,p2 = param
if 'fc' not in p1[0]:
if p1[1].data.ne(p2.data).sum() > 0:
print('NETWORK HAS CHANGED THE WEIGHTS in layer {}'.format(p1[0]))
Am I missing something?
Thank you in advance!