I created a Huggingface model and a function to make predictions. Here is the prediction function I wrote (which is working fine)
def predict_proba(text_list, model, tokenizer):
#tokenize the text
encodings = tokenizer(text_list,
max_length=512,
truncation=True,
padding=True)
#transform to tf.Dataset
dataset = tf.data.Dataset.from_tensor_slices((dict(encodings)))
#predict
preds = model.predict(dataset.batch(1))['logits']
#transform to array with probabilities
res = tf.nn.softmax(preds, axis=1).numpy()
return res
Now If do
pred = predict_proba(x_test_list, model, tokenizer)
Its working fine . But when I save the model
path = '/Shared/P1-Prediction/savedmodels'
model.save(path)
And then I load it at a later point of time to make predictions
loadedmodel = keras.models.load_model(path)
and now If I try to make predictions using this new loadedmodel
pred = predict_proba(x_test_list, loadedmodel , tokenizer)
I am getting the below error. I dont understand why. this loadedmodel and model are exact same things . infact the model.summary() and loadedmodel.summary() look exactly the same. The error I get is as follows and I don't get this error with the original model.I am not able to understand this error and any help is highly highly appreciated.
ValueError: in user code:
File "/databricks/python/lib/python3.8/site-packages/keras/engine/training.py", line 1801, in predict_function *
return step_function(self, iterator)
File "/databricks/python/lib/python3.8/site-packages/keras/engine/training.py", line 1790, in step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
File "/databricks/python/lib/python3.8/site-packages/keras/engine/training.py", line 1783, in run_step **
outputs = model.predict_step(data)
File "/databricks/python/lib/python3.8/site-packages/keras/engine/training.py", line 1751, in predict_step
return self(x, training=False)
File "/databricks/python/lib/python3.8/site-packages/keras/utils/traceback_utils.py", line 67, in error_handler
raise e.with_traceback(filtered_tb) from None
ValueError: Exception encountered when calling layer "tf_distil_bert_for_sequence_classification" (type TFDistilBertForSequenceClassification).
Could not find matching concrete function to call loaded from the SavedModel. Got:
Positional arguments (9 total):
* {'attention_mask': <tf.Tensor 'input_ids:0' shape=(None, 512) dtype=int32>, 'input_ids': <tf.Tensor 'input_ids_1:0' shape=(None, 512) dtype=int32>}
* None
* None
* None
* None
* None
* None
* None
* False
Keyword arguments: {}
Expected these arguments to match one of the following 2 option(s):
Option 1:
Positional arguments (9 total):
* {'input_ids': TensorSpec(shape=(None, 5), dtype=tf.int32, name='input_ids/input_ids')}
* None
* None
* None
* None
* None
* None
* None
* False
Keyword arguments: {}
Option 2:
Positional arguments (9 total):
* {'input_ids': TensorSpec(shape=(None, 5), dtype=tf.int32, name='input_ids/input_ids')}
* None
* None
* None
* None
* None
* None
* None
* True
Keyword arguments: {}
Call arguments received:
• args=({'attention_mask': 'tf.Tensor(shape=(None, 512), dtype=int32)', 'input_ids': 'tf.Tensor(shape=(None, 512), dtype=int32)'},)
• kwargs={'training': 'False'}
I really wish I can make this issue more reproducible by sharing the code which I can but without the data it wont be reproducible. Any help is really appreciated.
Related
I am working on building a LSTM model on M5 Forecasting Challenge (a Kaggle dataset)
I using functional keras API to build my model. I have attached picture of my model. Input is generated using 'tf.keras.utils.timeseries_dataset_from_array' and the error I receive is
ValueError: Layer "model_4" expects 18 input(s), but it received 1 input tensors. Inputs received: [<tf.Tensor 'IteratorGetNext:0' shape=(None, None, 18) dtype=float32>]
This is the code I am using to generate a time series dataset.
dataset = tf.keras.utils.timeseries_dataset_from_array(data=array, targets=None,
sequence_length=window, sequence_stride=1, batch_size=32)
My NN model
input_tensors = {}
for col in train_sel.columns:
if col in cat_cols:
input_tensors[col] = layers.Input(name = col, shape=(1,),dtype=tf.string)
else:
input_tensors[col]=layers.Input(name = col, shape=(1,), dtype = tf.float16
embedding = []
for feature in input_tensors:
if feature in cat_cols:
embed = layers.Embedding(input_dim = train_sel[feature].nunique(), output_dim = int(math.sqrt(train_sel[feature].nunique())))
embed = embed(input_tensors[feature])
else:
embed = layers.BatchNormalization()
embed = embed(tf.expand_dims(input_tensors[feature], -1))
embedding.append(embed)
temp = embedding
embedding = layers.concatenate(inputs = embedding)
nn_model = layers.LSTM(128)(embedding)
nn_model = layers.Dropout(0.1)(nn_model)
output = layers.Dense(1, activation = 'tanh')(nn_model)
model = tf.keras.Model(inputs=split_input,outputs = output)
Presently, I am fitting the model using
model.compile(
optimizer=tf.keras.optimizers.Adam(learning_rate=0.01),
loss=tf.keras.losses.MeanSquaredError(),
metrics=[tf.keras.losses.MeanSquaredError()])
model.fit(dataset,epochs = 5)
I am receiving a value error
ValueError: in user code:
File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1051, in train_function *
return step_function(self, iterator)
File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1040, in step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 1030, in run_step **
outputs = model.train_step(data)
File "/usr/local/lib/python3.8/dist-packages/keras/engine/training.py", line 889, in train_step
y_pred = self(x, training=True)
File "/usr/local/lib/python3.8/dist-packages/keras/utils/traceback_utils.py", line 67, in error_handler
raise e.with_traceback(filtered_tb) from None
File "/usr/local/lib/python3.8/dist-packages/keras/engine/input_spec.py", line 200, in assert_input_compatibility
raise ValueError(f'Layer "{layer_name}" expects {len(input_spec)} input(s),'
ValueError: Layer "model_4" expects 18 input(s), but it received 1 input tensors. Inputs received: [<tf.Tensor 'IteratorGetNext:0' shape=(None, None, 18) dtype=float32>]
I am working on a multi-label image classification problem with 13 labels. I want to use Hamming Loss to evaluate the performance of the model. So I specified tfa.metrics.HammingLoss(mode = 'multilabel') in the metrics parameter during model compilation. This worked when I provided both X_train and y_train to model.fit(), but it threw a ValueError when I used a Sequence object (described below) for training.
Data Generator description
I used a keras.utils.Sequence input object similar to what is present here. The generator returns 2 numpy arrays for each batch - the first array consists of the input images of shape (128, 128, 3) and the second array consists of labels each of shape (13,).
This is what my code looks like:
model.compile(
loss='binary_crossentropy',
optimizer='rmsprop',
metrics=[tfa.metrics.HammingLoss(mode = 'multilabel')]
)
model.fit(
train_datagen,
epochs = 5,
batch_size = BATCH_SIZE,
steps_per_epoch = TOTAL // BATCH_SIZE
)
And this is the error that I obtained:
Epoch 1/5
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-140-978987a2bbaa> in <module>
3 epochs=5,
4 batch_size=BATCH_SIZE,
----> 5 steps_per_epoch = 2000 // BATCH_SIZE
6 # validation_data=validation_generator,
7 )
4 frames
/usr/local/lib/python3.7/dist-packages/tensorflow_addons/metrics/hamming.py in else_body_2()
64 try:
65 do_return = True
---> 66 retval_ = (ag__.ld(nonzero) / ag__.converted_call(ag__.ld(y_true).get_shape, (), None, fscope)[(- 1)])
67 except:
68 do_return = False
ValueError: in user code:
File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1051, in train_function *
return step_function(self, iterator)
File "/usr/local/lib/python3.7/dist-packages/tensorflow_addons/metrics/utils.py", line 66, in update_state *
matches = self._fn(y_true, y_pred, **self._fn_kwargs)
File "/usr/local/lib/python3.7/dist-packages/tensorflow_addons/metrics/hamming.py", line 133, in hamming_loss_fn *
return nonzero / y_true.get_shape()[-1]
ValueError: None values not supported.
How do I correct this? Is there any issue with the format of the labels?
I get this error this error after few step of training of an RL script for trading
ValueError: in user code:
File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1801, in predict_function *
return step_function(self, iterator)
File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1790, in step_function **
outputs = model.distribute_strategy.run(run_step, args=(data,))
File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1783, in run_step **
outputs = model.predict_step(data)
File "/usr/local/lib/python3.7/dist-packages/keras/engine/training.py", line 1751, in predict_step
return self(x, training=False)
File "/usr/local/lib/python3.7/dist-packages/keras/utils/traceback_utils.py", line 67, in error_handler
raise e.with_traceback(filtered_tb) from None
File "/usr/local/lib/python3.7/dist-packages/keras/engine/input_spec.py", line 264, in assert_input_compatibility
raise ValueError(f'Input {input_index} of layer "{layer_name}" is '
ValueError: Input 0 of layer "sequential" is incompatible with the layer: expected shape=(None, 66), found shape=(None, 67)
The first part of code define an array from a pandas df of OHLC forex price:
def _get_normalised_bars_array(bars):
bars = bars.iloc[-10:, :-1].values.flatten()
"""Normalizing candlesticks"""
bars = (bars-np.mean(bars))/np.std(bars)
return bars
self.state = np.append(self.state, _get_normalised_bars_array(self.last5m))
After that I create a pands df of features, I find the correlation and I create a df that I transform in np.array.flatten ana attache to the previous "self.state" array
correlation_ret = bars.corrwith(bars["returns_dir"]).sort_values(ascending=False)
correlation_sel = correlation_ret.loc[(correlation_ret >= 0.55) & (correlation_ret < 1)].drop_duplicates(keep='last')
df_correlation_sel = correlation_sel.to_frame().T
columns = df_correlation_sel.columns.tolist()
delete_element = ['open', 'high', 'low', 'close']
for i in delete_element:
if i in columns_def:
columns_def.remove(i)
bars = bars[columns_def].iloc[-1:, :-3].to_numpy().flatten()
return bars
self.state = np.append(self.state, _get_tsfresh_features(self.last5m))
My DDQN network is the following:
def init_net(env, rl_config):
"""
This initialises the RL run by
creating two new predictive neural network
Args:
env:
Returns:
modelQ: the neural network
modelR: the neural network
"""
hidden_size = len(env.state)*rl_config['HIDDEN_MULT']
modelQ = Sequential()
modelQ.add(Dense(len(env.state), input_shape=(
len(env.state),), activation=rl_config['ACTIVATION_FUN']))
modelQ.add(Dense(hidden_size, activation=rl_config['ACTIVATION_FUN']))
modelQ.add(Dense(rl_config['NUM_ACTIONS'], activation='softmax'))
modelQ.compile(SGD(lr=rl_config['LEARNING_RATE']), loss=rl_config['LOSS_FUNCTION'])
modelR = Sequential()
modelR.add(Dense(len(env.state), input_shape=(
len(env.state),), activation=rl_config['ACTIVATION_FUN']))
modelR.add(Dense(hidden_size, activation=rl_config['ACTIVATION_FUN']))
modelR.add(Dense(rl_config['NUM_ACTIONS'], activation='softmax'))
modelR.compile(SGD(lr=rl_config['LEARNING_RATE']), loss=rl_config['LOSS_FUNCTION'])
return modelQ, modelR
then I get the error exposed above with the following details:
Error Message Image
the Error doesn't appear if I exclude the "Technical Indicators" section.
How can I solve it? Is it due to the variable length of "Technical Indicators" array during the training?
After a few tests I've tried to lock the number of features and consequently the input shape. It works fine now, it seems that a variable number of inputs is not allowed
The following code is giving me an error which I cannot find the answer to. I am trying to apply a python function to each element of a tensor, which transforms the element into a vector of shape 3, so I can calculate a custom evaluation metric. It needs to be a Python function as it is used in other places too.
The error (log below) is Invalid argument: PartialTensorShape: Incompatible ranks during merge: 1 vs. 0, and I assume it has to do with the result of map_fn and its shape. However, it only happens at runtime as if I have any other shape then it throws an error with incompatible shapes when I do model.compile(). Have I misundertood how to use map_fn? Any suggestions?
Thanks in advance!
2021-04-09 12:19:31.357542: W tensorflow/core/framework/op_kernel.cc:1767] OP_REQUIRES failed at list_kernels.h:101 : Invalid argument: PartialTensorShape: Incompatible ranks during merge: 1 vs. 0
Traceback (most recent call last):
File "test.py", line 93, in <module>
validation_data=(val_input, val_output))
File "/home/user/anaconda3/envs/tf_models/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 108, in _method_wrapper
return method(self, *args, **kwargs)
File "/home/user/anaconda3/envs/tf_models/lib/python3.6/site-packages/tensorflow/python/keras/engine/training.py", line 1098, in fit
tmp_logs = train_function(iterator)
File "/home/user/anaconda3/envs/tf_models/lib/python3.6/site-packages/tensorflow/python/eager/def_function.py", line 780, in __call__
result = self._call(*args, **kwds)
File "/home/user/anaconda3/envs/tf_models/lib/python3.6/site-packages/tensorflow/python/eager/def_function.py", line 840, in _call
return self._stateless_fn(*args, **kwds)
File "/home/user/anaconda3/envs/tf_models/lib/python3.6/site-packages/tensorflow/python/eager/function.py", line 2829, in __call__
return graph_function._filtered_call(args, kwargs) # pylint: disable=protected-access
File "/home/user/anaconda3/envs/tf_models/lib/python3.6/site-packages/tensorflow/python/eager/function.py", line 1848, in _filtered_call
cancellation_manager=cancellation_manager)
File "/home/user/anaconda3/envs/tf_models/lib/python3.6/site-packages/tensorflow/python/eager/function.py", line 1924, in _call_flat
ctx, args, cancellation_manager=cancellation_manager))
File "/home/user/anaconda3/envs/tf_models/lib/python3.6/site-packages/tensorflow/python/eager/function.py", line 550, in call
ctx=ctx)
File "/home/user/anaconda3/envs/tf_models/lib/python3.6/site-packages/tensorflow/python/eager/execute.py", line 60, in quick_execute
inputs, attrs, num_outputs)
tensorflow.python.framework.errors_impl.InvalidArgumentError: 2 root error(s) found.
(0) Invalid argument: PartialTensorShape: Incompatible ranks during merge: 1 vs. 0
[[node map/TensorArrayV2Stack/TensorListStack (defined at test.py:27) ]]
[[map_1/while/LoopCond/_50/_64]]
(1) Invalid argument: PartialTensorShape: Incompatible ranks during merge: 1 vs. 0
[[node map/TensorArrayV2Stack/TensorListStack (defined at test.py:27) ]]
0 successful operations.
0 derived errors ignored. [Op:__inference_train_function_823]
Function call stack:
train_function -> train_function
This is the code to reproduce the issue, using Tensorflow 2.3.1 and Python 3.6.
from typing import List
import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Dense, Input, Flatten
INPUT_SHAPE = (2, 10, 10)
class CustomMetric(tf.keras.metrics.Metric):
def __init__(self, name='custom_metric', **kwargs):
super().__init__(name=name, **kwargs)
self.mean_custom_metric = self.add_weight(name='mean_custom_metric', initializer='zeros', dtype=float)
def update_state(self, y_true, y_pred, sample_weight=None):
# y_true is a probability distribution (batch, 2*10*10), so find index of most likely position
y_pred = tf.argmax(y_pred, axis=1)
# y_pred and y_true are both tensors with shape (batch, 1)
print(f"y_pred: {y_pred}")
# apply python func to convert each value to a 3D value (single scalar to vector with 3 scalars)
# according to docs: map_fn(fn, elems).shape = [elems.shape[0]] + fn(elems[0]).shape.
# So: elems.shape[0] == batch | fn(elems[0]).shape == 3,
# error happens when trying to do anything with the result of map_fn below
y_true_positions = tf.map_fn(self.wrapper, y_true, fn_output_signature=tf.float32)
y_pred_positions = tf.map_fn(self.wrapper, y_pred, fn_output_signature=tf.float32)
# y_true_positions, y_pred_positions: tensors with shape (batch, 3)
print(f"y_true_positions: {y_true_positions}")
# do something with y_true_positions and y_pred_positions
y_final = y_true_positions
mean = tf.reduce_sum(y_final)
print('---')
self.mean_custom_metric.assign(mean)
def result(self):
return self.mean_custom_metric
def reset_states(self):
self.mean_custom_metric.assign(0.0)
def wrapper(self, x):
# x: tensor with shape (1,)
print(f"x: {x}")
result = tf.py_function(python_function, [int(x)], tf.float32)
# result is a tensor of shape unknown
print(f"result: {result}")
result.set_shape(tf.TensorShape(3))
# result: tensor with shape (3,)
print(f"result: {result}")
return result
def python_function(index: int) -> List[float]:
# dummy function
return [0, 0, 0]
# dummy model
block_positions = Input(shape=(*INPUT_SHAPE, 1), dtype=tf.float32)
block_positions_layer = Flatten()(block_positions)
target_output_layer = Dense(128, activation='relu')(block_positions_layer)
target_output = Dense(np.prod(INPUT_SHAPE), activation='softmax', name='regions')(target_output_layer)
model = tf.keras.models.Model(
inputs=[block_positions],
outputs=(target_output))
custom_metric = CustomMetric()
model.compile(
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
optimizer=tf.optimizers.Adam(learning_rate=0.001),
metrics=['accuracy', custom_metric])
print(model.summary())
# placeholder data
train_input = np.zeros(shape=(100, *INPUT_SHAPE), dtype=np.float32)
train_output = np.zeros(shape=(100, 1), dtype=np.int32)
val_input = np.zeros(shape=(100, *INPUT_SHAPE), dtype=np.float32)
val_output = np.zeros(shape=(100, 1), dtype=np.int32)
history = model.fit(
train_input, train_output, epochs=10, verbose=1,
validation_data=(val_input, val_output))
I found the solution after a while. The wrapper function was returning a tensor of shape (3,), whereas the map_fn was applied over a tensor of shape (batch, 1). I don't fully understand why, but it seems that map_fn requires a return tensor of shape (batch, 1,) and not fn(elems[0]).shape as the documentation suggests.
Changing the line:
result.set_shape(tf.TensorShape(3))
for
result = tf.reshape(tf.concat(result, 1), (1, 3)) in wrapper
so that the return value is (1, 3) instead of (3) fixed the issue. After map_fn, you end up with a tensor of shape (batch, 1, 3), which I reshaped to be (batch, 3).
I'm trying to federate a keras model which has multiple outputs. There are two separate dense layers that perform a binary classification and a multi-class classification. I am getting the following ValueError when I try to build my federated averaging process tff.learning.build_federated_averaging_process from model_fn(). Following are the code snippets and error information. I am unable to understand what is going wrong and how to resolve it.
ValueError: in user code:
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow_federated/python/learning/framework/optimizer_utils.py:387 _compute_local_training_and_client_delta *
client_output = client_delta_fn(dataset, initial_model_weights)
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow_federated/python/learning/federated_averaging.py:92 reduce_fn *
output = model.forward_pass(batch, training=True)
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow_federated/python/learning/framework/dataset_reduce.py:28 _dataset_reduce_fn *
return dataset.reduce(initial_state=initial_state_fn(), reduce_func=reduce_fn)
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow_federated/python/learning/keras_utils.py:365 forward_pass *
return self._forward_pass(batch_input, training=training)
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow_federated/python/learning/keras_utils.py:357 _forward_pass *
metric.update_state(y_true=y_true, y_pred=predictions)
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow/python/keras/utils/metrics_utils.py:90 decorated **
update_op = update_state_fn(*args, **kwargs)
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow/python/keras/metrics.py:176 update_state_fn
return ag_update_state(*args, **kwargs)
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow/python/keras/metrics.py:604 update_state **
y_pred = math_ops.cast(y_pred, self._dtype)
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow/python/util/dispatch.py:201 wrapper
return target(*args, **kwargs)
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow/python/ops/math_ops.py:920 cast
x = ops.convert_to_tensor(x, name="x")
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow/python/framework/ops.py:1499 convert_to_tensor
ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow/python/ops/array_ops.py:1502 _autopacking_conversion_function
return _autopacking_helper(v, dtype, name or "packed")
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow/python/ops/array_ops.py:1438 _autopacking_helper
return gen_array_ops.pack(elems_as_tensors, name=scope)
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow/python/ops/gen_array_ops.py:6477 pack
"Pack", values=values, axis=axis, name=name)
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow/python/framework/op_def_library.py:744 _apply_op_helper
attrs=attr_protos, op_def=op_def)
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow/python/framework/func_graph.py:593 _create_op_internal
compute_device)
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow/python/framework/ops.py:3485 _create_op_internal
op_def=op_def)
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow/python/framework/ops.py:1975 __init__
control_input_ops, op_def)
/home/usr/Envs/tf-fed/lib/python3.7/site-packages/tensorflow/python/framework/ops.py:1815 _create_c_op
raise ValueError(str(e))
ValueError: Dimension 1 in both shapes must be equal, but are 1 and 3. Shapes are [?,1] and [?,3].
From merging shape 0 with other shapes. for '{{node Cast_1/x}} = Pack[N=2, T=DT_FLOAT, axis=0](functional_1/eye_output/Sigmoid, functional_1/mouth_output/Softmax)' with input shapes: [?,1], [?,3].
My model_fn() looks like this:
def model_fn():
losses = [tf.keras.losses.BinaryCrossentropy(), tf.keras.losses.SparseCategoricalCrossentropy()]
metrics = [tf.keras.metrics.BinaryAccuracy(),tf.keras.metrics.SparseCategoricalAccuracy()]
keras_model = build_model()
return tff.learning.from_keras_model(
keras_model,
input_spec=spec,
loss=losses,
metrics=metrics)
where build_model() creates the keras model:
build_model():
...
out1 = Dense(1, activation='sigmoid')(fc1)
out2 = Dense(3, activation='softmax')(fc2)
model = Model(inputs=inputs, outputs=[out1, out2])
return model
And input_specification that looks like this
OrderedDict([('x',
TensorSpec(shape=(None, 240, 320), dtype=tf.float32, name=None)),
('y',
(TensorSpec(shape=(None, 1), dtype=tf.int64, name=None),
TensorSpec(shape=(None, 1), dtype=tf.int64, name=None)))])
How can I build my TFF fedAvg process using such a model?
This seems like it might be from the metrics arguments, based on reading this line in the stack trace:
tensorflow_federated/python/learning/keras_utils.py:357 _forward_pass *
metric.update_state(y_true=y_true, y_pred=predictions)
I suspect BinaryAccuracy and SparseCategoricalAccuracy are being applied to both outputs, but the metrics only operate on specific shaped tensors (code here). In particular it appears to be trying to pass both outputs to the metric at once.
This leads me to believe that TFF does not support different metrics on different outputs for multi-output models defined using Keras. This could be a good candidate for a PR or Issue at https://github.com/tensorflow/federated/issues.