【问题标题】:Training only one output of a network in Keras在 Keras 中只训练一个网络的输出
【发布时间】:2017-03-19 16:38:17
【问题描述】:

我在 Keras 中有一个包含许多输出的网络,但是,我的训练数据一次只提供一个输出的信息。

目前我的训练方法是对有问题的输入进行预测,更改我正在训练的特定输出的值,然后进行单批更新。如果我是对的,这与将所有输出的损失设置为零相同,但我正在尝试训练的输出除外。

有没有更好的方法?我尝试了类权重,除了我正在训练的输出之外,我将所有的权重设置为零,但它没有给我预期的结果?

我正在使用 Theano 后端。

【问题讨论】:

  • 对于监督学习来说,这是一个不常见的设置。展示一些示例数据并解释一下为什么你得到这个设置。
  • 我将它用于深度 Q 学习。输入是一个状态,每个输出是一个动作的分数。您选择一个动作,然后根据该动作的结果更新网络。但是,您只想更新一个输出,因为您不知道其他操作的结果...
  • 我明白了。这是不同的处理方式。查看these sources(我在链接中标记了这一行)。您只需保留其他操作的当前值!
  • 我想实现一个类似的具有多个输出的 CNN(多任务学习)。我将在输入(图像)上运行网络,得到一个输出;然后根据输出,选择其他输出之一来运行网络并获得最终输出。在训练中,我一次只更新一个流。我认为这是一个非常常见的问题,但奇怪的是,没有示例或文档来描述解决方案。 @simeon:您设法解决了您的问题吗?如果是这样,怎么做?谢谢。
  • 前几天我确实做过,但忘记了这篇文章。今晚我会做出更详细的回应,但是,在 Keras 中,您可以使用共享值的相同层制作多个模型(在我的脑海中,您需要使用“序列”的替代方案)。我基本上为每个共享层的输出制作了一个模型。效果很好。

标签: keras neural-network theano reinforcement-learning q-learning


【解决方案1】:

输出多个结果并仅优化其中一个

假设您想从多个层返回输出,可能来自一些中间层,但您只需要优化一个目标输出。你可以这样做:

让我们从这个模型开始:

inputs = Input(shape=(784,))
x = Dense(64, activation='relu')(inputs)

# you want to extract these values
useful_info = Dense(32, activation='relu', name='useful_info')(x)

# final output. used for loss calculation and optimization
result = Dense(1, activation='softmax', name='result')(useful_info)

使用多个输出编译,将损失设置为None 用于额外输出:

为您不想用于损失计算和优化的输出提供None

model = Model(inputs=inputs, outputs=[result, useful_info])
model.compile(optimizer='rmsprop',
              loss=['categorical_crossentropy', None],
              metrics=['accuracy'])

训练时只提供target输出。跳过额外的个输出:

model.fit(my_inputs, {'result': train_labels}, epochs=.., batch_size=...)

# this also works:
#model.fit(my_inputs, [train_labels], epochs=.., batch_size=...)

一个预测可以全部搞定

拥有一个模型,您只需运行一次 predict 即可获得所需的所有输出:

predicted_labels, useful_info = model.predict(new_x)

【讨论】:

  • 不知何故这在 v2.3.0 中不起作用,因为我收到了错误:ValueError: The two structures don't have the same sequence length. Input structure has length 1, while shallow structure has length 3.
  • 尝试将其应用于我的网络时出现以下错误:“ValueError: Variable has @ 987654329@ 用于渐变。请确保您的所有操作都定义了渐变(即可微分)。没有渐变的常见操作:K.argmax、K.round、K.eval。我的张量流==1.14.0.我的损失是 [None,''categorical_crossentropy"]
  • @omsrisagar 是的,我也是!你能找到解决办法吗?
【解决方案2】:

为了实现这一点,我最终使用了“功能 API”。您基本上可以创建多个模型,使用相同的输入层和隐藏层,但输出层不同。

例如:

https://keras.io/getting-started/functional-api-guide/

from keras.layers import Input, Dense
from keras.models import Model

# This returns a tensor
inputs = Input(shape=(784,))

# a layer instance is callable on a tensor, and returns a tensor
x = Dense(64, activation='relu')(inputs)
x = Dense(64, activation='relu')(x)
predictions_A = Dense(1, activation='softmax')(x)
predictions_B = Dense(1, activation='softmax')(x)

# This creates a model that includes
# the Input layer and three Dense layers
modelA = Model(inputs=inputs, outputs=predictions_A)
modelA.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
modelB = Model(inputs=inputs, outputs=predictions_B)
modelB.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

【讨论】:

  • 这里的问题是 - 你必须运行预测两次才能获得两个输出。
  • @Serhiy 他可以创建第三个predictions = Concatenate()([predictions_A, predictions_B]) 并将其设置为第三个模型的输出。
猜你喜欢
  • 2020-04-16
  • 1970-01-01
  • 1970-01-01
  • 2019-07-05
  • 2021-07-30
  • 2017-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多