How to perform custom operations in between keras layers?

Issue

I have one input and one output neural network and in between I need to perform small operation. I have two inputs (from the same distribution of either mean 0 or mean 1) which I need to fed to the neural network one at a time and compare the output of each input. After the comparison, I am finally generating the prediction of the model. The implementation is as follows:

   
from tensorflow import keras
import tensorflow as tf
import numpy as np
#define network
x1 = keras.Input(shape=(1), name="x1")
x2 = keras.Input(shape=(1), name="x2")

model = keras.layers.Dense(20) 
model1 = keras.layers.Dense(1)

x11 = model1(model(x1))
x22 = model1(model(x2))

After this I need to perform following operations:

if x11>=x22:
  Vm=x1
else:
  Vm=x2

Finally I need to do:

out = Vm - 0.5
out= keras.activations.sigmoid(out)
model = keras.Model([x1,x2], out)

model.compile(
    optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),
    loss=tf.keras.losses.binary_crossentropy, 
    metrics=['accuracy']
    )
model.summary()
tf.keras.utils.plot_model(model) #visualize model

I have normally distributed pair of data with same mean (mean 0 and mean 1 as generated below:

#Generating training dataset
from scipy.stats import skewnorm

n=1000 #sample each
s = 1 # scale to change o/p range
X1_0 = skewnorm.rvs(a = 0 ,loc=0, size=n)*s; X1_1 = skewnorm.rvs(a = 0 ,loc=1, size=n)*s  #Skewnorm function
X2_0 = skewnorm.rvs(a = 0 ,loc=0, size=n)*s; X2_1 = skewnorm.rvs(a = 0 ,loc=1, size=n)*s  #Skewnorm function

X1_train = list(X1_0) + list(X1_1) #append both data 
X2_train = list(X2_0) + list(X2_1) #append both data

y_train = [x for x in (0,1) for i in range(0, n)] #make Y for above conditions

#reshape to proper format
X1_train = np.array(X1_train).reshape(-1,1)
X2_train = np.array(X2_train).reshape(-1,1)
y_train = np.array(y_train)

#train model
model.fit([X1_train, X2_train], y_train, epochs=10)

I am not been able to run the program if I include operation

if x11>=x22:
  Vm=x1
else:
  Vm=x2

in between layers. If I directly work with maximum of outputs as:

Vm = keras.layers.Maximum()([x11,x22])

The program is working fine. But I need to select either x1 or x2 based on the value of x11 and x22.

The problem might be due to the inclusion of the comparison operation while defining structure of the model where there is no value for x11 and x22 (I guess). I am totally new to all these stuffs and so I could not resolve this. I would greatly appreciate any help/suggestions. Thank you.

Solution

You can add this functionality via a Lambda layer.

Vm = tf.keras.layers.Lambda(lambda x: tf.where(x[0]>=x[1], x[2], x[3]))([x11, x22, x1, x2])

Answered By – thushv89

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published