Tensorflow / Keras多标签分类器

时间:2018-11-27 14:09:44

标签: python tensorflow keras

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

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

Corresponding label: [1, 0]

Corresponding label: [3, 0]

Corresponding label: [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)])

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

在遍历我的程序并玩弄之后,我找到了解决方案:一个多热编码数组。 在此数组中,如果我有一个圆形,正方形,星形和空白(因此有4个位置数组)的位置,则可以向模型标签中每个对应的空间中都带有'1'的位置进行输入。 例如。 (参考上面的示例):

  • [1、0、1、0]
  • [1、0、0、1]
  • [0,0,1,1]

这确实很好。