Как построить модель с использованием нескольких функций в Tensorflow Federated?

У меня есть следующие коды и проблема при попытке создать OrderedDict для нескольких входов функций (то есть функций a-g) и одной метки h.


def preprocess(dataset):

  def batch_format_fn(element):

    return collections.OrderedDict(
        x=collections.OrderedDict(
            a=tf.TensorSpec(shape=[None,], dtype=tf.int32),
            b=tf.TensorSpec(shape=[None,], dtype=tf.int32),
            c=tf.TensorSpec(shape=[None,], dtype=tf.int32),
            d=tf.TensorSpec(shape=[None,], dtype=tf.int32),
            e=tf.TensorSpec(shape=[None,], dtype=tf.int32),
            f=tf.TensorSpec(shape=[None,], dtype=tf.int32),
            g=tf.TensorSpec(shape=[None,], dtype=tf.int32)),
        y=tf.TensorSpec(shape=[None,], dtype=tf.int32))
  return dataset.map(batch_format_fn).prefetch(PREFETCH_BUFFER)

preprocessed_sample_dataset = preprocess(example_dataset)

def create_keras_model():
    model = Sequential([
    feature_layer,
    Dense(64, activation='relu'),
    Dense(64, activation='relu'),
    Dense(3, activation='softmax') #classification 3 outputs
    ])
    return model

def model_fn():

  keras_model = create_keras_model()
  return tff.learning.from_keras_model(
      keras_model,
      input_spec=preprocessed_sample_dataset.element_spec,
      loss=losses.SparseCategoricalCrossentropy(),
      metrics=[metrics.SparseCategoricalAccuracy()])

Он показывает такую ​​ошибку при выполнении input_spec=preprocessed_sample_dataset.element_spec:

TypeError: Unsupported return value from function passed to Dataset.map(): OrderedDict([('x', OrderedDict([('a', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), ('b', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), ('c', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), ('d', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), ('e', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), ('f', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), ('g', TensorSpec(shape=(None,), dtype=tf.int32, name=None))])), ('y', TensorSpec(shape=(None,), dtype=tf.int32, name=None))]).

Я прочитал это альтернативное решение, однако непонятно, как это реализовать в моем случае. Следовательно, как правильно назначить упорядоченный dict для нескольких функций в TFF?

Текущий example_dataset.element_spec выглядит следующим образом:

OrderedDict([
('a', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), 
('b', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), 
('c', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), 
('d', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), 
('e', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), 
('f', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), 
('g', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), 
('y', TensorSpec(shape=(None,), dtype=tf.int32, name=None))])

Я хочу, чтобы element_spec стал таким:

OrderedDict([('x', OrderedDict([
('a', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), 
('b', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), 
('c', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), 
('d', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), 
('e', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), 
('f', TensorSpec(shape=(None,), dtype=tf.int32, name=None)), 
('g', TensorSpec(shape=(None,), dtype=tf.int32, name=None))])), 
('y', TensorSpec(shape=(None,), dtype=tf.int32, name=None))])

Как сделать element_spec последним, используя batch_format_fn?


person tfreak    schedule 14.07.2020    source источник
comment
Глядя на batch_format_fn, похоже, что возвращаемое значение не зависит от аргумента element; Я подозреваю, что вы получите ту же ошибку, если просто перебираете набор данных. Может быть, возвращенный OrderedDict должен изменить element?   -  person Keith Rush    schedule 15.07.2020
comment
@KeithRush, как возвращенный OrderedDict может изменить форму элемента?   -  person tfreak    schedule 15.07.2020
comment
Можете дать развернутый ответ ниже, но можете ли вы обновить вопрос с помощью свойства element_spec example_dataset? Я считаю, что нам это понадобится, чтобы понять, как изменить   -  person Keith Rush    schedule 15.07.2020
comment
@KeithRush Я обновил вопрос с помощью element_spec   -  person tfreak    schedule 16.07.2020


Ответы (1)


batch_format_fn в настоящее время возвращает структуру тензорных типов; tf.data.Dataset.map ожидает получить структуру тензоров в качестве возвращаемого значения функции.

Мы должны обновить batch_format_fn, чтобы переформатировать его аргумент element и вместо этого вернуть его. Попробуем что-нибудь вроде:

def batch_format_fn(element):
  feature_dict = collections.OrderedDict(
      a=element['a'],
      b=element['b'],
      c=element['c'],
      d=element['d'],
      e=element['e'],
      f=element['f'],
      g=element['g'],
  )
  return collections.OrderedDict(x=feature_dict, y=element['y'])

и сохраняя все остальное без изменений.

person Keith Rush    schedule 16.07.2020
comment
Я снова обновил свой вопрос. Текущий element_spec отсутствует ('x', OrderedDict([. Я хочу, чтобы текущий element_spec был таким же, как input_spec, чтобы он работал. На самом деле я пытаюсь использовать batch_format_fn (self), но все равно возникает та же ошибка. Как это обойти? Поскольку мне нужно включить .map(batch_format_fn) - person tfreak; 16.07.2020