我正在尝试使用 Keras 的 Merge
层从多个并行模型中计算加权输出。我使用的是 Theano
后端。
我有 L
个并行模型 (Ci)
。它们的输出层都是大小为 k 的 softmax。
还有一个模型 (N)
,它的输出是一个大小为 L 的 softmax。
到目前为止,我做的是这样:
并行模型 (Ci)
每个在输出层都有 k 维:
model.add(Dense(K, activation='softmax', W_regularizer=l2(0.001),init='normal'))
加权模型 (N)
的输出层:
model.add(Dense(L, activation='softmax', W_regularizer=l2(0.001), init='normal'))
合并方式如下:
model.add(Merge(layers=model_group, mode=lambda model_group: self.merge_fun(model_group, L), output_shape = (None, k)))
其中 “model_group” 是一个长度为 (L+1) 的列表 [N, C1, C2, ..., CL]
,而 merge_fun
的签名是:
def merge_fun(self, model_group, L):
从数学上讲,我希望合并层的输出是一个加权和:
out = N[1]x([C11, C12, C13, .., C1k]) + N[2]x([C21, C22, C23, …, C2k]) + … + N[L]x([CL1, CL2, CL3, …, CLk]),
其中 out 是一个大小为 k
的向量
我如何使用 Merge 层来实现这个目标?
我知道魔术可能需要在 ‘merge_fun’ 中发生,但我不知道如何在 Keras 中进行矩阵代数。张量参数没有 “shape” 参数 – 它们有一个 keras_shape = (None, K or L)
– 但我不知道如何将并行模型的输出组合成一个矩阵。
我尝试使用以下表达式进行本地评估:
K.concatenate([model_group[1], model_group[2]], axis=0)*model_group[0]
和
model_group[0] * K.concatenate([model_group[1], model_group[2]], axis=0)
这两者都没有抛出错误,所以我无法以此为指导。乘法后,返回的结果没有 keras_shape
变量,所以我不确定结果的形状是什么。
有什么建议吗?
回答:
我建议您使用功能 API,并以以下方式使用它:
-
定义
L
个输出模型:softmax_1 = Dense(K, activation='softmax', ...)(input_to_softmax_1)softmax_2 = Dense(K, activation='softmax', ...)(input_to_softmax_2)...softmax_L = Dense(K, activation='softmax', ...)(input_to_softmax_L)
-
定义合并 softmax:
merge_softmax= Dense(L, activation='softmax', ...)(input_to_merge_softmax)merge_softmax = Reshape((1, L))(merge_softmax)
-
合并并重塑
L
个模型的集合:bag_of_models = merge([softmax_1, ..., softmax_L], mode = 'concat')bag_of_models = Reshape((L, K))(bag_of_models)
-
计算最终合并的 softmax:
final_result = merge([bag_of_models, merge_softmax], mode = 'dot', dot_axes = [1, 2])final_result = Reshape((K, ))(final_result)
当然 – 根据您的拓扑结构 – 不同的张量可能是相同的(例如,不同 softmax 的输入)。我在我的机器上测试了这个方法,但由于进行了大量的重构 – 我可能会犯错 – 所以如果您发现错误 – 请告知我。
使用 Sequential
的解决方案要模糊得多,也有点繁琐 – 但如果您想要一个 – 请在评论中写下来,我会更新我的回答。