我一直在尝试使用python 3.6学习Tensorflow,并决定使用来自埃塞克斯大学的面部数据库(http://cswww.essex.ac.uk/mv/allfaces/index.html)的数据构建面部识别程序。到目前为止,我一直在关注Tensorflow的MNIST专家指南,但是当我开始测试时,我的每个时期的准确度为0,所以我知道出了问题。我对如何处理标签感到非常不稳定,所以我认为这就是问题所在。
数据集中的标签是数字ID,如987323,或某人的名称,如“fordj”。我想解决这个问题的方法是创建一个“预编码” encode_labels 函数,该函数为测试和训练中的每个唯一标签设置它们自己唯一的整数值。我检查确保测试和火车组中的每个唯一标签具有相同的唯一值。它还返回一个字典,以便我可以轻松地从编码版本映射回原始标签。如果我不执行此步骤并在检索标签时传递标签(即“fordj”),则会收到错误消息
UnimplementedError(参见上面的回溯):不支持将字符串转换为int32 [[Node:Cast = CastDstT = DT_INT32,SrcT = DT_STRING,_device =“/ job:localhost / replica:0 / task:0 / device:CPU:0”]]
我解释这一点的方式是,由于许多标签都是人名,因此tensorflow无法将像“fordj”这样的标签转换为tf.int32。抓取标签和路径的代码在这里:
def get_paths_and_labels(path):
""" image_paths : list of relative image paths
labels : mix of alphanumeric characters """
image_paths = [path + image for image in os.listdir(path)]
labels = [i.split(".")[-3] for i in image_paths]
labels = [i.split("/")[-1] for i in labels]
return image_paths, labels
def encode_labels(train_labels, test_labels):
""" Assigns a numeric value to each label since some are subject's names """
found_labels = []
index = 0
mapping = {}
for i in train_labels:
if i in found_labels:
continue
mapping[i] = index
index += 1
found_labels.append(i)
return [mapping[i] for i in train_labels], [mapping[i] for i in test_labels], mapping
以下是我分配培训和测试标签的方法。然后,我想使用tensorflow的one-hot编码器为我再次编码。
def main():
# Grabs the labels and each image's relative path
train_image_paths, train_labels = get_paths_and_labels(TRAIN_PATH)
# Smallish dataset so I can read it all into memory
train_images = [cv2.imread(image) for image in train_image_paths]
test_image_paths, test_labels = get_paths_and_labels(TEST_PATH)
test_images = [cv2.imread(image) for image in test_image_paths]
num_classes = len(set(train_labels))
# Placeholders
x = tf.placeholder(tf.float32, shape=[None, IMAGE_SIZE[0] * IMAGE_SIZE[1]])
y_ = tf.placeholder(tf.float32, shape=[None, num_classes])
x_image = tf.reshape(x, [-1, IMAGE_SIZE[0], IMAGE_SIZE[1], 1])
# One-hot labels
train_labels, test_labels, mapping = encode_labels(train_labels, test_labels)
train_labels = tf.one_hot(indices=tf.cast(train_labels, tf.int32), depth=num_classes)
test_labels = tf.one_hot(indices=tf.cast(test_labels, tf.int32), depth=num_classes)
我确定我做错了什么。我知道sklearn有一个LabelEncoder,虽然我还没有尝试过。感谢您对此提出任何建议,感谢所有帮助!
答案 0 :(得分:1)
我解释这一点的方式是,由于许多标签都是人的名字,因此张量流不能转换标签,例如" fordj"到了tf.int32。
你是对的。 Tensorflow无法做到这一点。相反,您可以创建从nome到唯一(和渐进)ID的映射功能。完成后,您可以使用其一个热表示正确地对每个数字ID进行一次编码。 您已经拥有数字ID和字符串标签之间的关系,因此您可以执行以下操作:
train_labels, test_labels, mapping = encode_labels(train_labels, test_labels)
numeric_train_ids = [labels[idx] for idx in train_labels]
numeric_test_ids = [labels[idx] for idx in test_labels]
one_hot_train_labels = tf.one_hot(indices=numeric_train_ids, depth=num_classes)
one_hot_test_labels = tf.one_hot(indices=numeric_test_ids, depth=num_classes)