首页 > 解决方案 > TensorFlow/Keras 多标签分类器

问题描述

我刚刚开始在 Tenosrflow 中开发一些简单的分类器,并开始在 Tensorflow 网站上使用这个示例:https ://www.tensorflow.org/tutorials/keras/basic_classification

现在我希望我的模型获得这样的图像作为特征:

对应标签:[1, 0]

对应标签:[3, 0]

对应标签:[1, 3]

这些图像应具有作为相应标签的三个数组:[1,0]、[3,0] 和 [1,3]。我的问题是:如何将这些标签(即标签是数组而不是单个标量)加载到模型中?当我在下面的示例中尝试时,我得到的唯一一件事是一条错误消息,我不会在这里报告,因为它们是由于我对我正在尝试做的事情缺乏了解而产生的。

附加问题:最后一个神经层应该如何?它应该有多少个神经元?

这是代码:

import tensorflow as tf
from tensorflow import keras
import skimage
from skimage.color import rgb2gray
import csv
import numpy as np

names = ['Cerchio', 'Quadrato', 'Stella']

images = []
labels = [[]]

test_images = []
test_labels = [[]]
final_images = []

for i in range(1, 501):
    images.append(skimage.data.imread("{0}.bmp".format(i)))
for i in range(501, 601):
    test_images.append(skimage.data.imread("{0}.bmp".format(i)))

for i in range(601, 701):
    final_images.append(skimage.data.imread("{0}.bmp".format(i)))

file = open("labels.csv", "rU")

reader = csv.reader(file, delimiter=",")


for row in reader:
    for i in range(0, 499):
        if int(row[i]) < 10:
            labels.append([int(int(row[i])/10), 0])
        else:
            labels.append([int(int(row[i])/10), int(row[i])%10])
    for i in range(500, 600):
        if int(row[i]) < 10:
            test_labels.append([int(int(row[i])/10), 0])
        else:
            test_labels.append([int(int(row[i])/10), int(row[i])%10])


file.close()

images28 = np.array(images)
images28 = rgb2gray(images28)
test_images28 = np.array(test_images)
test_images28 = rgb2gray(test_images28)
final_images28 = np.array(final_images)
final_images28 = rgb2gray(final_images28)

labels = np.array(labels)
test_labels = np.array(test_labels)
print(labels)

model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 56)),
    keras.layers.Dense(128, activation=tf.nn.relu),
    keras.layers.Dense(4, activation=tf.nn.softmax)
])

model.compile(optimizer=tf.train.AdamOptimizer(), 
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(images28, labels, epochs=5)

test_loss, test_acc = model.evaluate(test_images28, test_labels)

print('Test accuracy:', test_acc)
a = input()
img = final_images28[int(a)]

print(img.shape)

img = (np.expand_dims(img, 0))
print(img.shape)

predictions_single = model.predict(img)
print(predictions_single)
print(names[np.argmax(predictions_single)])

标签: pythontensorflowkeras

解决方案


一种方法是将数组标签映射到索引中,例如 [[0,0],[0,0],[0,0]]->0, [[1,0],[0,0],[ 0,0]]->1,... 等等。您将有 3^6=729 个可能的标签。如果图像上的这些形式是标准的,您可能可以使用没有隐藏层的最简单的分类器,因此它将是 dim1xdim2x729 可训练的权重。如果它们不是标准的,那么最好使用卷积层。

对于这个问题,您可能还可以使用完全卷积模型,该模型将 3 维张量作为输出返回。在这种情况下,您可以使用多维标签。但是你必须为它编写自定义损失函数。


推荐阅读