Closed Newboot32 closed 2 years ago
You should not use InceptionResnetV1 to load the saved model. Their class structure is different, although the model is the same (because the saved model is a class that I defined). You should import the script of facenet2 which is the class of the saved model.
I see. Thank you
I'm really sorry for reopening the issue. I've tried importing facenet2 but it still won't load.
What I imported :
class PKSampler(Sampler):
def __init__(self, data_source, p=15, k=20):
super().__init__(data_source)
self.p = p
self.k = k
self.data_source = data_source
def __iter__(self):
pk_count = len(self) // (self.p * self.k)
for _ in range(pk_count):
labels = np.random.choice(np.arange(len(self.data_source.label_to_samples)), self.p, replace=False)
for l in labels:
indices = self.data_source.label_to_samples[l]
replace = True if len(indices) < self.k else False
for i in np.random.choice(indices, self.k, replace=replace):
yield i
def __len__(self):
pk = self.p * self.k
samples = ((len(self.data_source) - 1) // pk + 1) * pk
return samples
def grouper(iterable, n):
it = itertools.cycle(iter(iterable))
for _ in range((len(iterable) - 1) // n + 1):
yield list(itertools.islice(it, n))
class PKSampler2(Sampler):
def __init__(self, data_source, p=15, k=20):
super().__init__(data_source)
self.p = p
self.k = k
self.data_source = data_source
def __iter__(self):
rand_labels = np.random.permutation(np.arange(len(self.data_source.label_to_samples)))
for labels in grouper(rand_labels, self.p):
for l in labels:
indices = self.data_source.label_to_samples[l]
replace = True if len(indices) < self.k else False
for j in np.random.choice(indices, self.k, replace=replace):
yield j
def __len__(self):
num_labels = len(self.data_source.label_to_samples)
samples = ((num_labels - 1) // self.p + 1) * self.p * self.k
return samples
class ArcMarginProduct(nn.Module):
def __init__(self, in_features, out_features):
super().__init__()
self.weight = nn.Parameter(torch.Tensor(out_features, in_features))
self.reset_parameters()
def reset_parameters(self):
nn.init.xavier_uniform_(self.weight)
def forward(self, features):
cosine = F.linear(F.normalize(features), F.normalize(self.weight))
return cosine
def get_Optimizer(model, optimizer_type=None, lr=1e-3, weight_decay=1e-3):
if(optimizer_type=='sgd'):
return optim.SGD(model.parameters(), lr=lr, momentum=0.9, nesterov=True, weight_decay=weight_decay)
elif(optimizer_type=='rmsprop'):
return optim.RMSprop(model.parameters(), lr=lr, weight_decay=weight_decay)
elif(optimizer_type=='adadelta'):
return optim.Adadelta(model.parameters(), lr=lr, weight_decay=weight_decay)
else:
return optim.Adam(model.parameters(), lr=lr, weight_decay=weight_decay)
def get_Scheduler(optimizer, lr, scheduler_name=None):
if(scheduler_name=='cyclic'):
return optim.lr_scheduler.CyclicLR(optimizer, base_lr=5e-4, max_lr=lr, step_size_up=500)
elif(scheduler_name=='cosine'):
return optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=1000)
elif(scheduler_name=='multistep'):
return optim.lr_scheduler.MultiStepLR(optimizer, milestones=[5, 10, 15, 20], gamma=0.1)
else:
return optim.lr_scheduler.StepLR(optimizer, step_size=1, gamma=0.7)
class InceptionResnet(nn.Module):
def __init__(self, device, pool=None, dropout=0.3, pretrain=True):
super(InceptionResnet, self).__init__()
# fit an image, the output is a 512 embedding original
# the model is pre-trained on vggface2
# pretrained='vggface2'
if pretrain:
self.net = InceptionResnetV1(pretrained='vggface2', dropout_prob=dropout, device=device)
else:
self.net = InceptionResnetV1(dropout_prob=dropout, device=device)
# the number of channels in the output of convolutional layers
self.out_features = self.net.last_linear.in_features
# keep convolutional layers only and remove linear layers and global average pooling layer
if pool == 'gem':
self.net.avgpool_1a = GeM(p_trainable=True)
def forward(self, x):
# return a 512 dimension vector
return self.net(x)
class EfficientNetEncoderHead(nn.Module):
def __init__(self, depth, pretrain=True):
super(EfficientNetEncoderHead, self).__init__()
self.depth = depth
if pretrain:
self.net = EfficientNet.from_pretrained(f'efficientnet-b{self.depth}')
else:
self.net = EfficientNet.from_name(f'efficientnet-b{self.depth}')
self.out_features = self.net._fc.in_features
def forward(self, x):
# only the cnn part
return self.net.extract_features(x)
class SEResNeXt101(nn.Module):
def __init__(self, pretrained=True):
super(SEResNeXt101, self).__init__()
self.net = timm.create_model('gluon_seresnext101_32x4d', pretrained=pretrained)
# the output size of this model
self.out_features = self.net.fc.in_features
def forward(self, x):
return self.net.forward_features(x)
def gem(x, p=3, eps=1e-6):
return F.avg_pool2d(x.clamp(min=eps).pow(p), (x.size(-2), x.size(-1))).pow(1./p)
class GeM(nn.Module):
def __init__(self, p=3, eps=1e-6, p_trainable=True):
super(GeM,self).__init__()
if p_trainable:
self.p = Parameter(torch.ones(1)*p)
else:
self.p = p
self.eps = eps
def forward(self, x):
return gem(x, p=self.p, eps=self.eps)
def __repr__(self):
return self.__class__.__name__ + '(' + 'p=' + '{:.4f}'.format(self.p.data.tolist()[0]) + ', ' + 'eps=' + str(self.eps) + ')'
class FaceNet(nn.Module):
def __init__(self, model_name=None, pool=None, dropout=0.0, embedding_size=512, device='cuda', pretrain=True):
super(FaceNet, self).__init__()
# Backbone
# three models choice 1. SE-ResNeXt101 2.EfficientNetB7 3.InceptionResnetV1 (Pre-trained for face recog.)
self.model_name = model_name
# model (backbone)
if(model_name=='resnet'):
self.model = SEResNeXt101(pretrain)
elif(model_name=='effnet'):
self.model = EfficientNetEncoderHead(depth=3, pretrain=pretrain)
else:
self.model = InceptionResnet(device, pool=pool, dropout=dropout, pretrain=pretrain)
if(pool == "gem"):
self.global_pool = GeM(p_trainable=True)
else:
self.global_pool = nn.AdaptiveAvgPool2d(1)
self.neck = nn.Sequential(
nn.Linear(self.model.out_features, embedding_size, bias=True),
nn.BatchNorm1d(embedding_size, eps=0.001),
#nn.Sigmoid()
)
self.dropout = nn.Dropout(p=dropout)
def forward(self, x):
# backbone
if self.model_name == None:
return self.model(x)
x = self.model(x)
# global pool
x = self.global_pool(x)
x = self.dropout(x)
# change the output from cnn to a vector first
x = x[:,:,0,0]
# neck
embeddings = self.neck(x)
return embeddings
class ArcMarginProduct(nn.Module):
def __init__(self, in_features, out_features):
super().__init__()
self.weight = nn.Parameter(torch.Tensor(out_features, in_features))
self.reset_parameters()
def reset_parameters(self):
nn.init.xavier_uniform_(self.weight)
def forward(self, features):
cosine = F.linear(F.normalize(features), F.normalize(self.weight))
return cosine
class FaceNet2(nn.Module):
def __init__(self, num_classes, model_name=None, pool=None, dropout=0.0, embedding_size=512, device='cuda', pretrain=True):
super(FaceNet2, self).__init__()
# Backbone (backbone)
# three models choice 1. SE-ResNeXt101 2.EfficientNetB7 3.InceptionResnetV1 (Pre-trained for face recog.)
self.model_name = model_name
# model
if(model_name=='resnet'):
self.model = SEResNeXt101(pretrain)
elif(model_name=='effnet'):
self.model = EfficientNetEncoderHead(depth=3, pretrain=pretrain)
else:
self.model = InceptionResnet(device, pool=pool, dropout=dropout, pretrain=pretrain)
# global pooling
if(pool == "gem"):
# Generalizing Pooling
self.global_pool = GeM(p_trainable=True)
else:
# global average pooling
self.global_pool = nn.AdaptiveAvgPool2d(1)
# neck
self.neck = nn.Sequential(
nn.Linear(self.model.out_features, embedding_size, bias=True),
nn.BatchNorm1d(embedding_size, eps=0.001),
)
self.dropout = nn.Dropout(p=dropout)
self.head = ArcMarginProduct(embedding_size, num_classes)
def forward(self, x):
# backbone
if self.model_name == None:
embeddings = self.model(x)
logits = self.head(embeddings)
return {'logits': logits, 'embeddings': embeddings}
x = self.model(x)
# global pool
x = self.global_pool(x)
x = self.dropout(x)
# change the output from cnn to a vector first
x = x[:,:,0,0]
# neck
embeddings = self.neck(x)
# vector with num_classes
logits = self.head(embeddings)
return {'logits': logits, 'embeddings': embeddings}
def load(save_path):
save_path = '/content/drive/MyDrive/export/InceptionResNetV1_ArcFace.pt'
checkpoint = torch.load(save_path)
model = checkpoint['model']
optimizer = checkpoint['optimizer']
scheduler = checkpoint['scheduler']
print(f'Model loaded from <== {save_path}')
return model, optimizer, scheduler`
Yet when I run this code:
facenet = FaceNet2(num_classes=8631)
optimizer = get_Optimizer(model=facenet) # optimizer
scheduler = get_Scheduler(optimizer,lr=5e-2) # scheduler
facenet, optimizer, scheduler = load('/content/drive/MyDrive/export/InceptionResNetV1_ArcFace.pt')
I got this instead:
ModuleNotFoundError Traceback (most recent call last)
[<ipython-input-35-887c94ca79c9>](https://localhost:8080/#) in <module>()
----> 1 facenet, optimizer, scheduler = load('/content/drive/MyDrive/export/InceptionResNetV1_ArcFace.pt')
3 frames
[<ipython-input-34-6acbab7e4d87>](https://localhost:8080/#) in load(save_path)
1 def load(save_path):
2 save_path = '/content/drive/MyDrive/export/InceptionResNetV1_ArcFace.pt'
----> 3 checkpoint = torch.load(save_path)
4 model = checkpoint['model']
5 optimizer = checkpoint['optimizer']
[/usr/local/lib/python3.7/dist-packages/torch/serialization.py](https://localhost:8080/#) in load(f, map_location, pickle_module, **pickle_load_args)
710 opened_file.seek(orig_position)
711 return torch.jit.load(opened_file)
--> 712 return _load(opened_zipfile, map_location, pickle_module, **pickle_load_args)
713 return _legacy_load(opened_file, map_location, pickle_module, **pickle_load_args)
714
[/usr/local/lib/python3.7/dist-packages/torch/serialization.py](https://localhost:8080/#) in _load(zip_file, map_location, pickle_module, pickle_file, **pickle_load_args)
1044 unpickler = UnpicklerWrapper(data_file, **pickle_load_args)
1045 unpickler.persistent_load = persistent_load
-> 1046 result = unpickler.load()
1047
1048 torch._utils._validate_loaded_sparse_tensors()
[/usr/local/lib/python3.7/dist-packages/torch/serialization.py](https://localhost:8080/#) in find_class(self, mod_name, name)
1037 pass
1038 mod_name = load_module_mapping.get(mod_name, mod_name)
-> 1039 return super().find_class(mod_name, name)
1040
1041 # Load the data (which may in turn use `persistent_load` to load tensors)
ModuleNotFoundError: No module named 'model'
Have I made a mistake? Is there any workaround or solution to solve this problem?
Can you run my code with python3 main2.py?
You have loaded the .pth model but there is no attribute name called model in the loaded class. Can you check all attributes variables after checkpoint = torch.load(save_path) and post it here? Then, I can figure out what problem is there.
Never mind, turns out I'm using the wrong model by mistake. It works now when I used the triplet model Thank you and sorry for disturbing
I'm trying to load the .pt model you provided, but I can't seem to make it work Code:
Output:
Can you please tell me what did I do wrong and how to fix it? I'm a beginner so I don't really know what to do here.