keras的compute_output_shape不适用于自定义层 [英] keras compute_output_shape not working for Custom layer

查看:174
本文介绍了keras的compute_output_shape不适用于自定义层的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我定制了一个图层,将batch_size和第一个维度合并,其他维度保持不变,但是compute_output_shape似乎没有任何作用,导致随后的图层无法获取准确的形状信息,从而导致错误.如何使compute_output_shape工作?

I customized a layer, merged the batch_size and the first dimension, the other dimensions remained unchanged, but compute_output_shape seemed to have no effect, resulting in the subsequent layer could not get accurate shape information, resulting in an error. How do I make compute_output_shape work?

import keras
from keras import backend as K

class BatchMergeReshape(keras.layers.Layer):
    def __init__(self, **kwargs):
        super(BatchMergeReshape, self).__init__(**kwargs)

    def build(self, input_shape):
        super(BatchMergeReshape, self).build(input_shape)  

    def call(self, x):
        input_shape = K.shape(x)
        batch_size, seq_len = input_shape[0], input_shape[1]
        r = K.reshape(x, (batch_size*seq_len,)+input_shape[2:])
        print("call_shape:",r.shape)
        return r

    def compute_output_shape(self, input_shape):
        if input_shape[0] is None:
            r = (None,)+input_shape[2:]
            print("compute_output_shape:",r)
            return r
        else:
            r = (input_shape[0]*input_shape[1],)+input_shape[2:]
            return r

a = keras.layers.Input(shape=(3,4,5))
b = BatchMergeReshape()(a)
print(b.shape)

# call_shape: (?, ?)
# compute_output_shape: (None, 4, 5)
# (?, ?)

我需要获取(None,4,5)但要获取(None,None),为什么compute_output_shape不起作用.我的keras版本是2.2.4

I need to get (None,4,5) but get (None,None),why compute_output_shape didn't work. My keras version is 2.2.4

推荐答案

问题可能是 K.shape 返回一个张量而不是一个元组.您不能执行(batch_size * seq_len,)+ input_shape [2:] .这混合了很多东西,张量和元组,结果肯定是错误的.

The problem is probably that K.shape returns a tensor not a tuple. You can't do (batch_size*seq_len,) + input_shape[2:]. This is mixing a lot of things, tensors and tuples, the result will certainly be wrong.

现在的好处是,如果您知道其他尺寸而不是批量大小,则只需要这一层:

Now the good thing is that, if you know the other dimensions and just not the batch size, you just need this layer:

Lambda(lambda x: K.reshape(x, (-1,) + other_dimensions_tuple))

如果不这样做,则:

input_shape = K.shape(x)
new_batch_size = input_shape[0:1] * input_shape[1:2] #needs to keep a shape of an array   
                 #new_batch_size.shape = (1,)
new_shape = K.concatenate([new_batch_size, input_shape[2:]]) #this is a tensor   
                                                             #result of concatenating 2 tensors   

r = K.reshape(x, new_shape)

请注意,这在Tensorflow中有效,但在Theano中可能无效.

Notice that this works in Tensorflow, but may not work in Theano.

还请注意,Keras将要求模型输出的批量大小等于模型输入的批量大小.这意味着您将需要在模型结束之前恢复原始的批处理大小.

Notice also that Keras will demand that the batch size of the model's output is equal to the batch size of the model's inputs. This means that you will need to restore the original batch size before the end of the model.

这篇关于keras的compute_output_shape不适用于自定义层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆