Keras: Splitting the output of a layer over the channels

Created on 22 Feb 2017  路  11Comments  路  Source: keras-team/keras

I am trying to implement a single input, multiple-output model using the functional API. I want to split the output of a convolutional layer over the channels and then work these outputs to different loss functions. I tried the following below; however, it did not work:

x = Convolution2D(3, 5, 5, border_mode='same')(x)
x0 = x[:, 0, :, :]  
x1 = x[:, 1, :, :]
x2 = x[:, 2, :, :]

I saw that the possibility of a Split layer has been discussed but I don't think it exists yet. Any suggestions on how I can achieve this splitting?

Most helpful comment

x0 = Lambda(lambda x : x[:,:,:,0])(x)
x1 = Lambda(lambda x : x[:,:,:,1])(x)
x2 = Lambda(lambda x : x[:,:,:,2])(x)

All 11 comments

3 Lambda layers, each one of which connects to x and are the output layers..

x0 = Lambda(lambda x : x[:,:,:,0])(x)
x1 = Lambda(lambda x : x[:,:,:,1])(x)
x2 = Lambda(lambda x : x[:,:,:,2])(x)

Thank you @patyork and @abhaikollara for your suggestions.
I tried using the Lambda layer exactly as follows:

de_out1 = Lambda(lambda x: x[:, 0, :, :])(de_out) 

However de_out1 has the same keras_shape as de_out has. Any ideas why this is not behaving as expected?

@atuysuz Could you mention the input to the convolutional layer ?

It seems to work fine for me (using Tensorflow as backend)
~~~~
x = Input((1,28,28))
x = Convolution2D(3,5,5,border_mode='same', dim_ordering='th')(x)
x0 = Lambda(lambda x : x[:,0,:,:])(x)
x1 = Lambda(lambda x : x[:,1,:,:])(x)
x2 = Lambda(lambda x : x[:,2,:,:])(x)

print x.shape
print x0.shape
~~~~

~~
(?, 3, 28, 28)
(?, 28, 28)
~
~

You should provide the output_shape parameter to the Lambda layers when you are changing the shape within the function.

Yes, Theano does not automatically infer shapes of lambda layer outputs. I think updating Keras should produce warnings about this.

Thank you again folks!
Indeed, this was the issue in using the Lambda layer. I am using Theano backend and once I provided the output shape, all is fine.

Is there a way to do this with a layer object?

If the input shape is shape=(?, 64, 64, 64)
How to split into say 30% and 70% without changing the last three dimension
eg. for(100,64,64,64) to (30,64,64,64) and (70,64,64,64)

@sandeepnmenon - Were you able to figure out a solution to your question?

@bairavi26 Please see the code below

def get_gated_connections(gatePercentageFactor,inputLayer):
    fractionG = Lambda(lambda x, factor : factor * x, arguments = {'factor': gatePercentageFactor})(inputLayer)
    complement = Lambda(lambda x: x[0] - x[1])([inputLayer,fractionG])

    return fractionG,complement

where gatePercentage is the split factor (ex. 0.7) and inputLayer is the layer whose output who you want to split.

Usage

 x1 = Conv2D(64, conv_filter, activation='relu', padding='same')(input_img)
 fg1,c1 = get_gated_connections(0.1,x1)

Hope it helps

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kylemcdonald picture kylemcdonald  路  3Comments

fredtcaroli picture fredtcaroli  路  3Comments

oweingrod picture oweingrod  路  3Comments

braingineer picture braingineer  路  3Comments

snakeztc picture snakeztc  路  3Comments