1

我无法调整现有的 Keras 模型以与TenforFlow Federated一起使用。

现有模型是一维卷积自编码器(详情如下图)

现有型号:

input_window = Input(shape=(window_length,1))

x = Conv1D(16, 3, activation="relu", padding="same")(input_window)
x = MaxPooling1D(2, padding="same")(x)
x = Conv1D(1, 3, activation="relu", padding="same")(x)

encoded = MaxPooling1D(2, padding="same")(x)
encoder = Model(input_window, encoded)

x = Conv1D(1, 3, activation="relu", padding="same")(encoded)
x = UpSampling1D(2)(x)
x = Conv1D(16, 1, activation='relu')(x)
x = UpSampling1D(2)(x)

decoded = Conv1D(1, 3, activation='sigmoid', padding='same')(x)

autoencoder = Model(input_window, decoded)

训练数据作为numpy.ndarray形状传递(102, 48, 1)

从概念上讲,这代表 102 天的数据,每个包含 48 个值。如果它有助于回答,我可以提供一个例子。

我尝试转换模型如下所示。

转换模型:

def create_compiled_keras_model():

    input_window = tf.keras.layers.Input(shape=(window_length,1))

    x = tf.keras.layers.Conv1D(16, 3, activation="relu", padding="same")(input_window)
    x = tf.keras.layers.MaxPooling1D(2, padding="same")(x)
    x = tf.keras.layers.Conv1D(1, 3, activation="relu", padding="same")(x)

    encoded = tf.keras.layers.MaxPooling1D(2, padding="same")(x)
    encoder = tf.keras.Model(input_window, encoded)

    x = tf.keras.layers.Conv1D(1, 3, activation="relu", padding="same")(encoded)
    x = tf.keras.layers.UpSampling1D(2)(x)
    x = tf.keras.layers.Conv1D(16, 1, activation='relu')(x)
    x = tf.keras.layers.UpSampling1D(2)(x)

    decoded = tf.keras.layers.Conv1D(1, 3, activation='sigmoid', padding='same')(x)

    autoencoder = tf.keras.Model(input_window, decoded)
    autoencoder.compile(optimizer='adam', loss='MSE')
    return autoencoder



sample_batch = train // numpy.ndarray of shape (102, 48, 1)


def model_fn():
    keras_model = create_compiled_keras_model()
    return tff.learning.from_compiled_keras_model(keras_model, train)

这会产生错误:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-397-9bed171c79be> in <module>
----> 1 model = model_fn()

<ipython-input-396-13bc1955a7f2> in model_fn()
      1 def model_fn():
      2     keras_model = create_compiled_keras_model()
----> 3     return tff.learning.from_compiled_keras_model(keras_model, train)

~/miniconda3/lib/python3.6/site-packages/tensorflow_federated/python/learning/model_utils.py in from_compiled_keras_model(keras_model, dummy_batch)
    190     raise ValueError('`keras_model` must be compiled. Use from_keras_model() '
    191                      'instead.')
--> 192   return enhance(_TrainableKerasModel(keras_model, dummy_batch))
    193 
    194 

~/miniconda3/lib/python3.6/site-packages/tensorflow_federated/python/learning/model_utils.py in __init__(self, inner_model, dummy_batch)
    434     # until the model has been called on input. The work-around is to call
    435     # Model.test_on_batch() once before asking for metrics.
--> 436     inner_model.test_on_batch(**dummy_batch)
    437     # This must occur after test_on_batch()
    438     if len(inner_model.loss_functions) != 1:

TypeError: test_on_batch() argument after ** must be a mapping, not numpy.ndarray

到目前为止,我一直无法解决这个问题。这是与我的模型未正确编译有关的问题,还是由于我传递数据的方式?

任何解决此问题的帮助将不胜感激,谢谢!

4

1 回答 1

1

样本批次应该是可以传递给tff.learning.Model.forward_passbatch_input参数的东西。

对于包装好的 Keras 模型,这必须是一个带有与tf.keras.models.Model.test_on_batch的参数匹配的键的字典。

对于这种情况,我认为您可以简单地将示例批次包装在一个带有单个键的 dict 中x

numpy_sample_batch = train // numpy.ndarray
sample_batch = {'x': numpy_sample_batch}
于 2019-04-18T19:02:51.427 回答