ChengguiS.
ChengguiS.

Reputation: 81

Typeerror: 1 positional argument but 2 were given, torch.nn.linear takes

I am using EfficientNet to extract features and trying to add a fully connected layer to pre-trained model to reduce the dimension of the out-features from efficientnet to 512. I encountered the following error when the features pass through the layer or the function that I defined.

"Typeerror: 1 positional argument but 2 were given"

Here are the code that I tried:

# define a function to reduce the dimension to 512
# def block_dim_red():
#     block_dim_red = Sequential(OrderedDict([
#         ('fc', Linear(1280, 512)),
#     ]))
#     return block_dim_red

def fc():
    fc = Linear(in_features = 1280, out_feaures = 512)
    return fc

The following codes show how I defined the Class BaseModel(object).

Thank you very much in advance.

class BaseModel(object):

def __init__(self):
    self.image_size = 224
    self.dimision = 1280
    self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    self.load_model()

def load_model(self):
    self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    self.model = EfficientNet.from_pretrained('efficientnet-b0').to(self.device)

    self.model = self.model.eval()
    self.PIXEL_MEANS = torch.tensor((0.485, 0.456, 0.406)).to(self.device)
    self.PIXEL_STDS = torch.tensor((0.229, 0.224, 0.225)).to(self.device)
    self.num = torch.tensor(255.0).to(self.device)

def preprocess_input(self, image):
    image = cv2.resize(image, (self.image_size, self.image_size))
    # gpu version
    image_tensor = torch.from_numpy(image.copy()).to(self.device).float()
    image_tensor /= self.num
    image_tensor -= self.PIXEL_MEANS
    image_tensor /= self.PIXEL_STDS
    image_tensor = image_tensor.permute(2, 0, 1)
    return image_tensor

# define a function to reduce the dimension to 512
# def block_dim_red():
#     block_dim_red = Sequential(OrderedDict([
#         ('fc', Linear(1280, 512)),
#     ]))
#     return block_dim_red

def fc():
    fc = Linear(in_features = 1280, out_feaures = 512)
    return fc

def forward(self, x):
    x = self.preprocess_input(x).unsqueeze(0)
    # extraccted feature shape torch.Size([1, 1280, 7, 7])
    x = self.model.extract_features(x)
    x = F.max_pool2d(x, kernel_size=(7, 7))
    x = x.view(x.size(0),-1)
    x = torch.reshape(x,(-1,1))
    x = self.fc(x) # fully connecte layer to reduce dimension

    return self.torch2list(x)


def torch2list(self, torch_data):
    return torch_data.cpu().detach().numpy().tolist()

def load_model(): return BaseModel()

Upvotes: 1

Views: 3389

Answers (2)

Erling Olsen
Erling Olsen

Reputation: 740

There was a self.fc() problem in your def forward function

def __init__(self):
    self.image_size = 224
    self.dimision = 1280
    self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    self.load_model()

def load_model(self):
    self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    self.model = EfficientNet.from_pretrained('efficientnet-b0').to(self.device)

    self.model = self.model.eval()
    self.PIXEL_MEANS = torch.tensor((0.485, 0.456, 0.406)).to(self.device)
    self.PIXEL_STDS = torch.tensor((0.229, 0.224, 0.225)).to(self.device)
    self.num = torch.tensor(255.0).to(self.device)

def preprocess_input(self, image):
    image = cv2.resize(image, (self.image_size, self.image_size))
    # gpu version
    image_tensor = torch.from_numpy(image.copy()).to(self.device).float()
    image_tensor /= self.num
    image_tensor -= self.PIXEL_MEANS
    image_tensor /= self.PIXEL_STDS
    image_tensor = image_tensor.permute(2, 0, 1)
    return image_tensor

# define a function to reduce the dimension to 512
# def block_dim_red():
#     block_dim_red = Sequential(OrderedDict([
#         ('fc', Linear(1280, 512)),
#     ]))
#     return block_dim_red

def fc():
    fc = Linear(in_features = 1280, out_feaures = 512)
    return fc

def forward(self, x):
    x = self.preprocess_input(x).unsqueeze(0)
    # extraccted feature shape torch.Size([1, 1280, 7, 7])
    x = self.model.extract_features(x)
    x = F.max_pool2d(x, kernel_size=(7, 7))
    x = x.view(x.size(0),-1)
    x = torch.reshape(x,(-1,1))
    self.fc()(x)

    return self.torch2list(x)


def torch2list(self, torch_data):
    return torch_data.cpu().detach().numpy().tolist()

def load_model(): 
    return BaseModel()

Upvotes: 0

Vaibhav G.
Vaibhav G.

Reputation: 169

Try replacing x = self.fc(x) with self.fc()(x) since self.fc() is a function that expects no arguments and returns the Linear layer which in turn expects the argument.

Although a better way would be to add self.fc = Linear(in_features = 1280, out_feaures = 512) inside the __init__ and use x=self.fc(x) as you have done.

Upvotes: 1

Related Questions