Tensorflow tf.map_fn `TypeError: Expected binary or unicode string, got array`

  keras, numpy, python, tensorflow

(I know the title is a little generic but I don’t know what else to name this question)

In attempting to train a neural network with a custom loss function I’ve encountered the error TypeError: Expected binary or unicode string, got array.

Looking at this multiple times and checking through my code I cannot see where I have gone wrong, I would really appreciate any help here.

Live example and the code:

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np

# An array of [image,target image], for this example I've simplified it
sizes = [[10,10],[20,20],[15,15],[25,30],[5,9],[80,33],[54,78]]
images = [
  [np.random.rand(s[0],s[1]).astype("float32"), np.random.rand(s[0],s[1]).astype("float32")] 
  for s in sizes
]
images = np.array(images,dtype=object)
print(images.shape)

def binarize_image(image, params):
  extreme_luma_boundary = params[0]
  # If the value is very close to 0 or 255
  def extreme_fn(elem):
    if elem < extreme_luma_boundary:
      return 0.0
    elif elem > 255 - extreme_luma_boundary:
      return 255.0
    else:
      return elem

  extreme_luma = tf.map_fn(lambda e: tf.map_fn(extreme_fn,e),image)
  return extreme_luma

def mean_squared_error(x):
  return (tf.reduce_mean(tf.square(tf.subtract(x[0], binarize_image(x[1], x[2])))),0,0)
def custom_loss(images, binary_images):
  # `y_true` is useless, `y_pred` should be [uint8]
  def loss(y_true, y_pred):
    # Gets MSE of each image
    mse = tf.map_fn(mean_squared_error, (binary_images, images, y_pred))[0]
    # Gets average MSE
    return tf.reduce_mean(mse)
  return loss

# Actual model has more inputs and outputs, this is just simplified for example.
bin_param_model = keras.Sequential([
  layers.InputLayer(input_shape=(2,)),
  layers.Dense(625, activation="relu"),
  layers.Dropout(0.2),
  layers.Dense(125, activation="relu"),
  layers.Dropout(0.2),
  layers.Dense(25, activation="relu"),
  layers.Dropout(0.2),
  layers.Dense(1)
])

print(images.shape)
bin_param_model.compile(loss=custom_loss(images[:,0],images[:,1]), optimizer="adam",metrics=["accuracy"])

# Given this is not used, can we not pass this?
y_temp = np.zeros((input_arr.shape[0],1), dtype="float32")
print(input_arr.shape,"->",y_temp.shape)
print(input_arr.dtype,"->",y_temp.dtype)
bin_param_model.fit(x=input_arr, y=y_temp, batch_size=BATCH_SIZE, epochs=EPOCHS)

The full error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-171-d16920633be1> in <module>()
      3 print(input_arr.shape,"->",y_temp.shape)
      4 print(input_arr.dtype,"->",y_temp.dtype)
----> 5 bin_param_model.fit(x=input_arr, y=y_temp, batch_size=BATCH_SIZE, epochs=EPOCHS)

9 frames
/usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/func_graph.py in wrapper(*args, **kwargs)
    984           except Exception as e:  # pylint:disable=broad-except
    985             if hasattr(e, "ag_error_metadata"):
--> 986               raise e.ag_error_metadata.to_exception(e)
    987             else:
    988               raise

TypeError: in user code:

    /usr/local/lib/python3.7/dist-packages/tensorflow/python/keras/engine/training.py:855 train_function  *
        return step_function(self, iterator)
    <ipython-input-41-1c4e62f15369>:7 loss  *
        mse = tf.map_fn(mean_squared_error,(binary_images,images,y_pred))[0]
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/util/deprecation.py:602 new_func  **
        return func(*args, **kwargs)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/util/deprecation.py:535 new_func
        return func(*args, **kwargs)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/map_fn.py:651 map_fn_v2
        name=name)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/util/deprecation.py:535 new_func
        return func(*args, **kwargs)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/map_fn.py:418 map_fn
        ops.convert_to_tensor_or_composite(t, name="elem") for t in elems_flat
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/ops/map_fn.py:418 <listcomp>
        ops.convert_to_tensor_or_composite(t, name="elem") for t in elems_flat
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/ops.py:1689 convert_to_tensor_or_composite
        value=value, dtype=dtype, name=name, as_ref=False)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/ops.py:1728 internal_convert_to_tensor_or_composite
        accepted_result_types=(Tensor, composite_tensor.CompositeTensor))
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/profiler/trace.py:163 wrapped
        return func(*args, **kwargs)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/ops.py:1566 convert_to_tensor
        ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/tensor_conversion_registry.py:52 _default_conversion_function
        return constant_op.constant(value, dtype, name=name)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/constant_op.py:265 constant
        allow_broadcast=True)
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/constant_op.py:283 _constant_impl
        allow_broadcast=allow_broadcast))
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/framework/tensor_util.py:564 make_tensor_proto
        append_fn(tensor_proto, proto_values)
    tensorflow/python/framework/fast_tensor_util.pyx:127 tensorflow.python.framework.fast_tensor_util.AppendObjectArrayToTensorProto
        
    /usr/local/lib/python3.7/dist-packages/tensorflow/python/util/compat.py:87 as_bytes
        (bytes_or_text,))

    TypeError: Expected binary or unicode string, got array([[0.3708436 , 0.273628  , 0.85551167, 0.31498218, 0.3828464 ,
            0.76416665, 0.4608041 , 0.80451405, 0.978937  , 0.9616637 ],
           [0.69154716, 0.9528596 , 0.13822418, 0.21962982, 0.7007309 ,
            0.47694248, 0.28868306, 0.08779896, 0.36212742, 0.06124286],
           [0.9394008 , 0.65731245, 0.30748397, 0.97992855, 0.4047509 ,
            0.19440095, 0.85488856, 0.5276741 , 0.78735834, 0.6793549 ],
           [0.36192748, 0.89441717, 0.8655567 , 0.8142468 , 0.45290884,
            0.85871464, 0.3810781 , 0.97054464, 0.09471539, 0.9191041 ],
           [0.96772945, 0.21954712, 0.8076186 , 0.57447   , 0.8913575 ,
            0.7951947 , 0.04163739, 0.76690865, 0.14838892, 0.3646785 ],
           [0.79908353, 0.7708255 , 0.64932877, 0.29521045, 0.01199513,
            0.6691519 , 0.31242362, 0.56586903, 0.35160235, 0.73782194],
           [0.01625271, 0.8637356 , 0.92600924, 0.67533934, 0.0166781 ,
            0.71028876, 0.46053496, 0.98303723, 0.19478427, 0.6498143 ],
           [0.27523398, 0.4680294 , 0.53886676, 0.854011  , 0.6059636 ,
            0.41213104, 0.95060736, 0.5366922 , 0.6755187 , 0.42585388],
           [0.8287889 , 0.30330795, 0.9765252 , 0.8087933 , 0.89739794,
            0.12891938, 0.60768914, 0.851281  , 0.0300381 , 0.6945736 ],
           [0.25339052, 0.44093215, 0.27894568, 0.00986656, 0.18557529,
            0.0335553 , 0.9011967 , 0.45136884, 0.8949942 , 0.03440449]],
          dtype=float32)

Source: Python Questions

LEAVE A COMMENT