Keras: How to reshape a 4D tensor to 3D with None dimensions?

Created on 20 Oct 2017  路  3Comments  路  Source: keras-team/keras

Hi all,

I encountered a problem to reshape an intermediate 4D tensorflow tensor X of shape ( batch_size, nb_rows, nb_cols, nb_filters ) to a new tensor Y of shape ( batch_size, nb_rows * nb_cols, nb_filters ), where nb_filters is always a known integer.

Of course, when nb_rows and nb_cols are also known integers, I can reshape X without any problem. However, what if nb_rows = nb_cols = None? I tried Y = Reshape( (-1, nb_filters))(X) but keras returns an error, basically saying that dimension can not be None.

For me, this operation is deterministic in the way that it always squeeze the two middle axes into a single one while keeping the first axis and the last axis unchanged. Can anyone help me?

Most helpful comment

Alright, I finally got helps from stack overflow
https://stackoverflow.com/questions/47026042/how-to-reshape-a-tensor-with-multiple-none-dimensions

Below is my (tensorflow) solution

from keras.layers import Layer, Input, Lambda
from keras import backend as K
import tensorflow as tf
from keras.models import Model
import numpy as np 

def squeeze_middle2axes_operator( x4d ) :
    shape = tf.shape( x4d ) # get dynamic tensor shape
    x3d = tf.reshape( x4d, [shape[0], shape[1] * shape[2], shape[3] ] )
    return x3d

def squeeze_middle2axes_shape( x4d_shape ) :
    in_batch, in_rows, in_cols, in_filters = x4d_shape
    if ( None in [ in_rows, in_cols] ) :
        output_shape = ( in_batch, None, in_filters )
    else :
        output_shape = ( in_batch, in_rows * in_cols, in_filters )
    return output_shape

# define a dummy model
xx = Input( shape=(None, None, 16) )
yy = Lambda( squeeze_middle2axes_operator, output_shape = squeeze_middle2axes_shape )( xx )
mm = Model( inputs = xx, outputs = yy )
print mm.summary()

# validate model outputs
a = np.random.randn(1,2,3,16)
a2 = np.random.randn(2,4,5,16)
print mm.predict(a).shape # (1, 6, 16)
print mm.predict(a2).shape # (2, 20, 16)

All 3 comments

Alright, I finally got helps from stack overflow
https://stackoverflow.com/questions/47026042/how-to-reshape-a-tensor-with-multiple-none-dimensions

Below is my (tensorflow) solution

from keras.layers import Layer, Input, Lambda
from keras import backend as K
import tensorflow as tf
from keras.models import Model
import numpy as np 

def squeeze_middle2axes_operator( x4d ) :
    shape = tf.shape( x4d ) # get dynamic tensor shape
    x3d = tf.reshape( x4d, [shape[0], shape[1] * shape[2], shape[3] ] )
    return x3d

def squeeze_middle2axes_shape( x4d_shape ) :
    in_batch, in_rows, in_cols, in_filters = x4d_shape
    if ( None in [ in_rows, in_cols] ) :
        output_shape = ( in_batch, None, in_filters )
    else :
        output_shape = ( in_batch, in_rows * in_cols, in_filters )
    return output_shape

# define a dummy model
xx = Input( shape=(None, None, 16) )
yy = Lambda( squeeze_middle2axes_operator, output_shape = squeeze_middle2axes_shape )( xx )
mm = Model( inputs = xx, outputs = yy )
print mm.summary()

# validate model outputs
a = np.random.randn(1,2,3,16)
a2 = np.random.randn(2,4,5,16)
print mm.predict(a).shape # (1, 6, 16)
print mm.predict(a2).shape # (2, 20, 16)

@rex-yue-wu Hi Can you help me how I can convert my tensor from(None,) to (None,1)

encoded (?, 4)
encod (?, 2)
normalize (?, 2)
Complex_symbols (?,)
decode(?,)
concat (?, 2)
deco (?, 4)
decod (?, 4)
I have size (None,) in 2 layers decode and concat where I need the size to be (None,1)
how should I use a Reshape or lambda function in this case? Or is there any other option

@pachpandepriti
x.shape == (None,)
x = tf.keras.layers.Reshape((-1,1))(x)
x.shape == (None,1)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

farizrahman4u picture farizrahman4u  路  3Comments

zygmuntz picture zygmuntz  路  3Comments

nryant picture nryant  路  3Comments

vinayakumarr picture vinayakumarr  路  3Comments

snakeztc picture snakeztc  路  3Comments