首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Keras:具有一个输入和两个输出的模型,在不同的数据上联合训练(半监督学习)

Keras:具有一个输入和两个输出的模型,在不同的数据上联合训练(半监督学习)
EN

Stack Overflow用户
提问于 2017-06-01 06:16:20
回答 2查看 1.3K关注 0票数 1

我想用Keras编码,这是一个神经网络,既是一个自动编码器,也是一个半监督学习的分类器。以这个数据集为例,其中有几个标记的图像和许多未标记的图像:https://cs.stanford.edu/~acoates/stl10/

一些论文列出了here成功地实现了这一点,或者非常类似的事情。

总而言之:如果模型具有相同的输入数据形状和相同的“编码”卷积层,但会分成两个头(分叉式),那么就有一个分类头和一个解码头,在某种程度上,无监督自动编码器将有助于分类头的良好学习。

有了TensorFlow,这样做是没有问题的,因为我们可以完全控制计算图。

但在Keras中,事情是更高层次的,我觉得所有对".fit“的调用都必须一次提供所有数据(所以它会迫使我将分类头和自动编码头绑定到一个时间步中)。

在keras中,一种几乎可以做到这一点的方法是这样的:

代码语言:javascript
复制
input = Input(shape=(32, 32, 3))
cnn_feature_map = sequential_cnn_trunk(input)

classification_predictions = Dense(10, activation='sigmoid')(cnn_feature_map)

autoencoded_predictions = decode_cnn_head_sequential(cnn_feature_map)

model = Model(inputs=[input], outputs=[classification_predictions, ])

model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])
model.fit([images], [labels, images], epochs=10)

然而,我认为,我担心,如果我只是想以这种方式拟合事物,它将失败,并要求丢失的头部:

代码语言:javascript
复制
for epoch in range(10):
    # classifications step
    model.fit([images], [labels, None], epochs=1)
    # "semi-unsupervised" autoencoding step
    model.fit([images], [None, images], epochs=1)
    # note: ".train_on_batch" could probably be used rather than ".fit" to avoid doing a whole epoch each time.

应该如何使用Keras实现该行为?是否可以在不拆分对".fit“函数的两个调用的情况下共同完成训练?

EN

回答 2

Stack Overflow用户

发布于 2017-10-11 17:18:16

有时,当你没有标签时,你可以传递零向量,而不是一个热编码的向量。它不应该改变你的结果,因为零向量没有任何具有分类交叉熵损失的错误信号。

我的自定义to_categorical函数如下所示:

代码语言:javascript
复制
def tricky_to_categorical(y, translator_dict):
    encoded = np.zeros((y.shape[0], len(translator_dict)))
    for i in range(y.shape[0]):
        if y[i] in translator_dict:
            encoded[i][translator_dict[y[i]]] = 1
    return encoded

当y包含标签时,translator_dict是包含标签及其唯一键的python字典,如下所示:

{'unisex':2, 'female': 1, 'male': 0}

如果在这个指令中找不到UNK标签,那么它的编码标签将是一个零向量

如果你使用这个技巧,你还必须修改你的精度函数来查看真实的精度数字。你必须从我们的指标中过滤掉所有的零向量

代码语言:javascript
复制
def tricky_accuracy(y_true, y_pred):
    mask = K.not_equal(K.sum(y_true, axis=-1), K.constant(0))  # zero vector mask
    y_true = tf.boolean_mask(y_true, mask)
    y_pred = tf.boolean_mask(y_pred, mask)
    return K.cast(K.equal(K.argmax(y_true, axis=-1), K.argmax(y_pred, axis=-1)), K.floatx())

注意:为了防止零矩阵更新,你必须使用更大的批次(例如32),因为这会让你的精度指标变得疯狂,我不知道为什么

替代解决方案

使用伪标签:)

票数 1
EN

Stack Overflow用户

发布于 2017-09-20 21:44:33

你可以联合训练,你必须传递一个单一标签的数组实例。

我用的是fit_generator,例如

代码语言:javascript
复制
model.fit_generator(
batch_generator(),
steps_per_epoch=len(dataset) / batch_size,
epochs=epochs)


def batch_generator():
batch_x = np.empty((batch_size, img_height, img_width, 3))
gender_label_batch = np.empty((batch_size, len(gender_dict)))
category_label_batch = np.empty((batch_size, len(category_dict)))
while True:
    i = 0
    for idx in np.random.choice(len(dataset), batch_size):
        image_id = dataset[idx][0]
        batch_x[i] = load_and_convert_image(image_id)
        gender_label_batch[i] = gender_labels[idx]
        category_label_batch[i] = category_labels[idx]

        i += 1
    yield batch_x, [gender_label_batch, category_label_batch]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44295518

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档