【问题标题】:Tensorflow/Keras multi-label classifierTensorFlow/Keras 多标签分类器
【发布时间】:2018-12-26 16:59:34
【问题描述】:

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

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

这些图像应该具有作为对应标签的三个数组:[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)])

【问题讨论】:

    标签: python tensorflow keras


    【解决方案1】:

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

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

    【讨论】:

    • 如果我没有说清楚的话,图像一次只给出一个,一次只给出一个二维标签作为输出。所以我只有 2^4 个不同的输出,根据你的建议,我会映射。虽然我想要一个数组作为输出,因为如果我增加提供给它的不同图像的数量(然后组合在一起),我不想重新映射所有内容。
    【解决方案2】:

    在谷歌搜索并玩弄我的程序后,我找到了解决方案:多热编码数组。 在这个数组中,如果我有一个圆形、一个正方形、一个星形和一个空白空间(因此是一个 4 位置数组)的位置,我可以提供给我的模型标签,在每个相应的空间中都有一个“1”。 例如。 (参考上面的例子):

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

    这确实工作得很好。

    【讨论】:

      猜你喜欢
      • 2017-01-08
      • 2019-05-21
      • 1970-01-01
      • 2018-08-04
      • 2019-02-26
      • 2019-01-06
      • 2018-07-02
      • 2018-06-11
      • 2017-12-30
      相关资源
      最近更新 更多