首页 > 解决方案 > 如何仅将样本拟合到多个输出中的一些 Keras 功能 API

问题描述

我目前遇到的问题是试图拟合具有 10 个输出和一个输入的功能性 keras 模型,其中每个样本都有分配给输出的样本。

每个样本都有一个包含 10 个布尔值的列表,这些布尔值指示应该在哪些输出上拟合该样本。

我当前的模型如下所示:

        inputs = Input(shape=(self.state_count,))
        # create the layers that learn the gane
        d1 = Dense(64, activation="relu", name="dense_1_shared",
                   kernel_initializer=keras.initializers.glorot_uniform(seed=int(time.time())))(inputs)
        d2 = Dense(64, activation="relu", name="dense_2_shared",
                   kernel_initializer=keras.initializers.glorot_uniform(seed=None))(d1)
        # create the heads that come on top of the gamelayers
        models = []
        heads = []
        for i in range(head_count):
            name = "head_{}".format(i)
            head = Dense(self.action_count, activation='relu', name=name,
                         kernel_initializer=keras.initializers.glorot_uniform(seed=None))(d2)
            heads.append(head)
            model = Model(input=inputs, output=head, name=("headmodel: {}".format(str(i))))
            model.compile(loss='mse', optimizer='adam')
            models.append(model)
        total_model = Model(input=inputs, output=heads, name="overall_modell")
        total_model.compile(loss='mse', optimizer='adam')

我正在寻找一种方法来传递掩码列表以及 x 和 y 的训练集,以便只有掩码指示的头部适合对应的 x 和 y。

提前致谢

标签: kerasneural-network

解决方案


我会做以下事情。

为每个头部创建 head_masks

inputs = Input(shape=(state_count,))
head_masks = [Input(shape=(n_labels,)) for _ in range(head_count)]
# create the layers that learn the gane
d1 = Dense(64, activation="relu", name="dense_1_shared",
            kernel_initializer=keras.initializers.glorot_uniform(seed=100))(inputs)
d2 = Dense(64, activation="relu", name="dense_2_shared",
            kernel_initializer=keras.initializers.glorot_uniform(seed=None))(d1)
# create the heads that come on top of the gamelayers
models = []
heads = []
for i in range(head_count):
    name = "head_{}".format(i)
    head = Dense(n_labels, activation='relu', name=name,
                  kernel_initializer=keras.initializers.glorot_uniform(seed=None))(d2)
    heads.append(head*head_masks[i])

total_model = Model(inputs=[inputs,*head_masks], outputs=heads, name="overall_modell")

创建输入、目标和掩码

这是使用玩具数据集。我正在创建一个包含 25 个元素的数据集。首先samples是数据点。然后我有一个与每个头对应的标签列表(每个标签集的大小25, state_count)。

接下来我创建面具。假设我有一个 size 的面具(25, head_count)。我需要做一些操作才能使这个形状正确。最终,我们需要一个(带有head_count元素)作为掩码的列表,其中每个掩码是 size (25, n_labels)。然后我们屏蔽任何具有屏蔽值 0 的预测和标签。这将导致梯度为零。所以不会对这些样本和相应的头部进行任何训练。

samples = np.random.normal(size=(25, state_count))
labels = [np.random.choice([0,1], size=(25, n_labels)) for _ in range(head_count)]
fit_mask = np.random.choice([0,1], size=(25, head_count))
fit_mask = np.repeat(np.expand_dims(fit_mask, axis=-1), n_labels, axis=-1)
fit_masks = [m[:,0,:] for m in np.split(fit_mask, head_count, axis=1)]

total_model.fit([samples, *fit_masks], [l*m for l,m in zip(labels, fit_masks)])


推荐阅读