Керас: Есть ли обходной путь для разделения вывода промежуточного слоя без использования слоя Lamda?

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

Изменить: я уже пробовал подход Softmax + Reshape, прежде чем задавать вопрос. При таком подходе я бы получил матрицу 10x10x4, преобразованную в тензор 100x4 с использованием Reshape в качестве вывода. Что мне действительно нужно, так это сеть с несколькими выходами и 100 различными выходами. В моем приложении невозможно совместно оптимизировать матрицу 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 (быстро, но дает тензор формы (None, 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 в первом фрагменте кода.


person user6240174    schedule 19.12.2018    source источник
comment
Можете ли вы поделиться кодом о том, как вы это делаете сейчас? Вероятно, это очень легко сделать с помощью Reshape и Softmax.   -  person Dr. Snoopy    schedule 19.12.2018
comment
@MatiasValdenegro - я обновил вопрос, добавив код как для подхода уровня Lambda, так и для подхода Softmax + Reshape, который вы предложили. Как видите, мне нужно 100 различных выходов, а не один выходной тензор формы 100. Приносим извинения за задержку с отслеживанием - мне пришлось проверить, что изучение сустава действительно не сработает в моем случае. Пожалуйста, дайте мне знать, если есть более быстрый способ.   -  person user6240174    schedule 21.12.2018
comment
@ user6240174 Я думаю, вы ошибаетесь, полагая, что когда модель имеет 100 выходных слоев формы (4,) по сравнению с выходом (100, 4), будет разница в их процессе оптимизации. Нет, нет. Фактически категориальная кроссэнтропия применяется к последней оси, и в этих случаях нет никакой разницы. Обратите внимание, что когда есть 100 выходных данных формы (4,), их потери будут суммироваться, и это значение будет минимизировано. По той же причине вам может вообще не понадобиться этот слой Reshape (конечно, если форма меток согласована).   -  person today    schedule 21.12.2018


Ответы (1)


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

from keras.layers import Softmax

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

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

person today    schedule 19.12.2018
comment
Спасибо за ответы. Пожалуйста, ознакомьтесь с моей редакцией вопроса - это работает, но мне не нужно этому учиться. Мне нужна сеть с несколькими выходами и 100 различными выходами. - person user6240174; 21.12.2018