Как использовать лямбда-слой в Керасе?

Я хочу определить лямбда-слой, чтобы объединить функции с перекрестным произведением, а затем объединить эти модели, как показано на рис. ,Что я должен делать?

введите здесь описание изображения

Протестируйте модель_1, получите 128-мерную форму, используйте pywt, чтобы получить две 64-мерные функции (cA,cD), затем верните cA*cD //конечно, я хочу объединить две модели, но сначала попробуйте model_1.

from keras.models import Sequential,Model
from keras.layers import Input,Convolution2D,MaxPooling2D
from keras.layers.core import Dense,Dropout,Activation,Flatten,Lambda
import pywt

def myFunc(x):
    (cA, cD) = pywt.dwt(x, 'db1')
#    x=x*x
    return cA*cD

batch_size=32
nb_classes=3
nb_epoch=20
img_rows,img_cols=200,200
img_channels=1
nb_filters=32
nb_pool=2
nb_conv=3

inputs=Input(shape=(1,img_rows,img_cols))
x=Convolution2D(nb_filters,nb_conv,nb_conv,border_mode='valid',
                  input_shape=(1,img_rows,img_cols),activation='relu')(inputs)
x=Convolution2D(nb_filters,nb_conv,nb_conv,activation='relu')(x)
x=MaxPooling2D(pool_size=(nb_pool,nb_pool))(x)
x=Dropout(0.25)(x)
x=Flatten()(x)
y=Dense(128,activation='relu')(x)
cross=Lambda(myFunc,output_shape=(64,))(y)   
predictions=Dense(nb_classes,activation='softmax')(cross)
model = Model(input=inputs, output=predictions)
model.compile(loss='categorical_crossentropy',optimizer='adadelta',metrics=['accuracy'])

model.fit(X_train,Y_train,batch_size=batch_size,nb_epoch=nb_epoch,
          verbose=1,validation_data=(X_test,Y_test))

Извините, могу я задать вопрос о тензоре?

import tensorflow as tf
W1 = tf.Variable(np.array([[1,2],[3,4]]))
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
array = W1.eval(sess)
print (array)

Это верно! Однако,

from keras import backend as K
import numpy as np
kvar=K.variable(np.array([[1,2],[3,4]]))
K.eval(kvar)
print(kvar)

У меня <CudaNdarrayType(float32, matrix)>, а kvar.eval() у меня b'CudaNdarray([[ 1. 2.]\n [ 3. 4.]])'. Я использую keras, так как я могу получить массив, подобный тензорному потоку, с помощью keras?


person Ting Li    schedule 03.07.2017    source источник
comment
Итак, лямбда-функциям keras нужны все операции для использования тензоров. Все общие операции перечислены на странице keras.io/backend. Вы должны найти способ переписать pywt.dwt тензорным способом. К сожалению, это непростая задача. Я считаю, что этот вопрос очень важен, и я не могу ответить на него должным образом.   -  person Daniel Möller    schedule 06.07.2017
comment
Должен ли лямбда-слой использовать бэкэнд-функцию keras? Могу ли я преобразовать тензор в массив, затем использовать pywt.dwt, а затем преобразовать массив в тензор?   -  person Ting Li    schedule 06.07.2017
comment
Это возможно, но это прервет график и вызовет ошибку. Чтобы преобразовать тензор в массив, используйте tensorVar.eval(). Чтобы создать тензор из массива, используйте K.variable(arrayVar), где K — это keras.backend.   -  person Daniel Möller    schedule 06.07.2017
comment
Большое спасибо! я попробую   -  person Ting Li    schedule 07.07.2017
comment
Попробуйте karr = kvar.eval()   -  person Daniel Möller    schedule 07.07.2017
comment
Я print(karr), получил b'CudaNdarray([[ 1. 2.]\n [ 3. 4.]])'   -  person Ting Li    schedule 07.07.2017


Ответы (1)


Я бы, наверное, продублировал плотные слои. Вместо 2 слоев по 128 единиц используйте 4 слоя по 64 единицы. Результат тот же, но вы сможете лучше выполнять перекрестные произведения.

from keras.models import Model

#create dense layers and store their output tensors, they use the output of models 1 and to as input    
d1 = Dense(64, ....)(Model_1.output)   
d2 = Dense(64, ....)(Model_1.output)   
d3 = Dense(64, ....)(Model_2.output)   
d4 = Dense(64, ....)(Model_2.output)   

cross1 = Lambda(myFunc, output_shape=....)([d1,d4])
cross2 = Lambda(myFunc, output_shape=....)([d2,d3])

#I don't really know what kind of "merge" you want, so I used concatenate, there are Add, Multiply and others....
output = Concatenate()([cross1,cross2])
    #use the "axis" attribute of the concatenate layer to define better which axis will be doubled due to the concatenation    

model = Model([Model_1.input,Model_2.input], output)

Теперь для лямбда-функции:

import keras.backend as K

def myFunc(x):
    return x[0] * x[1]
person Daniel Möller    schedule 04.07.2017
comment
Большое спасибо! когда я использую model.add(Dense(128)) получаю 128 измерений, я добавляю model.add(Lambda(wavelets,output_shape=input_shape[0])), но я не знаю, как использовать лямбда-слой. Я хочу использовать вейвлеты (функция: (cA, cD) = pywt.dwt (x, 'db1')) для получения коэффициентов аппроксимации и детализации (они оба 64-мерные, как этот рис.). Затем произведите перекрестное произведение коэффициентов аппроксимации с моделями 1 и 2. Наконец, объедините коэффициенты аппроксимации и детализации с режимом concat. Можете ли вы помочь написать лямбда-слои? - person Ting Li; 05.07.2017
comment
извините, это не перекрестное произведение, это * - person Ting Li; 05.07.2017
comment
Обновил мой ответ. - person Daniel Möller; 05.07.2017
comment
извините, output_shape=..? Я использую theano в качестве бэкэнда, он не может делать автоматические выводы. - person Ting Li; 06.07.2017
comment
Да, вы должны поместить output_shape в лямбда-слои. Если вы используете одномерные векторы, плотные слои будут выводить (64,), поэтому выходная форма в лямбда-выражении также будет (64,) - person Daniel Möller; 06.07.2017
comment
Когда я запускаю этот код, я получаю сообщение об ошибке: TypeError: Cannot convert str to numpy.dtype Если myFunc(x) равно x=x*x и return x, это правильно! почему я не могу справиться с x с pywt.dwt?Пожалуйста, помогите - person Ting Li; 06.07.2017
comment
Не могли бы вы опубликовать свой код? Мы не сможем помочь, если не будем точно знать, что вы делаете. Но вкратце: вы должны использовать тензоры keras внутри лямбда-функции (см.: keras.io/backend). Вы не можете использовать обычные списки, массивы и т. д. Вы можете преобразовать список или массив в тензор с помощью tensor = K.variable(array) - person Daniel Möller; 06.07.2017