【发布时间】: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