假设我有一个10x10x4
的卷积层中间输出,我需要将其分割成100个1x1x4
的体数据,并对每个体数据应用softmax函数,以从网络中获得100个输出。有没有办法在不使用Lambda
层的情况下实现这一点?使用Lambda
层的问题在于,在前向传递过程中,需要通过lambda层进行100次传递,这使得网络性能对于我的实际使用非常慢。请建议一个更快的方法来实现这一点。
编辑:在提问之前,我已经尝试过Softmax+Reshape的方法。使用这种方法,我会得到一个10x10x4的矩阵,通过Reshape重塑为100×4的张量作为输出。但我真正需要的是一个具有100个不同输出的多输出网络。在我的应用中,不可能对10×10矩阵进行联合优化,但通过使用具有100个不同输出的网络,并使用Lambda层,我得到了很好的结果。
以下是我使用Keras函数式API的方法的代码片段:
使用Lambda层(速度慢,按预期给出100个形状为(None, 4)的张量):
# 假设conv_output是形状为(None, 10, 10, 4)的卷积层输出preds = []for i in range(10): for j in range(10): y = Lambda(lambda x, i,j: x[:, i, j,:], arguments={'i': i,'j':j})(conv_output) preds.append(Activation('softmax',name='predictions_' + str(i*10+j))(y))model = Model(inputs=img, outputs=preds, name='model')model.compile(loss='categorical_crossentropy', optimizer=Adam(), metrics=['accuracy']
使用Softmax+Reshape(速度快,但给出形状为(None, 100, 4)的张量)
# 假设conv_output是形状为(None, 10, 10, 4)的卷积层输出y = Softmax(name='softmax', axis=-1)(conv_output)preds = Reshape([100, 4])(y)model = Model(inputs=img, outputs=preds, name='model')model.compile(loss='categorical_crossentropy', optimizer=Adam(), metrics=['accuracy']
我认为在第二种情况下,不可能对100个输出中的每一个进行单独优化(可能可以将其视为学习联合分布,而我需要像第一种情况那样学习边缘分布)。请告诉我是否有任何方法可以更快地实现我在第一个代码片段中使用Lambda层所做的事情
回答:
你可以使用Softmax
层,并将axis参数设置为最后一个轴(即-1
),以便在该轴上应用softmax函数:
from keras.layers import Softmaxsoft_out = Softmax(axis=-1)(conv_out)
请注意,axis
参数默认设置为-1
,所以你可能甚至不需要传递这个参数。