具有多个 类 的最后一个输出层。由 Tensorflow 支持的 Keras
Last output layer with multiple classes. Keras backed by Tensorflow
按照此 example and this article 进行强化学习。我终于设法创建了一个类似的 Q-learning 来学习玩另一个游戏环境。我唯一的问题是神经网络的最后一个输出层代表游戏的输入动作。
游戏环境的mechanics/logic与本题无关,但游戏环境对于每个给定的动作同时需要2种类型的输入:
- 输入数字1表示3种可能之间的单次按键
键。所以基本上该层应该输出 3 classes,其中概率和为 1。然后我会选择 class 最高的
这三个中的概率。
- 输入数字 2 表示从 0 到 1 的百分比。并且应该独立于前三个 class。
我真的不知道如何创建最后一个输出层,使其总共有 4 个输出 classes。前 3 个 class 应该给出彼此之间的概率,总和为 1。最后一个 class 应该独立于前三个并且应该在 0 到 1 之间。
有人可以为我指出正确的方向来实现这一目标吗?我如何构建这样的层?
我正在考虑这样的第一个输入:
model.add(Dense(output_dim=3))
model.add(Activation("softmax"))
model.compile(loss='categorical_crossentropy', optimizer="adam")
然后第二个输入是这样的
model.add(Dense(output_dim=1))
model.add(Activation("sigmoid"))
model.compile(loss='binary_crossentropy', optimizer='adam')
但我如何将它们组合成一个输出层?
也许您有另一种结构?
您可以使用 2 个输出层,每个层都有自己的损失。在 keras 的模型定义中使用输出数组。
您需要使用 functional API。然后,您可以有多个输出并为每个输出使用不同的损失函数,因为 compile()
的 loss
参数接受字典。这是一个小例子。我编造了 num_samples
和 num_features
,但在其他方面遵循了您的规范:
import numpy as np
from keras.layers import Input, Dense
from keras.models import Model
from keras.utils import to_categorical
num_samples = 10
num_features = 5
num_keys = 3
inputs = Input(shape=(num_features,))
hidden = Dense(30)(inputs)
key_press = Dense(num_keys, name='key_press', activation='softmax')(hidden)
percentage = Dense(1, name='percentage', activation='sigmoid')(hidden)
model = Model(inputs=inputs, outputs=[key_press, percentage])
loss_map = {'key_press': 'categorical_crossentropy', 'percentage': 'mse'}
model.compile(loss=loss_map, optimizer='sgd')
当您 fit()
.
时,您需要为 y
传递一个字典
y_key_press = np.random.randint(num_keys, size=num_samples)
y_key_press = to_categorical(y_key_press) # needs to be one-hot encoded
y_percentage = np.random.uniform(size=num_samples)
y = {'key_press': y_key_press, 'percentage': y_percentage}
x = np.random.normal(size=(num_samples, num_features))
model.fit(x=x, y=y, epochs=5)
按照此 example and this article 进行强化学习。我终于设法创建了一个类似的 Q-learning 来学习玩另一个游戏环境。我唯一的问题是神经网络的最后一个输出层代表游戏的输入动作。
游戏环境的mechanics/logic与本题无关,但游戏环境对于每个给定的动作同时需要2种类型的输入:
- 输入数字1表示3种可能之间的单次按键 键。所以基本上该层应该输出 3 classes,其中概率和为 1。然后我会选择 class 最高的 这三个中的概率。
- 输入数字 2 表示从 0 到 1 的百分比。并且应该独立于前三个 class。
我真的不知道如何创建最后一个输出层,使其总共有 4 个输出 classes。前 3 个 class 应该给出彼此之间的概率,总和为 1。最后一个 class 应该独立于前三个并且应该在 0 到 1 之间。
有人可以为我指出正确的方向来实现这一目标吗?我如何构建这样的层?
我正在考虑这样的第一个输入:
model.add(Dense(output_dim=3))
model.add(Activation("softmax"))
model.compile(loss='categorical_crossentropy', optimizer="adam")
然后第二个输入是这样的
model.add(Dense(output_dim=1))
model.add(Activation("sigmoid"))
model.compile(loss='binary_crossentropy', optimizer='adam')
但我如何将它们组合成一个输出层?
也许您有另一种结构?
您可以使用 2 个输出层,每个层都有自己的损失。在 keras 的模型定义中使用输出数组。
您需要使用 functional API。然后,您可以有多个输出并为每个输出使用不同的损失函数,因为 compile()
的 loss
参数接受字典。这是一个小例子。我编造了 num_samples
和 num_features
,但在其他方面遵循了您的规范:
import numpy as np
from keras.layers import Input, Dense
from keras.models import Model
from keras.utils import to_categorical
num_samples = 10
num_features = 5
num_keys = 3
inputs = Input(shape=(num_features,))
hidden = Dense(30)(inputs)
key_press = Dense(num_keys, name='key_press', activation='softmax')(hidden)
percentage = Dense(1, name='percentage', activation='sigmoid')(hidden)
model = Model(inputs=inputs, outputs=[key_press, percentage])
loss_map = {'key_press': 'categorical_crossentropy', 'percentage': 'mse'}
model.compile(loss=loss_map, optimizer='sgd')
当您 fit()
.
y
传递一个字典
y_key_press = np.random.randint(num_keys, size=num_samples)
y_key_press = to_categorical(y_key_press) # needs to be one-hot encoded
y_percentage = np.random.uniform(size=num_samples)
y = {'key_press': y_key_press, 'percentage': y_percentage}
x = np.random.normal(size=(num_samples, num_features))
model.fit(x=x, y=y, epochs=5)