Керас: Есть ли способ обойти вывод промежуточного слоя без использования слоя Lamda? - PullRequest
0 голосов
/ 19 декабря 2018

Скажем, у меня есть 10x10x4 промежуточный выход слоя свертки, который мне нужно разделить на объем 100 1x1x4 и применить softmax к каждому, чтобы получить 100 выходов из сети.Есть ли способ сделать это без использования слоя Lambda?Проблема со слоем Lambda в этом случае заключается в том, что эта простая задача разделения занимает 100 проходов через лямбда-слой во время прямого прохода, что делает производительность сети очень низкой для моего практического использования.Пожалуйста, предложите более быстрый способ сделать это.

Редактировать: Я уже пробовал подход Softmax + Reshape, прежде чем задавать вопрос.При таком подходе я получу матрицу 10x10x4, преобразованную в Tensor 100x4 с использованием Reshape в качестве вывода.Что мне действительно нужно, так это сеть с несколькими выходами.В моем приложении невозможно совместно оптимизировать матрицу 10x10, но я получаю хорошие результаты, используя сеть с 100 различными выходами со слоем Lambda.

Вот фрагменты кода моего подхода с использованием функционального API Keras:

Со слоем Lambda (медленный, при желании выдает 100 тензорных фигур (None, 4)):

# Assume conv_output is output from a convolutional layer with shape (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 (быстро, но дает тензор формы (Нет, 100, 4))

# Assume conv_output is output from a convolutional layer with shape (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 в первом фрагменте кода, более быстрым способом

1 Ответ

0 голосов
/ 19 декабря 2018

Вы можете использовать слой Softmax и установить аргумент оси на последнюю ось (то есть -1), чтобы применить softmax к этой оси:

from keras.layers import Softmax

soft_out = Softmax(axis=-1)(conv_out)

Обратите внимание, что аргумент axisпо умолчанию установлено значение -1, поэтому вам, возможно, даже не понадобится передавать его.

...