diff --git a/src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs b/src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs
index 2032374a..e22866f0 100644
--- a/src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs
+++ b/src/TensorFlowNET.Core/Tensors/Tensor.Creation.cs
@@ -36,8 +36,8 @@ namespace Tensorflow
public Tensor(IntPtr handle)
{
_handle = handle;
- }
-
+ }
+
#if _REGEN
%types=["sbyte", "byte", "short", "ushort", "int", "uint", "long", "ulong", "float", "double", "Complex"]
%foreach types%
@@ -66,6 +66,8 @@ namespace Tensorflow
var v = (#1*)Marshal.AllocHGlobal(sizeof(#1));
*v = value;
Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) => {
+ if (arg.deallocator_called)
+ return;
Marshal.FreeHGlobal(values);
arg.deallocator_called = true;
//_handle = IntPtr.Zero;
@@ -74,13 +76,15 @@ namespace Tensorflow
}
%
#else
-
+
+
+
///
/// Create a 1d Tensor from the given linear array and shape
///
public Tensor(sbyte[] data, TF_DataType? dType = null)
{
- _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(sbyte)), new long[]{data.Length}, data, Marshal.SizeOf());
+ _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(sbyte)), new long[] { data.Length }, data, Marshal.SizeOf());
}
///
@@ -98,20 +102,23 @@ namespace Tensorflow
{
var v = (sbyte*)Marshal.AllocHGlobal(sizeof(sbyte));
*v = value;
- Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) => {
+ Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) =>
+ {
+ if (arg.deallocator_called)
+ return;
Marshal.FreeHGlobal(values);
arg.deallocator_called = true;
//_handle = IntPtr.Zero;
};
- _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(sbyte)), dims:new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(sbyte), deallocator: deallocator, ref _deallocatorArgs);
- }
-
+ _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(sbyte)), dims: new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(sbyte), deallocator: deallocator, ref _deallocatorArgs);
+ }
+
///
/// Create a 1d Tensor from the given linear array and shape
///
public Tensor(byte[] data, TF_DataType? dType = null)
{
- _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(byte)), new long[]{data.Length}, data, Marshal.SizeOf());
+ _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(byte)), new long[] { data.Length }, data, Marshal.SizeOf());
}
///
@@ -129,20 +136,23 @@ namespace Tensorflow
{
var v = (byte*)Marshal.AllocHGlobal(sizeof(byte));
*v = value;
- Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) => {
+ Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) =>
+ {
+ if (arg.deallocator_called)
+ return;
Marshal.FreeHGlobal(values);
arg.deallocator_called = true;
//_handle = IntPtr.Zero;
};
- _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(byte)), dims:new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(byte), deallocator: deallocator, ref _deallocatorArgs);
- }
-
+ _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(byte)), dims: new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(byte), deallocator: deallocator, ref _deallocatorArgs);
+ }
+
///
/// Create a 1d Tensor from the given linear array and shape
///
public Tensor(short[] data, TF_DataType? dType = null)
{
- _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(short)), new long[]{data.Length}, data, Marshal.SizeOf());
+ _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(short)), new long[] { data.Length }, data, Marshal.SizeOf());
}
///
@@ -160,20 +170,23 @@ namespace Tensorflow
{
var v = (short*)Marshal.AllocHGlobal(sizeof(short));
*v = value;
- Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) => {
+ Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) =>
+ {
+ if (arg.deallocator_called)
+ return;
Marshal.FreeHGlobal(values);
arg.deallocator_called = true;
//_handle = IntPtr.Zero;
};
- _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(short)), dims:new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(short), deallocator: deallocator, ref _deallocatorArgs);
- }
-
+ _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(short)), dims: new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(short), deallocator: deallocator, ref _deallocatorArgs);
+ }
+
///
/// Create a 1d Tensor from the given linear array and shape
///
public Tensor(ushort[] data, TF_DataType? dType = null)
{
- _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(ushort)), new long[]{data.Length}, data, Marshal.SizeOf());
+ _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(ushort)), new long[] { data.Length }, data, Marshal.SizeOf());
}
///
@@ -191,20 +204,23 @@ namespace Tensorflow
{
var v = (ushort*)Marshal.AllocHGlobal(sizeof(ushort));
*v = value;
- Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) => {
+ Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) =>
+ {
+ if (arg.deallocator_called)
+ return;
Marshal.FreeHGlobal(values);
arg.deallocator_called = true;
//_handle = IntPtr.Zero;
};
- _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(ushort)), dims:new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(ushort), deallocator: deallocator, ref _deallocatorArgs);
- }
-
+ _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(ushort)), dims: new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(ushort), deallocator: deallocator, ref _deallocatorArgs);
+ }
+
///
/// Create a 1d Tensor from the given linear array and shape
///
public Tensor(int[] data, TF_DataType? dType = null)
{
- _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(int)), new long[]{data.Length}, data, Marshal.SizeOf());
+ _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(int)), new long[] { data.Length }, data, Marshal.SizeOf());
}
///
@@ -222,20 +238,23 @@ namespace Tensorflow
{
var v = (int*)Marshal.AllocHGlobal(sizeof(int));
*v = value;
- Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) => {
+ Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) =>
+ {
+ if (arg.deallocator_called)
+ return;
Marshal.FreeHGlobal(values);
arg.deallocator_called = true;
//_handle = IntPtr.Zero;
};
- _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(int)), dims:new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(int), deallocator: deallocator, ref _deallocatorArgs);
- }
-
+ _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(int)), dims: new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(int), deallocator: deallocator, ref _deallocatorArgs);
+ }
+
///
/// Create a 1d Tensor from the given linear array and shape
///
public Tensor(uint[] data, TF_DataType? dType = null)
{
- _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(uint)), new long[]{data.Length}, data, Marshal.SizeOf());
+ _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(uint)), new long[] { data.Length }, data, Marshal.SizeOf());
}
///
@@ -253,20 +272,23 @@ namespace Tensorflow
{
var v = (uint*)Marshal.AllocHGlobal(sizeof(uint));
*v = value;
- Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) => {
+ Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) =>
+ {
+ if (arg.deallocator_called)
+ return;
Marshal.FreeHGlobal(values);
arg.deallocator_called = true;
//_handle = IntPtr.Zero;
};
- _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(uint)), dims:new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(uint), deallocator: deallocator, ref _deallocatorArgs);
- }
-
+ _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(uint)), dims: new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(uint), deallocator: deallocator, ref _deallocatorArgs);
+ }
+
///
/// Create a 1d Tensor from the given linear array and shape
///
public Tensor(long[] data, TF_DataType? dType = null)
{
- _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(long)), new long[]{data.Length}, data, Marshal.SizeOf());
+ _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(long)), new long[] { data.Length }, data, Marshal.SizeOf());
}
///
@@ -284,20 +306,23 @@ namespace Tensorflow
{
var v = (long*)Marshal.AllocHGlobal(sizeof(long));
*v = value;
- Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) => {
+ Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) =>
+ {
+ if (arg.deallocator_called)
+ return;
Marshal.FreeHGlobal(values);
arg.deallocator_called = true;
//_handle = IntPtr.Zero;
};
- _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(long)), dims:new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(long), deallocator: deallocator, ref _deallocatorArgs);
- }
-
+ _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(long)), dims: new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(long), deallocator: deallocator, ref _deallocatorArgs);
+ }
+
///
/// Create a 1d Tensor from the given linear array and shape
///
public Tensor(ulong[] data, TF_DataType? dType = null)
{
- _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(ulong)), new long[]{data.Length}, data, Marshal.SizeOf());
+ _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(ulong)), new long[] { data.Length }, data, Marshal.SizeOf());
}
///
@@ -315,20 +340,23 @@ namespace Tensorflow
{
var v = (ulong*)Marshal.AllocHGlobal(sizeof(ulong));
*v = value;
- Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) => {
+ Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) =>
+ {
+ if (arg.deallocator_called)
+ return;
Marshal.FreeHGlobal(values);
arg.deallocator_called = true;
//_handle = IntPtr.Zero;
};
- _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(ulong)), dims:new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(ulong), deallocator: deallocator, ref _deallocatorArgs);
- }
-
+ _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(ulong)), dims: new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(ulong), deallocator: deallocator, ref _deallocatorArgs);
+ }
+
///
/// Create a 1d Tensor from the given linear array and shape
///
public Tensor(float[] data, TF_DataType? dType = null)
{
- _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(float)), new long[]{data.Length}, data, Marshal.SizeOf());
+ _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(float)), new long[] { data.Length }, data, Marshal.SizeOf());
}
///
@@ -346,20 +374,23 @@ namespace Tensorflow
{
var v = (float*)Marshal.AllocHGlobal(sizeof(float));
*v = value;
- Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) => {
+ Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) =>
+ {
+ if (arg.deallocator_called)
+ return;
Marshal.FreeHGlobal(values);
arg.deallocator_called = true;
//_handle = IntPtr.Zero;
};
- _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(float)), dims:new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(float), deallocator: deallocator, ref _deallocatorArgs);
- }
-
+ _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(float)), dims: new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(float), deallocator: deallocator, ref _deallocatorArgs);
+ }
+
///
/// Create a 1d Tensor from the given linear array and shape
///
public Tensor(double[] data, TF_DataType? dType = null)
{
- _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(double)), new long[]{data.Length}, data, Marshal.SizeOf());
+ _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(double)), new long[] { data.Length }, data, Marshal.SizeOf());
}
///
@@ -377,20 +408,23 @@ namespace Tensorflow
{
var v = (double*)Marshal.AllocHGlobal(sizeof(double));
*v = value;
- Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) => {
+ Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) =>
+ {
+ if (arg.deallocator_called)
+ return;
Marshal.FreeHGlobal(values);
arg.deallocator_called = true;
//_handle = IntPtr.Zero;
};
- _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(double)), dims:new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(double), deallocator: deallocator, ref _deallocatorArgs);
- }
-
+ _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(double)), dims: new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(double), deallocator: deallocator, ref _deallocatorArgs);
+ }
+
///
/// Create a 1d Tensor from the given linear array and shape
///
public Tensor(Complex[] data, TF_DataType? dType = null)
{
- _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(Complex)), new long[]{data.Length}, data, Marshal.SizeOf());
+ _handle = CreateTensorWithoutCopying(dType ?? dtypes.as_dtype(typeof(Complex)), new long[] { data.Length }, data, Marshal.SizeOf());
}
///
@@ -408,12 +442,15 @@ namespace Tensorflow
{
var v = (Complex*)Marshal.AllocHGlobal(sizeof(Complex));
*v = value;
- Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) => {
+ Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs arg) =>
+ {
+ if (arg.deallocator_called)
+ return;
Marshal.FreeHGlobal(values);
arg.deallocator_called = true;
//_handle = IntPtr.Zero;
};
- _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(Complex)), dims:new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(Complex), deallocator: deallocator, ref _deallocatorArgs);
+ _handle = TF_NewTensor(dType ?? dtypes.as_dtype(typeof(Complex)), dims: new long[0], num_dims: 0, data: (IntPtr)v, len: (UIntPtr)sizeof(Complex), deallocator: deallocator, ref _deallocatorArgs);
}
#endif
@@ -443,7 +480,7 @@ namespace Tensorflow
{
if (tensorDType == TF_DataType.TF_STRING && nd.dtype.Name == "Byte")
{
- var buffer=nd.Data();
+ var buffer = nd.Data();
var size = c_api.TF_StringEncodedSize((UIntPtr)buffer.Length);
var handle = TF_AllocateTensor(TF_DataType.TF_STRING, IntPtr.Zero, 0, (UIntPtr)((ulong)size + 8));
@@ -497,11 +534,13 @@ namespace Tensorflow
return new Tensor(UTF8Encoding.UTF8.GetBytes(nd.Data(0)), TF_DataType.TF_STRING);
default:
throw new NotImplementedException($"Marshal.Copy failed for {nd.dtype.Name}.");
- }
-
- // Free the original buffer and set flag
+ }
+
+ // Free the original buffer and set flag
Deallocator deallocator = (IntPtr values, IntPtr len, ref DeallocatorArgs args) =>
{
+ if (args.deallocator_called)
+ return;
Marshal.FreeHGlobal(values);
args.deallocator_called = true;
};
@@ -540,8 +579,22 @@ namespace Tensorflow
/// specified dimensions.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- protected IntPtr CreateTensorWithoutCopying(TF_DataType dt, long[] shape, Array data, int element_size)
+ protected unsafe IntPtr CreateTensorWithoutCopying(TF_DataType dt, long[] shape, Array data, int element_size)
{
+ if (dt == TF_DataType.TF_STRING && data is byte[])
+ {
+ var buffer = (byte[])data;
+ var size = c_api.TF_StringEncodedSize((UIntPtr)buffer.Length);
+ var handle = TF_AllocateTensor(TF_DataType.TF_STRING, IntPtr.Zero, 0, (UIntPtr)((ulong)size + 8));
+
+ IntPtr tensor = c_api.TF_TensorData(handle);
+ Marshal.WriteInt64(tensor, 0);
+ fixed (byte* src = &buffer[0])
+ c_api.TF_StringEncode(src, (UIntPtr)buffer.Length, (sbyte*)(tensor + sizeof(Int64)), size, status);
+
+ status.Check(true);
+ return handle;
+ }
return CreateTensorWithoutCopying(dt, shape, data, 0, data.Length, element_size);
}
@@ -568,21 +621,23 @@ namespace Tensorflow
// get a handle to the pinned array which we will pass on to the tensor computation engine to use
var gcHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
_isPinnedArray = true;
- _deallocatorArgs=new DeallocatorArgs(){ gc_handle = GCHandle.ToIntPtr( gcHandle) };
+ _deallocatorArgs = new DeallocatorArgs() { gc_handle = GCHandle.ToIntPtr(gcHandle) };
// Free the original buffer and set flag
Deallocator deallocator = (IntPtr ptr, IntPtr len, ref DeallocatorArgs args) =>
{
+ if (args.deallocator_called)
+ return;
// note: since the ptr given to tensorflow is just the addr of the pinned object we can not directly free it! we need to free the gcHandle instead
GCHandle.FromIntPtr(args.gc_handle).Free();
args.deallocator_called = true;
};
- if (shape == null || shape.Length==0)
+ if (shape == null || shape.Length == 0)
return TF_NewTensor(dt, new long[0], 0, gcHandle.AddrOfPinnedObject() + start * element_size, (UIntPtr)(count * element_size), deallocator, ref _deallocatorArgs);
else
return TF_NewTensor(dt, shape, shape.Length, gcHandle.AddrOfPinnedObject() + start * element_size, (UIntPtr)(count * element_size), deallocator, ref _deallocatorArgs);
}
- private DeallocatorArgs _deallocatorArgs=new DeallocatorArgs();
+ private DeallocatorArgs _deallocatorArgs = new DeallocatorArgs();
}
}
diff --git a/src/TensorFlowNET.Core/tf.cs b/src/TensorFlowNET.Core/tf.cs
index fe709c5b..9959a3a7 100644
--- a/src/TensorFlowNET.Core/tf.cs
+++ b/src/TensorFlowNET.Core/tf.cs
@@ -24,7 +24,8 @@ namespace Tensorflow
{
public static partial class tf
{
- public static TF_DataType bytes = TF_DataType.TF_STRING;
+ public static TF_DataType @byte = TF_DataType.TF_UINT8;
+ public static TF_DataType @sbyte = TF_DataType.TF_INT8;
public static TF_DataType int16 = TF_DataType.TF_INT16;
public static TF_DataType int32 = TF_DataType.TF_INT32;
public static TF_DataType int64 = TF_DataType.TF_INT64;
@@ -33,6 +34,7 @@ namespace Tensorflow
public static TF_DataType float64 = TF_DataType.TF_DOUBLE;
public static TF_DataType @bool = TF_DataType.TF_BOOL;
public static TF_DataType chars = TF_DataType.TF_STRING;
+ public static TF_DataType @string = TF_DataType.TF_STRING;
public static Context context = new Context(new ContextOptions(), new Status());
diff --git a/test/TensorFlowNET.Examples/ImageProcessing/RetrainImageClassifier.cs b/test/TensorFlowNET.Examples/ImageProcessing/RetrainImageClassifier.cs
index 0e7d8961..feb34663 100644
--- a/test/TensorFlowNET.Examples/ImageProcessing/RetrainImageClassifier.cs
+++ b/test/TensorFlowNET.Examples/ImageProcessing/RetrainImageClassifier.cs
@@ -557,7 +557,7 @@ namespace TensorFlowNET.Examples.ImageProcess
Tensor decoded_image_tensor, Tensor resized_input_tensor, Tensor bottleneck_tensor)
{
// First decode the JPEG image, resize it, and rescale the pixel values.
- var resized_input_values = sess.run(decoded_image_tensor, new FeedItem(image_data_tensor, image_data));
+ var resized_input_values = sess.run(decoded_image_tensor, new FeedItem(image_data_tensor, new Tensor( image_data, TF_DataType.TF_STRING)));
// Then run it through the recognition network.
var bottleneck_values = sess.run(bottleneck_tensor, new FeedItem(resized_input_tensor, resized_input_values));
bottleneck_values = np.squeeze(bottleneck_values);
@@ -644,7 +644,7 @@ namespace TensorFlowNET.Examples.ImageProcess
{
// height, width, depth
var input_dim = (299, 299, 3);
- var jpeg_data = tf.placeholder(tf.chars, name: "DecodeJPGInput");
+ var jpeg_data = tf.placeholder(tf.@string, name: "DecodeJPGInput");
var decoded_image = tf.image.decode_jpeg(jpeg_data, channels: input_dim.Item3);
// Convert from full range of uint8 to range [0,1] of float32.
var decoded_image_as_float = tf.image.convert_image_dtype(decoded_image, tf.float32);