Convert Tensor of hex strings to int

Issue

I have a dataset of tf.RaggedTensors with strings representing hexadecimal numbers that look like this:

[
 [[b'F6EE', b'BFED', b'4EEA', b'00EE', b'77AE', b'1FBE', b'1A6E',
   b'5AEB', b'6A0E', b'212F'],
    ...
  [b'FFEE', b'FFED', b'FEED', b'FDEE', b'FAAE', b'FFBE', b'FA8E',
   b'FAEB', b'FA0E', b'E12F']],

  ...

 [[b'FFEE', b'FFED', b'FEED', b'FDEE', b'FAAE', b'FFBE', b'FA8E',
   b'FAEB', b'FA0E', b'E12F'],
    ...
  [b'B6EE', b'BFED', b'4EEA', b'00EE', b'77AE', b'1FBE', b'1A6E',
   b'5AEB', b'6A0E', b'212F']]
]

I want to convert it into Tensor of int values, but tf.strings.to_number(tensor, tf.int32) doesn’t have an option to specify the base as base16. Are there any alternatives?

Dataset contains tf.RaggedTensors, but the target shape is (batch_size, 100, 10). I guess this could be helpful if we were to make a custom function for this.

Solution

I think you’re looking for something like this.

I first create an example tensor with 3D shape, as the one that you have.

import tensorflow as tf

>> a = tf.convert_to_tensor(['F6EE', 'BFED', '4EEA', '00EE', '77AE', '1FBE', '1A6E',
   '5AEB', '6A0E', '212F'])
>> b = tf.convert_to_tensor(['FFEE', 'FFED', 'FEED', 'FDEE', 'FAAE', 'FFBE', 'FA8E',
   'FAEB', 'FA0E', 'E12F'])
>> tensor = tf.ragged.stack([[a, b]]).to_tensor()

tf.Tensor(
[[[b'F6EE' b'BFED' b'4EEA' b'00EE' b'77AE' b'1FBE' b'1A6E' b'5AEB'
   b'6A0E' b'212F']
  [b'FFEE' b'FFED' b'FEED' b'FDEE' b'FAAE' b'FFBE' b'FA8E' b'FAEB'
   b'FA0E' b'E12F']]], shape=(1, 2, 10), dtype=string)

Then, based on this answer, I created a custom function that I map to each value of the tensor in order to apply a transformation, in this case a cast.

def my_cast(t):
    val = tf.keras.backend.get_value(t)
    return int(val, 16)

shape = tf.shape(tensor)
elems = tf.reshape(tensor, [-1])

res = tf.map_fn(fn=lambda t: my_cast(t), elems=elems, fn_output_signature=tf.int32)
res = tf.reshape(res, shape)

print(res)

The output is the tensor:

tf.Tensor(
    [[[63214 49133 20202   238 30638  8126  6766 23275 27150  8495]
      [65518 65517 65261 65006 64174 65470 64142 64235 64014 57647]]], 
    shape=(1, 2, 10), 
    dtype=int32
)

Adding fn_output_signature=tf.int32 to tf.map_fn is important because it lets you obtain a tensor with a different type with respect to the input tensor.

Answered By – ClaudiaR

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published