【问题标题】:TypeError: 'NoneType' object is not callable (pytorch- finetuning model resnet 50 to build pipeline face-recognition)TypeError: 'NoneType' object is not callable (pytorch-finetuning model resnet 50 to build pipeline face-recognition)
【发布时间】:2021-12-29 18:55:50
【问题描述】:

我正在尝试构建使用 pytorch 的管道人脸识别。我想用 arcface 构建retina-face。但是升级步骤导致错误。我不知道为什么它不运行。 请帮帮我! 为什么我会收到此错误?我很困惑。

你需要知道什么来回答我的问题?


import pandas as pd
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import torch.functional as F
from torchvision import models, transforms
from torchvision import transforms as T
import torchvision
from torchvision import datasets,models, transforms
from torch.utils.data import Dataset, SubsetRandomSampler, DataLoader
import os
from torchvision.datasets import ImageFolder
from torchvision.transforms import ToTensor
import copy
from collections import namedtuple, Counter
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error
from torch.optim import lr_scheduler
import time
from torchvision.io import read_image
import os
from typing import Any, Callable, List, Optional, Tuple
from PIL import Image
from torchvision.datasets.utils import check_integrity, download_and_extract_archive, download_url, verify_str_arg
from torchvision.datasets.vision import VisionDataset

class LFWDataset(datasets.ImageFolder):
    def __init__(self, dir, pairs_path, transform=None):

        super(LFWDataset, self).__init__(dir, transform)

        self.pairs_path = pairs_path

        # LFW dir contains 2 folders: faces and lists
        self.validation_images = self.get_lfw_paths(dir)

    def read_lfw_pairs(self, pairs_filename):
        pairs = []
        with open(pairs_filename, 'r') as f:
            for line in f.readlines()[1:]:
                pair = line.strip().split()
                pairs.append(pair)

        return np.array(pairs, dtype=object)

    def get_lfw_paths(self, lfw_dir):
        pairs = self.read_lfw_pairs(self.pairs_path)

        nrof_skipped_pairs = 0
        path_list = []
        issame_list = []
        for pair in pairs:
            if len(pair) == 3:
                path0 = self.add_extension(os.path.join(lfw_dir, pair[0], pair[0] + '_' + '%04d' % int(pair[1])))
                path1 = self.add_extension(os.path.join(lfw_dir, pair[0], pair[0] + '_' + '%04d' % int(pair[2])))
                issame = True
            elif len(pair) == 4:
                path0 = self.add_extension(os.path.join(lfw_dir, pair[0], pair[0] + '_' + '%04d' % int(pair[1])))
                path1 = self.add_extension(os.path.join(lfw_dir, pair[2], pair[2] + '_' + '%04d' % int(pair[3])))
                issame = False
            if os.path.exists(path0) and os.path.exists(path1):  # Only add the pair if both paths exist
                path_list.append((path0, path1, issame))
                issame_list.append(issame)
            else:
                nrof_skipped_pairs += 1
        if nrof_skipped_pairs > 0:
            print('Skipped %d image pairs' % nrof_skipped_pairs)

        return path_list

    def add_extension(self, path):
        if os.path.exists(path + '.jpg'):
            return path + '.jpg'
        elif os.path.exists(path + '.png'):
            return path + '.png'
        else:
            raise RuntimeError('No file "%s" with extension png or jpg.' % path)

    def __getitem__(self, index):
        """
        Args:
            index: Index of the triplet or the matches - not of a single image
        Returns:
        """

        def transform(img_path):
            img = self.loader(img_path)
            return self.transform(img)

        (path_1, path_2, issame) = self.validation_images[index]
        img1, img2 = transform(path_1), transform(path_2)
        return img1, img2, issame

    def __len__(self):
        return len(self.validation_images)

training_data = LFWDataset('/content/gdrive/MyDrive/FaceRecognition/LFW/lfw_funneled',"/content/gdrive/MyDrive/FaceRecognition/LFW/pairsDevTrain.txt")
test_data = LFWDataset('/content/gdrive/MyDrive/FaceRecognition/LFW/lfw_funneled','/content/gdrive/MyDrive/FaceRecognition/LFW/pairsDevTest.txt')

train_dataloader = DataLoader(training_data, batch_size=64, shuffle=True)
test_dataloader = DataLoader(test_data, batch_size=64, shuffle=True)

def Deconv(n_input, n_output, k_size=4, stride=2, padding=1):
    Tconv = nn.ConvTranspose2d(
        n_input, n_output,
        kernel_size=k_size,
        stride=stride, padding=padding,
        bias=False)
    block = [
        Tconv,
        nn.BatchNorm2d(n_output),
        nn.LeakyReLU(inplace=True),
    ]
    return nn.Sequential(*block)
        

def Conv(n_input, n_output, k_size=4, stride=2, padding=0, bn=False, dropout=0):
    conv = nn.Conv2d(
        n_input, n_output,
        kernel_size=k_size,
        stride=stride,
        padding=padding, bias=False)
    block = [
        conv,
        nn.BatchNorm2d(n_output),
        nn.LeakyReLU(0.2, inplace=True),
        nn.Dropout(dropout)
    ]
    return nn.Sequential(*block)


class Unet(nn.Module):
    def __init__(self, resnet):
        super().__init__()
        
        self.conv1 = resnet.conv1
        self.bn1 = resnet.bn1
        self.relu = resnet.relu
        self.maxpool = resnet.maxpool
        self.tanh = nn.Tanh()
        self.sigmoid = nn.Sigmoid()
        
        # get some layer from resnet to make skip connection
        self.layer1 = resnet.layer1
        self.layer2 = resnet.layer2
        self.layer3 = resnet.layer3
        self.layer4 = resnet.layer4
        
        # convolution layer, use to reduce the number of channel => reduce weight number
        self.conv_5 = Conv(2048, 512, 1, 1, 0)
        self.conv_4 = Conv(1536, 512, 1, 1, 0)
        self.conv_3 = Conv(768, 256, 1, 1, 0)
        self.conv_2 = Conv(384, 128, 1, 1, 0)
        self.conv_1 = Conv(128, 64, 1, 1, 0)
        self.conv_0 = Conv(32, 1, 3, 1, 1)
        
        # deconvolution layer
        self.deconv4 = Deconv(512, 512, 4, 2, 1)
        self.deconv3 = Deconv(512, 256, 4, 2, 1)
        self.deconv2 = Deconv(256, 128, 4, 2, 1)
        self.deconv1 = Deconv(128, 64, 4, 2, 1)
        self.deconv0 = Deconv(64, 32, 4, 2, 1)
        
        
    def forward(self, x):
        x = self.conv1(x)
        x = self.bn1(x)
        x = self.relu(x)
        skip_1 = x
        
        x = self.maxpool(x)
        x = self.layer1(x)
        skip_2 = x

        x = self.layer2(x)
        skip_3 = x
        x = self.layer3(x)
        skip_4 = x
        
        x5 = self.layer4(x)
        x5 = self.conv_5(x5)
        
        x4 = self.deconv4(x5)
        x4 = torch.cat([x4, skip_4], dim=1)
        x4 = self.conv_4(x4)
        
        x3 = self.deconv3(x4)
        x3 = torch.cat([x3, skip_3], dim=1)
        x3 = self.conv_3(x3)
        
        x2 = self.deconv2(x3)
        x2 = torch.cat([x2, skip_2], dim=1)
        x2 = self.conv_2(x2)
        
        x1 = self.deconv1(x2)
        x1 = torch.cat([x1, skip_1], dim=1)
        x1 = self.conv_1(x1)
        
        x0 = self.deconv0(x1)
        x0 = self.conv_0(x0)
        
        x0 = self.sigmoid(x0)
        return x0
        
device = torch.device("cuda")
resnet50 = models.resnet50(pretrained=True)

model = Unet(resnet50)
model.to(device)

## Freeze resnet50's layers in Unet
for i, child in enumerate(model.children()):
    if i <= 7:
        for param in child.parameters():
            param.requires_grad = False


train_params = [param for param in model.parameters() if param.requires_grad]
optimizer = torch.optim.Adam(train_params, lr=0.001, betas=(0.9, 0.99))

epochs = 5
model.train()
saved_dir = "model"
os.makedirs(saved_dir, exist_ok=True)
loss_function = nn.MSELoss(reduce="mean")

for epoch in range(epochs):
    for img, issame in tqdm(train_dataloader):
        img_gpu = img.to(device)
        outputs = model(img_gpu)
        issame = issame.to(device)
        loss = loss_function(outputs, issame)
        loss.backward()
        optimizer.step()

这是错误:

/usr/local/lib/python3.7/dist-packages/torch/nn/_reduction.py:42: UserWarning: size_average and reduce args will be deprecated, please use reduction='mean' instead.
  warnings.warn(warning.format(ret))
  0%|          | 0/35 [00:00<?, ?it/s]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-18-68b23124b0a0> in <module>()
      9 
     10 for epoch in range(epochs):
---> 11     for img, issame in tqdm(train_dataloader):
     12         img_gpu = img.to(device)
     13         outputs = model(img_gpu)

6 frames
<ipython-input-4-5d1f05768026> in transform(img_path)
     65 
     66             img = self.loader(img_path)
---> 67             return self.transform(img)
     68 
     69         (path_1, path_2, issame) = self.validation_images[index]

TypeError: 'NoneType' object is not callable

【问题讨论】:

  • 你确定img_path第66行是正确的
  • @FerasAlfrih 这与仅供参考的错误无关。
  • @FerasAlfrih 错误说 'NoneType' 对象不可调用,这是在LFWDataset__getitem__ 中引发的,这意味着该图像已经以某种方式加载并且self.transform,这是None,如上所述,是通过尝试被调用而导致问题。
  • 问题出现在self.transform( 部分,甚至在到达img) 部分之前。
  • @Neither 感谢您的反馈。

标签: python pytorch computer-vision artificial-intelligence face-recognition


【解决方案1】:

您正在定义返回调用自身结果的函数 transform()。 Python 不喜欢无休止的递归......我想它应该简单地返回“img”:

def transform(img_path):
   img = self.loader(img_path)
   return img

【讨论】:

  • 我这样做了,但它还有另一个错误:
  • TypeError: default_collate: batch must contain tensors, numpy arrays, numbers, dicts or lists; found &lt;class 'PIL.Image.Image'&gt;
  • 请在您的代码中显示:在哪里?
猜你喜欢
  • 2020-03-09
  • 1970-01-01
  • 1970-01-01
  • 2021-01-18
  • 2022-12-26
  • 2019-06-25
  • 1970-01-01
  • 2018-03-31
  • 2021-10-22
相关资源
最近更新 更多