时隔两年没有更新任何东西了,如今重新开始更新,以后每天我都会在CSDN中总结分享自己在深度学习当中遇到的问题以及解决方案。今天要总结的是yolov5+facenet实现人脸识别当中遇到的问题。
yolov5在精度上领先yolov3,与yolov4差不多,但是在网络参数上yolov5相比yolov4可减少90%,yolov5的原理这个就不介绍了,github官方源码地址https://github.com/ultralytics/yolov5,接下来就来总结下我在学习yolov5当中遇到的问题:
问题1:torch.nn.modules.module.ModuleAttributeError: ‘Detect’ object has no attribute ‘m’
这个问题出现主要是因为模型不匹配造成的,这里建议使用作者代码内的链接进行下载,我一开始使用b站up主的链接下载因此出现该问题。
问题2: torch.nn.modules.module.ModuleAttributeError: ‘BatchNorm2d’ object has no attribute ‘_non_persistent_buffers_set’
这个问题仍然是模型不匹配问题,使用作者链接机进行下载可以完美避开这两问题。
问题3如下图:
出现这个问题是因为我的代码中含有test的一个函数,而与python中的默认执行的test函数冲突,所以出现上图所示错误,解决方案就是将含有test或test_的函数变一个名字即可。此处我将test函数更名为king_test就没再报错了。
我第一次接触人脸识别,一位学长建议我使用facenet来实现人脸特征提取保存,其优点如下:
因为这是总结型博客,所以原理我在这就不多讲了,github官方源码地址:https://github.com/davidsandberg/facenet 如果只是用来做人脸识别特征提取保存,那么仅需下载其中的facenet.py与预训练权重即可。因为预训练权重在外网,无法下载的小伙伴在评论区留下邮箱,接下来就说说我遇到的问题吧。
在提到下个问题前,这里先粗略解释下下载的模型与模型恢复代码:
// 在facenet中这是两种解冻恢复模型,提示使用绝对路径
//恢复pb模型的
//使用这个模型需要给出pb路径,例如:F:\20180402-114759\20180402-114759.pb
if (os.path.isfile(model_exp)):
print('Model filename: %s' % model_exp)
with gfile.FastGFile(model_exp,'rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
tf.import_graph_def(graph_def, input_map=input_map, name='')
//这是恢复meta与ckpt模型的
//使用这个路径无需定位到文件,例如:F:\20180402-114759\ ,即可
else:
print('Model directory: %s' % model_exp)
meta_file, ckpt_file = get_model_filenames(model_exp)
print('Metagraph file: %s' % meta_file)
print('Checkpoint file: %s' % ckpt_file)
saver = tf.train.import_meta_graph(os.path.join(model_exp, meta_file), input_map=input_map)
saver.restore(tf.get_default_session(), os.path.join(model_exp, ckpt_file))
接下来回到问题:
// 问题2
ValueError: Node 'gradients/InceptionResnetV1/Bottleneck/BatchNorm/cond/FusedBatchNorm_1_grad/FusedBatchNormGrad' has an _output_shapes attribute inconsistent with the GraphDef for output #3: Dimension 0 in both shapes must be equal, but are 0 and 512. Shapes are [0] and [512].
这个问题出现是因为我解冻恢复的是meta与ckpt模型,好像是参数节点不匹配,因为我也是第一次学习人脸识别算法,所以这个问题我也没解决,如果会的大佬看到了,麻烦在评论区解释下解决方案,非常感谢。我的解决方案是直接恢复pb模型。
到此就是我在yolov5与facenet当中遇到的问题了。接下来,我总结下其他小问题。
// 使用scipy.misc.imread
img = scipy.misc.imread(image_paths[i])
//报错
module 'scipy.misc' has no attribute 'imread'
//解决方案1
//出现上面错误是因为scipy版本太高了,可以降低版本
pip install scipy==1.2.1
//解决方案2
//因为现在python版本大多都过高,因此不能兼容scipy==1.2.1,所以可以换个方法
import imageio
content_image = imageio.imread()
在人脸识别后进一步实现身份识别时,大家会在显示身份这里出现问题,因为cv2.putText只能给图片添加英文。
接下来我们就来使用draw.text解决cv2.putText不能显示中文的问题,首选对比下二者的区别
// draw.text
draw.text((left, top), text, textColor, font=fontStyle);
//各参数依次是:左上角坐标,添加文字,文字颜色,文字样式
// cv2.putText
cv2.putText(img, str(i), (123,456)), font, 2, (0,255,0), 3) ;
//各参数依次是:图片,添加的文字,左上角坐标,字体,字体大小,颜色,字体粗细
解决方案:
// 使用draw.text解决cv2.putText不能显示中文
import cv2
import numpy
from PIL import Image, ImageDraw, ImageFont
def plot_one_box(x, img, color=None, label=None, line_thickness=None):
# Plots one bounding box on image img
tl = line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1 //line/font thickness
color = color or [random.randint(0, 255) for _ in range(3)]
c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))
cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
if label:
tf = max(tl - 1, 1) # font thickness
t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
//判断是否OpenCV图片类型
if (isinstance(img, np.ndarray)):
//转换为PIL格式
img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
//创建一个可以在给定图像上绘图的对象
draw = ImageDraw.Draw(img)
//设置样式
fontStyle = ImageFont.truetype("C:\Windows\Fonts\simsun.ttc", 20, encoding="utf-8")
//绘制文本
draw.text((c1[0]-10, c1[1] - 2-22), label, tuple(color), font=fontStyle)
//PIL转换为cv2格式
return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
// 方法调用
im0 = plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3)
//显示
cv2.imshow("",im0)
cv2.waitKey(5)