PyTorch人脸识别报错:ValueError: too many values to unpack (expected 3)
ValueError: too many values to unpack (expected 3) 使用Face-Transformer仓库的预训练模型对7个数据集进行评估,所有数据集存储在同一文件夹(含.bin和.npy文件),训练阶段运行正常,但评估时触发上述错误,多次尝试修复未解决。
相关代码
import torch import torch.nn as nn import sys from vit_pytorch import ViT_face from util.utils import get_val_data, perform_val, perform_val_deit, buffer_val, test_forward from IPython import embed import sklearn import cv2 import numpy as np from image_iter import FaceDataset import torch.utils.data as data import argparse import os DEVICE = torch.device("cuda:0") DATA_ROOT = '/home/cvpr/Documents/ms1m-retinaface-t1/' with open(os.path.join(DATA_ROOT, 'property'), 'r') as f: NUM_CLASS, h, w = [int(i) for i in f.read().split(',')] model = ViT_face( image_size=112, patch_size=8, loss_type='CosFace', GPU_ID=DEVICE, num_class=NUM_CLASS, dim=512, depth=20, heads=8, mlp_dim=2048, dropout=0.1, emb_dropout=0.1 ) model_root = '/home/cvpr/Documents/Backbone_VIT_Epoch_2_Batch_20000_Time_2021-01-12-16-48_checkpoint.pth' model.load_state_dict(torch.load(model_root)) TARGET = 'lfw' vers = get_val_data('/home/cvpr/Documents/OPVT/eval') print(vers) for ver in vers: name, data_set, issame = ver time = test_forward(DEVICE, model, data_set) print(time)
print(vers)输出
(carray((12000, 3, 112, 112), float32) nbytes := 1.68 GB; cbytes := 9.02 MB; ratio: 190.96 cparams := cparams(clevel=5, shuffle=1, cname='lz4', quantize=0) chunklen := 13; chunksize: 1956864; blocksize: 262144 rootdir := '/home/cvpr/Documents/OPVT/eval/lfw' mode := 'r' [[[[ 0.92941177 0.94509804 0.96862745 ..., -0.81960785 -0.7647059 -0.73333335]
报错回溯
Traceback (most recent call last): File "/home/cvpr/Documents/OPVT/test_forward.py", line 42, in <module> name, data_set, issame = ver ValueError: too many values to unpack (expected 3)
问题原因与解决方法
核心原因
get_val_data函数的返回值不符合预期:原仓库中该函数应返回包含多个元组的列表,每个元组格式为(数据集名称, 数据数组, issame数组)。但当前vers直接返回了单个carray对象,说明函数未正确加载多个数据集,导致循环时尝试将单个数据对象解包为3个变量,触发错误。
具体修复步骤
检查数据集路径
确认传入get_val_data的路径'/home/cvpr/Documents/OPVT/eval'是包含7个数据集文件夹的父目录,而非某个具体数据集(如lfw)的目录。若路径错误,函数只会加载单个数据集,返回结构不符合预期。验证
get_val_data返回结构
在代码中添加以下调试代码,确认返回值类型与结构:print(type(vers)) print(len(vers) if isinstance(vers, list) else "Not a list")正常情况下应输出
<class 'list'>和7,每个列表元素是包含3个元素的元组。对齐原仓库的
get_val_data实现
检查本地util/utils.py中的get_val_data函数,确保与Face-Transformer仓库的实现一致。原函数逻辑应为:遍历指定目录下的所有数据集文件夹,加载每个文件夹内的.bin和.npy文件,返回(name, data, issame)元组组成的列表。手动排查单个数据集加载
若上述步骤无效,可尝试单独加载一个数据集,确认函数是否能正确返回三元组:single_ver = get_val_data('/home/cvpr/Documents/OPVT/eval/lfw') print(type(single_ver), len(single_ver))若返回的是三元组而非列表,说明
get_val_data未处理多数据集目录的情况,需修改函数逻辑支持遍历目录下的所有数据集。
内容的提问来源于stack exchange,提问作者Khawar Islam

