我一直在使用Keras模型和cv2
人脸检测脚本来进行人脸识别。最近我遇到一个问题,每当模型进行预测时,它总是输出0。这尤其奇怪,因为0并不在标签数组中。顺便说一下,我有一个名为opencvtrainer
的目录,其中包含三个子目录,每个子目录都包含人们面部的图像。以下是代码:
import PIL as PILimport tensorflow as tfimport numpy as npimport cv2 as cv2import os# 进入opencvtrainer目录basedir = os.path.dirname(os.path.abspath(__file__))imagedir = os.path.join(basedir, "opencvtrainer")ylabels = []# 如果目录是某人:idlabelids = { "john_": 001, "erin_": 002, "scott_": 003, "colin_": 004}''' "glenn_": 004, "faith_": 005,'''xtrain = []xl = []# 创建通用人脸分类器# 创建需要训练的AI# 遍历opencvtrainer目录中的文件fc = cv2.CascadeClassifier("lib/python2.7/site-package\s/cv2/data/haarcascade_frontalface_alt2.xml")for root, dirs, files in os.walk(imagedir): for file in files: if "png" in file: # 文件路径 path = os.path.join(root, file) # 所属文件的人 label = os.path.basename(root) # 获取图像 imagep = PIL.Image.open(path) # 将图像转换为灰度然后转为numpy数组 imagear = np.array(imagep.convert("L"), "uint8") imagearre = imagear face = fc.detectMultiScale(imagearre) for (x, y, w, h) in face: # 为人脸创建ROI roi = imagearre[y:y + h, x:x + w] roi = cv2.resize(roi, (70, 70)) # 将numpy数组添加到xtrain xtrain.append(roi) print(roi.shape) # 为所有打开的文件分配一个数字到ylabels xl.append(labelids[label])xtrain = np.array(xtrain)ylabels = np.array(xl)# 添加来自Keras的AImodel = tf.keras.models.Sequential()# 定义输入应是什么并处理当前输入model.add(tf.keras.layers.Flatten(input_shape=(70, 70)))# 添加层model.add(tf.keras.layers.Dense(128, activation=tf.nn.relu))# 添加层model.add(tf.keras.layers.Dense(128, activation=tf.nn.relu))# 添加层model.add(tf.keras.layers.Dense(1, activation=tf.nn.softmax))# 测试准确性model.compile(optimizer="adam", loss="binary_crossentropy", metrics= . ['accuracy'])print(ylabels)model.fit(xtrain, ylabels, epochs=3)model.save("test11")'
回答:
1) 将最后一层的单元数更改为4(因为你有4个不同的类别):
tf.keras.layers.Dense(4, activation=tf.nn.softmax)
2) 从零开始编号标签,而不是从一:
labelids = {"john_": 0, "erin_": 1, "scott_": 2, "colin_": 3}
3) 使用sparse_categorical_crossentropy
作为损失函数。或者,你可以对标签进行独热编码,然后使用categorical_crossentropy
作为损失函数。