0

I'm learning Tensorflow 2.10, with Python 3.7.7.

I'm trying to use the tutorial "Tensorflow - Custom training: walkthrough" to use my own loss function.

This is my first version of loss function, and it works:

def loss(model, x, y):
  output = model(x)
  return tf.norm(y - output)

I have changed to try another one, and it doesn't work:

def my_loss(model, x, y):
  output = model(x)

  # Only valid values for output var are 0.0 and 1.0.
  output_np = np.array(output)
  output_np[output_np >= 0.5] = 1.0
  output_np[output_np < 0.5] = 0.0

  # Counts how many 1.0 are on y var.
  unique, counts = np.unique(y, return_counts=True)
  dict_wmh = dict(zip(unique, counts))  
  wmh_count = 0
  if 1.0 in dict_wmh:
    wmh_count = dict_wmh[1.0]

  # Add y and output to get another array.
  c = y + output_np
  unique, counts = np.unique(c, return_counts=True)
  dict_net = dict(zip(unique, counts))

  # Counts how many 2.0 are on this new array.
  net_count = 0
  if 2.0 in dict_net:
    net_count = dict_net[2.0]

  # Return the different between the number of ones in the label and the network output.
  return wmh_count - net_count

But I can use it because my new loss function "interrupts the gradient chain registered by the gradient tape".

So, I have tried to use only Tensorflow Tensor:

def my_loss_tensor(model, x, y):
  output = model(x)

  # Only valid values for output var are 0.0 and 1.0.
  output = tf.math.round(output)
  output = tf.clip_by_value(output, clip_value_min=0.0, clip_value_max=1.0)

  # Counts how many 1.0 are on y var (WMH mask).
  y_ele, y_idx, y_count = tf.unique_with_counts(y)

  # Add output to WMH mask.
  sum = tf.math.add(output, y)

  # Counts how many 2.0 are on the sum.
  sum_ele, sum_idx, sum_count = tf.unique_with_counts(sum)

  return tf.math.subtract(sum_count[sum_ele == 1.0], y_count[y_ele == 2.0])

x is a tf.Tensor([[[[...]]]], shape=(1, 200, 200, 1), dtype=float32) y is a tf.Tensor([[[[...]]]], shape=(1, 200, 200, 1), dtype=float32)

They are images (200x200x1).

I get the following error:

unique expects a 1D vector. [Op:UniqueWithCounts]

Any idea about how to count how many times appear a value on a Tensor?

The real image data are on the 200x200 dimensions, the other two are used on my CNN.

VansFannel
  • 45,055
  • 107
  • 359
  • 626

1 Answers1

1

You can use tf.reshape() method inside the loss to convert it to 1d vector:

out_flat = tf.reshape(output,[-1])
y_ele, y_idx, y_count = tf.unique_with_counts(out_flat)
Tolik
  • 425
  • 4
  • 12