@@ -540,8 +540,10 @@ namespace Tensorflow | |||||
return nd.dtype; | return nd.dtype; | ||||
case Tensor tensor: | case Tensor tensor: | ||||
return tensor.dtype; | return tensor.dtype; | ||||
case Tensor[] tensor: | |||||
return tensor[0].dtype; | |||||
case Tensors tensors: | |||||
return tensors.dtype; | |||||
case IEnumerable<Tensor> tensors: | |||||
return tensors.First().dtype; | |||||
case ResourceVariable variable: | case ResourceVariable variable: | ||||
return variable.dtype; | return variable.dtype; | ||||
default: | default: | ||||
@@ -51,7 +51,8 @@ namespace Tensorflow.Eager | |||||
SafeTensorHandleHandle tensor_handle = inputs[i] switch | SafeTensorHandleHandle tensor_handle = inputs[i] switch | ||||
{ | { | ||||
EagerTensor et => et.EagerTensorHandle, | EagerTensor et => et.EagerTensorHandle, | ||||
_ => throw new NotImplementedException("") | |||||
Tensor nd => nd.EagerTensorHandle, | |||||
_ => throw new NotImplementedException("Eager tensor handle has not been allocated.") | |||||
}; | }; | ||||
c_api.TFE_OpAddInput(op, tensor_handle, status.Handle); | c_api.TFE_OpAddInput(op, tensor_handle, status.Handle); | ||||
status.Check(true); | status.Check(true); | ||||
@@ -186,7 +186,10 @@ namespace Tensorflow | |||||
private static Tensor _constant_if_small(int value, Tensor shape) | private static Tensor _constant_if_small(int value, Tensor shape) | ||||
{ | { | ||||
return shape < 1000L; | |||||
if (shape.dtype == TF_DataType.TF_INT64) | |||||
return shape < 1000L; | |||||
else | |||||
return shape < 1000; | |||||
} | } | ||||
private static Tensor _constant_if_small<T>(T value, Shape shape, TF_DataType dtype, string name) | private static Tensor _constant_if_small<T>(T value, Shape shape, TF_DataType dtype, string name) | ||||
@@ -16,7 +16,7 @@ namespace Tensorflow | |||||
{ | { | ||||
//Are the types matching? | //Are the types matching? | ||||
if (typeof(T).as_tf_dtype() != dtype) | if (typeof(T).as_tf_dtype() != dtype) | ||||
throw new ArrayTypeMismatchException($"dtype {dtype} mismatch."); | |||||
throw new ArrayTypeMismatchException($"Required dtype {dtype} mismatch with {typeof(T).as_tf_dtype()}."); | |||||
if (ndim == 0 && size == 1) //is it a scalar? | if (ndim == 0 && size == 1) //is it a scalar? | ||||
{ | { | ||||
@@ -74,7 +74,7 @@ namespace Tensorflow | |||||
if (dtype != TF_DataType.DtInvalid && | if (dtype != TF_DataType.DtInvalid && | ||||
value.GetType().Name != "NDArray" && | value.GetType().Name != "NDArray" && | ||||
value.GetType().BaseType.Name != "Array" && | value.GetType().BaseType.Name != "Array" && | ||||
dtypes.as_base_dtype(dtype) != dtypes.as_tf_dtype(value.GetType())) | |||||
dtype != value.GetDataType()) | |||||
{ | { | ||||
switch (dtype) | switch (dtype) | ||||
{ | { | ||||
@@ -87,6 +87,9 @@ namespace Tensorflow | |||||
case TF_DataType.TF_INT64: | case TF_DataType.TF_INT64: | ||||
value = Convert.ToInt64(value); | value = Convert.ToInt64(value); | ||||
break; | break; | ||||
case TF_DataType.TF_INT32: | |||||
value = Convert.ToInt32(value); | |||||
break; | |||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
@@ -162,7 +162,7 @@ namespace Tensorflow | |||||
? tensor.AsPlaceholder(name: name) | ? tensor.AsPlaceholder(name: name) | ||||
: tensor.AsConstant(name: name), | : tensor.AsConstant(name: name), | ||||
Tensor tensor => tensor, | Tensor tensor => tensor, | ||||
Tensor[] tensors => array_ops._autopacking_helper(tensors, dtype, name == null ? "packed" : name), | |||||
IEnumerable<Tensor> tensors => array_ops._autopacking_helper(tensors, dtype, name == null ? "packed" : name), | |||||
RefVariable varVal => varVal._TensorConversionFunction(dtype: dtype, name: name, as_ref: as_ref), | RefVariable varVal => varVal._TensorConversionFunction(dtype: dtype, name: name, as_ref: as_ref), | ||||
ResourceVariable varVal => varVal._TensorConversionFunction(dtype: dtype, name: name, as_ref: as_ref), | ResourceVariable varVal => varVal._TensorConversionFunction(dtype: dtype, name: name, as_ref: as_ref), | ||||
Axis ts => constant_op.constant(ts.axis, dtype: dtype, name: name), | Axis ts => constant_op.constant(ts.axis, dtype: dtype, name: name), | ||||
@@ -21,12 +21,14 @@ namespace Tensorflow.Keras.Layers | |||||
protected override Tensors Call(Tensors inputs, Tensor state = null, bool? training = null) | protected override Tensors Call(Tensors inputs, Tensor state = null, bool? training = null) | ||||
{ | { | ||||
var shapes = new List<object>(); | |||||
var shapes = new List<Tensor>(); | |||||
shapes.Add(array_ops.shape(inputs)[0]); | shapes.Add(array_ops.shape(inputs)[0]); | ||||
var dtype = shapes[0].dtype; | |||||
if (args.TargetShapeObjects != null) | if (args.TargetShapeObjects != null) | ||||
shapes.AddRange(args.TargetShapeObjects); | |||||
// shapes.AddRange(args.TargetShapeObjects); | |||||
throw new NotImplementedException(""); | |||||
if (args.TargetShape != null) | if (args.TargetShape != null) | ||||
args.TargetShape.dims.ToList().ForEach(x => shapes.Add(x)); | |||||
shapes.AddRange(args.TargetShape.dims.Select(x => constant_op.constant(x, dtype))); | |||||
var shape = ops.convert_to_tensor(shapes); | var shape = ops.convert_to_tensor(shapes); | ||||
var result = array_ops.reshape(inputs, shape); | var result = array_ops.reshape(inputs, shape); | ||||
@@ -184,7 +184,7 @@ namespace Tensorflow.Keras.Utils | |||||
public static int count_params(Layer layer, List<IVariableV1> weights) | public static int count_params(Layer layer, List<IVariableV1> weights) | ||||
{ | { | ||||
var weight_shapes = weights.Select(x => x.shape).ToArray(); | var weight_shapes = weights.Select(x => x.shape).ToArray(); | ||||
var total = weight_shapes.Select(p => (int)np.prod(p.dims)).Sum(); | |||||
var total = weight_shapes.Select(p => (int)p.size).Sum(); | |||||
return total; | return total; | ||||
} | } | ||||
@@ -1,4 +1,5 @@ | |||||
using Microsoft.VisualStudio.TestTools.UnitTesting; | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||
using Tensorflow; | |||||
using Tensorflow.NumPy; | using Tensorflow.NumPy; | ||||
using static Tensorflow.Binding; | using static Tensorflow.Binding; | ||||
using static Tensorflow.KerasApi; | using static Tensorflow.KerasApi; | ||||
@@ -11,8 +12,8 @@ namespace TensorFlowNET.Keras.UnitTest | |||||
[TestMethod] | [TestMethod] | ||||
public void ZeroPadding2D() | public void ZeroPadding2D() | ||||
{ | { | ||||
var input_shape = new[] { 1, 1, 2, 2 }; | |||||
var x = np.arange((int)np.prod(input_shape)).reshape(input_shape); | |||||
Shape input_shape = (1, 1, 2, 2); | |||||
var x = np.arange(input_shape.size).reshape(input_shape); | |||||
var zero_padding_2d = keras.layers.ZeroPadding2D(new[,] { { 1, 0 }, { 1, 0 } }); | var zero_padding_2d = keras.layers.ZeroPadding2D(new[,] { { 1, 0 }, { 1, 0 } }); | ||||
var y = zero_padding_2d.Apply(x); | var y = zero_padding_2d.Apply(x); | ||||
Assert.AreEqual((1, 2, 3, 2), y.shape); | Assert.AreEqual((1, 2, 3, 2), y.shape); | ||||
@@ -21,8 +22,8 @@ namespace TensorFlowNET.Keras.UnitTest | |||||
[TestMethod] | [TestMethod] | ||||
public void UpSampling2D() | public void UpSampling2D() | ||||
{ | { | ||||
var input_shape = new[] { 2, 2, 1, 3 }; | |||||
var x = np.arange((int)np.prod(input_shape)).reshape(input_shape); | |||||
Shape input_shape = (2, 2, 1, 3); | |||||
var x = np.arange(input_shape.size).reshape(input_shape); | |||||
var y = keras.layers.UpSampling2D(size: (1, 2)).Apply(x); | var y = keras.layers.UpSampling2D(size: (1, 2)).Apply(x); | ||||
Assert.AreEqual((2, 2, 2, 3), y.shape); | Assert.AreEqual((2, 2, 2, 3), y.shape); | ||||
} | } | ||||
@@ -21,7 +21,7 @@ namespace TensorFlowNET.Keras.UnitTest | |||||
{ | { | ||||
var mse = keras.losses.MeanSquaredError(); | var mse = keras.losses.MeanSquaredError(); | ||||
var call = mse.Call(y_true, y_pred); | var call = mse.Call(y_true, y_pred); | ||||
Assert.AreEqual((NDArray)0.5, call.numpy()) ; | |||||
Assert.AreEqual(call.numpy(), 0.5); | |||||
} | } | ||||
[TestMethod] | [TestMethod] | ||||
@@ -33,7 +33,7 @@ namespace TensorFlowNET.Keras.UnitTest | |||||
var mse = keras.losses.MeanSquaredError(); | var mse = keras.losses.MeanSquaredError(); | ||||
var call = mse.Call(y_true_float, y_pred_float); | var call = mse.Call(y_true_float, y_pred_float); | ||||
Assert.AreEqual((NDArray)0.5, call.numpy()); | |||||
Assert.AreEqual(call.numpy(), 0.5f); | |||||
} | } | ||||
[TestMethod] | [TestMethod] | ||||
@@ -42,7 +42,7 @@ namespace TensorFlowNET.Keras.UnitTest | |||||
{ | { | ||||
var mse = keras.losses.MeanSquaredError(); | var mse = keras.losses.MeanSquaredError(); | ||||
var call = mse.Call(y_true, y_pred, sample_weight: (NDArray)new double[] { 0.7, 0.3 }); | var call = mse.Call(y_true, y_pred, sample_weight: (NDArray)new double[] { 0.7, 0.3 }); | ||||
Assert.AreEqual((NDArray)0.25, call.numpy()); | |||||
Assert.AreEqual(call.numpy(), 0.25); | |||||
} | } | ||||
[TestMethod] | [TestMethod] | ||||
@@ -50,7 +50,7 @@ namespace TensorFlowNET.Keras.UnitTest | |||||
{ | { | ||||
var mse = keras.losses.MeanSquaredError(reduction: Reduction.SUM); | var mse = keras.losses.MeanSquaredError(reduction: Reduction.SUM); | ||||
var call = mse.Call(y_true, y_pred); | var call = mse.Call(y_true, y_pred); | ||||
Assert.AreEqual((NDArray)1.0, call.numpy()); | |||||
Assert.AreEqual(call.numpy(), 1.0); | |||||
} | } | ||||
[TestMethod] | [TestMethod] | ||||
@@ -59,7 +59,7 @@ namespace TensorFlowNET.Keras.UnitTest | |||||
{ | { | ||||
var mse = keras.losses.MeanSquaredError(reduction: Reduction.NONE); | var mse = keras.losses.MeanSquaredError(reduction: Reduction.NONE); | ||||
var call = mse.Call(y_true, y_pred); | var call = mse.Call(y_true, y_pred); | ||||
Assert.AreEqual((NDArray)new double[] { 0.5, 0.5 }, call.numpy()); | |||||
Assert.AreEqual(call.numpy(), new double[] { 0.5, 0.5 }); | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -67,7 +67,7 @@ namespace Tensorflow.Native.UnitTest.Tensors | |||||
Tensor t = c_api.TF_AllocateTensor(TF_DataType.TF_FLOAT, dims, 2, num_bytes); | Tensor t = c_api.TF_AllocateTensor(TF_DataType.TF_FLOAT, dims, 2, num_bytes); | ||||
EXPECT_EQ(TF_DataType.TF_FLOAT, t.dtype); | EXPECT_EQ(TF_DataType.TF_FLOAT, t.dtype); | ||||
EXPECT_EQ(2, t.ndim); | EXPECT_EQ(2, t.ndim); | ||||
EXPECT_EQ((int)dims[0], t.shape[0]); | |||||
EXPECT_EQ(dims[0], t.shape[0]); | |||||
EXPECT_EQ(num_bytes, t.bytesize); | EXPECT_EQ(num_bytes, t.bytesize); | ||||
t.Dispose(); | t.Dispose(); | ||||
} | } | ||||
@@ -101,9 +101,9 @@ namespace Tensorflow.Native.UnitTest.Tensors | |||||
EXPECT_EQ(tensor.dtype, TF_DataType.TF_FLOAT); | EXPECT_EQ(tensor.dtype, TF_DataType.TF_FLOAT); | ||||
EXPECT_EQ(tensor.rank, nd.ndim); | EXPECT_EQ(tensor.rank, nd.ndim); | ||||
EXPECT_EQ((int)tensor.shape[0], nd.dims[0]); | |||||
EXPECT_EQ((int)tensor.shape[1], nd.dims[1]); | |||||
EXPECT_EQ(tensor.bytesize, (ulong)nd.size * sizeof(float)); | |||||
EXPECT_EQ(tensor.shape[0], nd.dims[0]); | |||||
EXPECT_EQ(tensor.shape[1], nd.dims[1]); | |||||
EXPECT_EQ(tensor.bytesize, nd.size * sizeof(float)); | |||||
Assert.IsTrue(Enumerable.SequenceEqual(nd.Data<float>(), new float[] { 1, 2, 3, 4, 5, 6 })); | Assert.IsTrue(Enumerable.SequenceEqual(nd.Data<float>(), new float[] { 1, 2, 3, 4, 5, 6 })); | ||||
} | } | ||||