TypeError: Value passed to parameter 'input' has DataType bool not in list of allowed values, pass data in files to a model

TypeError: Value passed to parameter 'input' has DataType bool not in list of allowed values, pass data in files to a model

我正在使用多个 .CSV 文件来训练使用 TensorFlow federated 的多分类联邦学习模型。 我想使用自定义指标来衡量性能。但是我不确定如何将不同文件中提供的数据提供给这个自定义指标。 代码如下:

dataset_paths = {
  'file0': '/content/file0.csv',
  'file1': '/content/file1.csv',
  'file2': '/content/file2.csv',
}

@tf.function
def add_parsing(dataset):
  def parse_dataset(*x):
    return OrderedDict([('x', x[1:-1]),('y', x[-1])])
  return dataset.map(parse_dataset)
data = tff.simulation.datasets.FilePerUserClientData(
  dataset_paths, create_tf_dataset_for_client_fn) 

file_ids = sorted(data.file_ids)
data._file_ids = [tf.cast(c, tf.string) for c in data.client_ids] 

def create_keras_model():
  initializer = tf.keras.initializers.Zeros()
  return tf.keras.models.Sequential([
      tf.keras.layers.Input(shape=(7,)),
      tf.keras.layers.Dense(4, kernel_initializer=initializer),
      tf.keras.layers.Softmax(),
  ])
def model_fn():
  keras_model = create_keras_model()
  return tff.learning.from_keras_model(
      keras_model,
      input_spec=train_data[0].element_spec,
      loss=tf.keras.losses.SparseCategoricalCrossentropy(),
      metrics=[MulticlassTruePositives()]
      )

## compile the model
iterative_process = tff.learning.build_federated_averaging_process(
    model_fn,
    client_optimizer_fn=lambda: tf.keras.optimizers.SGD(learning_rate=0.06),
    server_optimizer_fn=lambda: tf.keras.optimizers.SGD(learning_rate=0.9))

自定义指标代码为:

class MulticlassTruePositives(tf.keras.metrics.Metric):
    def __init__(self, name='multiclass_true_positives', **kwargs):
        super(MulticlassTruePositives, self).__init__(name=name, **kwargs)
        self.true_positives = self.add_weight(name='tp', initializer='zeros')

    def update_state(self, y_true, y_pred, sample_weight=None):
        y_pred = tf.argmax(y_pred, axis=1)
        values = tf.cast(y_true, 'int32') == tf.cast(y_pred, 'int32')
        if sample_weight is not None:
            sample_weight = tf.cast(sample_weight, 'float32')
            values = tf.multiply(values, sample_weight)
        self.true_positives.assign_add(tf.reduce_sum(values))

    def result(self):
        return self.true_positives

    def reset_states(self):
        # The state of the metric will be reset at the start of each epoch.
        self.true_positives.assign(0.)

当我编译它时,我得到了这个错误:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-25-3023533c0d6e> in <module>()
      2     model_fn,
      3     client_optimizer_fn=lambda: tf.keras.optimizers.SGD(learning_rate=0.06),
----> 4     server_optimizer_fn=lambda: tf.keras.optimizers.SGD(learning_rate=0.9))

6 frames
/usr/local/lib/python3.7/dist-packages/tensorflow_federated/python/learning/federated_averaging.py in build_federated_averaging_process(model_fn, client_optimizer_fn, server_optimizer_fn, client_weighting, broadcast_process, model_update_aggregation_factory, metrics_aggregator, use_experimental_simulation_loop)
    289       broadcast_process=broadcast_process,
    290       model_update_aggregation_factory=model_update_aggregation_factory,
--> 291       metrics_aggregator=metrics_aggregator)
    292 
    293   server_state_type = iter_proc.state_type.member

/usr/local/lib/python3.7/dist-packages/tensorflow_federated/python/learning/framework/optimizer_utils.py in build_model_delta_optimizer_process(model_fn, model_to_client_delta_fn, server_optimizer_fn, broadcast_process, model_update_aggregation_factory, metrics_aggregator)
    622       broadcast_process=broadcast_process,
    623       aggregation_process=aggregation_process,
--> 624       metrics_aggregator=metrics_aggregator)
    625 
    626   return iterative_process.IterativeProcess(

/usr/local/lib/python3.7/dist-packages/tensorflow_federated/python/learning/framework/optimizer_utils.py in _build_one_round_computation(model_fn, server_optimizer_fn, model_to_client_delta_fn, broadcast_process, aggregation_process, metrics_aggregator)
    366 
    367   @computations.tf_computation(dataset_type, model_weights_type)
--> 368   @tf.function
    369   def _compute_local_training_and_client_delta(dataset, initial_model_weights):
    370     """Performs client local model optimization.

/usr/local/lib/python3.7/dist-packages/tensorflow_federated/python/core/impl/wrappers/computation_wrapper.py in __call__(self, tff_internal_types, *args)
    493       parameter_type = _parameter_type(parameters, parameter_types)
    494       wrapped_func = self._strategy(
--> 495           fn_to_wrap, fn_name, parameter_type, unpack=None)
    496 
    497     # Copy the __doc__ attribute with the documentation in triple-quotes from

/usr/local/lib/python3.7/dist-packages/tensorflow_federated/python/core/impl/wrappers/computation_wrapper.py in __call__(self, fn_to_wrap, fn_name, parameter_type, unpack)
    220     try:
    221       args, kwargs = unpack_arguments_fn(packed_args)
--> 222       result = fn_to_wrap(*args, **kwargs)
    223       if result is None:
    224         raise ComputationReturnedNoneError(fn_to_wrap)

/usr/local/lib/python3.7/dist-packages/tensorflow/python/util/traceback_utils.py in error_handler(*args, **kwargs)
    151     except Exception as e:
    152       filtered_tb = _process_traceback_frames(e.__traceback__)
--> 153       raise e.with_traceback(filtered_tb) from None
    154     finally:
    155       del filtered_tb

/usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/func_graph.py in autograph_handler(*args, **kwargs)
   1145           except Exception as e:  # pylint:disable=broad-except
   1146             if hasattr(e, "ag_error_metadata"):
-> 1147               raise e.ag_error_metadata.to_exception(e)
   1148             else:
   1149               raise

TypeError: in user code:

    File "/usr/local/lib/python3.7/dist-packages/tensorflow_federated/python/learning/framework/optimizer_utils.py", line 382, in _compute_local_training_and_client_delta  *
        client_output = client_delta_fn(dataset, initial_model_weights)
    File "/usr/local/lib/python3.7/dist-packages/tensorflow_federated/python/learning/federated_averaging.py", line 113, in reduce_fn  *
        output = model.forward_pass(batch, training=True)
    File "/usr/local/lib/python3.7/dist-packages/tensorflow_federated/python/learning/framework/dataset_reduce.py", line 33, in _dataset_reduce_fn  *
        return dataset.reduce(initial_state=initial_state_fn(), reduce_func=reduce_fn)
    File "/usr/local/lib/python3.7/dist-packages/tensorflow_federated/python/learning/keras_utils.py", line 455, in forward_pass  *
        return self._forward_pass(batch_input, training=training)
    File "/usr/local/lib/python3.7/dist-packages/tensorflow_federated/python/learning/keras_utils.py", line 443, in _forward_pass  *
        metric.update_state(y_true=y_true, y_pred=predictions)
    File "<ipython-input-17-69c4467a9ad6>", line 20, in decorated  *
        update_op = update_state_fn(*args, **kwargs)
    File "<ipython-input-17-69c4467a9ad6>", line 12, in update_state  *
        self.true_positives.assign_add(tf.reduce_sum(values))

    TypeError: Value passed to parameter 'input' has DataType bool not in list of allowed values: float32, float64, int32, uint8, int16, int8, complex64, int64, qint8, quint8, qint32, bfloat16, uint16, complex128, float16, uint32, uint64

我认为是因为将整个文件传递给了模型。我该如何解决?任何帮助将不胜感激。

问题出在这一行:

values = tf.cast(y_true, 'int32') == tf.cast(y_pred, 'int32')

它正在生成一个布尔值,tf.reduce_sum 不能应用于它:

y_true = [0, 1, 0, 0]
y_pred = [-18.6, 0.51, 2.94, -12.8]

values = tf.cast(y_true, 'int32') == tf.cast(y_pred, 'int32')
print(values)
# tf.Tensor([False False False False], shape=(4,), dtype=bool)
tf.reduce_sum(values) # throws error