input_shape 在 Keras 模型中无法识别

input_shape not recognised in Keras model

我正在尝试使用 Tensorflow 的 2.0 新 MirroredStrategy,但我收到一条错误消息:

ValueError: We currently do not support distribution strategy with a `Sequential` model that is created without `input_shape`/`input_dim` set in its first layer or a subclassed model.

型号:

class Model(kr.Model):
    def __init__(self, input_shape, conv_sizes, num_outputs):
        super().__init__('model_1')
        self.num_outputs = num_outputs

        rows, cols, depth = input_shape
        self.one_hot = kl.Lambda(lambda x: tf.one_hot(tf.cast(x, 'int32'), num_outputs), input_shape=(rows, cols))
        self.concat = kl.Concatenate(axis=-1)
        vision_layers = []
        for i, (filters, kernel, stride) in enumerate(conv_sizes):
            if not i:
                depth += num_outputs - 1
                vision_layers += [kl.Conv2D(filters, kernel, stride, activation='relu',
                                            input_shape=(rows, cols, depth))]
            else:
                vision_layers += [kl.Conv2D(filters, kernel, stride, activation='relu')]
            vision_layers += [kl.MaxPool2D(pool_size=(2, 2))]

        flatten = kl.Flatten()
        dense = kl.Dense(num_outputs)
        self.net = kr.Sequential(vision_layers+[flatten]+[dense])
        self.build(input_shape=(None, ) + input_shape)

    def call(self, inputs):
        one_hot = self.one_hot(inputs[:, :, :, -1])
        return self.net(self.concat([inputs[:, :, :, :-1], one_hot]))

复制代码:

model_args = {'conv_sizes': [(32, (2, 2), 1), (32, (2, 2), 1), (32, (2, 2), 1)],
               'input_shape': (50, 50, 6),
               'num_outputs': 5}

def dummy_loss(values, targets):
    return tf.reduce_sum(values-targets, axis=-1)


mirrored_strategy = tf.distribute.MirroredStrategy()
with mirrored_strategy.scope():
    model = Model(**model_args)
    model.compile(optimizer=kr.optimizers.Adam(learning_rate=0.01), loss=dummy_loss)

输出:

Traceback (most recent call last):
  File "/home/joao/anaconda3/envs/tf2/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 3296, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-4-dc492e7c638b>", line 18, in <module>
    model.compile(optimizer=kr.optimizers.Adam(learning_rate=0.01), loss=dummy_loss)
  File "/home/joao/anaconda3/envs/tf2/lib/python3.6/site-packages/tensorflow/python/training/tracking/base.py", line 456, in _method_wrapper
    result = method(self, *args, **kwargs)
  File "/home/joao/anaconda3/envs/tf2/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 263, in compile
    'We currently do not support distribution strategy with a '
ValueError: We currently do not support distribution strategy with a `Sequential` model that is created without `input_shape`/`input_dim` set in its first layer or a subclassed model.

模型总结(model.summary()):

Model: "model_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
lambda (Lambda)              multiple                  0         
_________________________________________________________________
concatenate (Concatenate)    multiple                  0         
_________________________________________________________________
sequential (Sequential)      (None, 5)                 13573     
=================================================================
Total params: 13,573
Trainable params: 13,573
Non-trainable params: 0

我会取消 Sequential 方法并直接使用 Model class:


def create_model(input_shape, conv_sizes, fc_sizes, num_outputs):
    num_outputs = num_outputs
    rows, cols, depth = input_shape
    input_layer = kl.Input(shape=(rows, cols, depth))
    actions = tf.slice(input_layer, [0, 0, 0, depth - 1], [-1, rows, cols, 1])
    non_actions = tf.slice(input_layer, [0, 0, 0, 0], [-1, rows, cols, depth - 1])
    one_hot = kl.Lambda(lambda x: tf.one_hot(tf.cast(x, 'int32'), num_outputs),
                        input_shape=(rows, cols))(actions)
    concat = kl.Concatenate(axis=-1)([non_actions, tf.reshape(one_hot, (-1, rows, cols, num_outputs))])
    vision_layer = concat
    for i, (filters, kernel, stride) in enumerate(conv_sizes):
        vision_layer = kl.Conv2D(filters, kernel, stride, activation='relu')(vision_layer)
        vision_layer = kl.MaxPool2D(pool_size=(2, 2))(vision_layer)

    flatten = kl.Flatten()(vision_layer)
    dense = kl.Dense(num_outputs)(flatten)
    return kr.Model(inputs=input_layer, outputs=[dense])