Browse Source

fix Operation.get_attr for all properties.

add Convolution class
add convert_data_format
add as_numpy_dtype
tags/v0.8.0
Oceania2018 6 years ago
parent
commit
b5360269b5
24 changed files with 403 additions and 57 deletions
  1. +6
    -0
      TensorFlow.NET.sln
  2. +6
    -0
      src/TensorFlowNET.Core/Graphs/Graph.cs
  3. +6
    -1
      src/TensorFlowNET.Core/Keras/Engine/InputSpec.cs
  4. +3
    -1
      src/TensorFlowNET.Core/Keras/Engine/Layer.cs
  5. +32
    -1
      src/TensorFlowNET.Core/Keras/Layers/Conv.cs
  6. +33
    -0
      src/TensorFlowNET.Core/Keras/Utils/conv_utils.cs
  7. +10
    -4
      src/TensorFlowNET.Core/Layers/Layer.cs
  8. +66
    -0
      src/TensorFlowNET.Core/Operations/NnOps/Convolution.cs
  9. +56
    -0
      src/TensorFlowNET.Core/Operations/NnOps/_NonAtrousConvolution.cs
  10. +55
    -0
      src/TensorFlowNET.Core/Operations/NnOps/_WithSpaceToBatch.cs
  11. +14
    -0
      src/TensorFlowNET.Core/Operations/NnOps/gen_nn_ops.cs
  12. +1
    -21
      src/TensorFlowNET.Core/Operations/OpDefLibrary.cs
  13. +12
    -19
      src/TensorFlowNET.Core/Operations/Operation.cs
  14. +2
    -2
      src/TensorFlowNET.Core/Operations/gen_array_ops.cs
  15. +24
    -0
      src/TensorFlowNET.Core/Operations/nn_ops.cs
  16. +21
    -0
      src/TensorFlowNET.Core/Python.cs
  17. +4
    -0
      src/TensorFlowNET.Core/TensorFlowNET.Core.csproj
  18. +5
    -0
      src/TensorFlowNET.Core/Tensors/dtypes.cs
  19. +36
    -0
      src/TensorFlowNET.Core/Tensors/tensor_util.cs
  20. +1
    -1
      src/TensorFlowNET.Core/Variables/RefVariable.cs
  21. +7
    -7
      src/TensorFlowNET.Core/Variables/gen_state_ops.py.cs
  22. +1
    -0
      src/TensorFlowNET.Core/Variables/variable_scope.py.cs
  23. +1
    -0
      test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj
  24. +1
    -0
      test/TensorFlowNET.UnitTest/TensorFlowNET.UnitTest.csproj

+ 6
- 0
TensorFlow.NET.sln View File

@@ -11,6 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Core", "src\T
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Visualization", "src\TensorFlowNET.Visualization\TensorFlowNET.Visualization.csproj", "{0254BFF9-453C-4FE0-9609-3644559A79CE}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NumSharp.Core", "..\NumSharp\src\NumSharp.Core\NumSharp.Core.csproj", "{3EEAFB06-BEF0-4261-BAAB-630EABD25290}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -33,6 +35,10 @@ Global
{0254BFF9-453C-4FE0-9609-3644559A79CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0254BFF9-453C-4FE0-9609-3644559A79CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0254BFF9-453C-4FE0-9609-3644559A79CE}.Release|Any CPU.Build.0 = Release|Any CPU
{3EEAFB06-BEF0-4261-BAAB-630EABD25290}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3EEAFB06-BEF0-4261-BAAB-630EABD25290}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3EEAFB06-BEF0-4261-BAAB-630EABD25290}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3EEAFB06-BEF0-4261-BAAB-630EABD25290}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE


+ 6
- 0
src/TensorFlowNET.Core/Graphs/Graph.cs View File

@@ -21,6 +21,7 @@ namespace Tensorflow
public int _version;
private int _next_id_counter;
private List<String> _unfetchable_ops = new List<string>();
private List<Tensor> _unfeedable_tensors = new List<Tensor>();

public string _name_stack = "";
public string _graph_key;
@@ -366,6 +367,11 @@ namespace Tensorflow
return _collections[name];
}

public void prevent_feeding(Tensor tensor)
{
_unfeedable_tensors.Add(tensor);
}

public void Dispose()
{
c_api.TF_DeleteGraph(_handle);


+ 6
- 1
src/TensorFlowNET.Core/Keras/Engine/InputSpec.cs View File

@@ -10,11 +10,16 @@ namespace Tensorflow.Keras.Engine
public class InputSpec
{
public int ndim;
Dictionary<int, int> axes;

public InputSpec(TF_DataType dtype = TF_DataType.DtInvalid,
int? ndim = null)
int? ndim = null,
Dictionary<int, int> axes = null)
{
this.ndim = ndim.Value;
if (axes == null)
axes = new Dictionary<int, int>();
this.axes = axes;
}
}
}

+ 3
- 1
src/TensorFlowNET.Core/Keras/Engine/Layer.cs View File

@@ -66,7 +66,7 @@ namespace Tensorflow.Keras.Engine

}

protected virtual void add_weight(string name,
protected virtual RefVariable add_weight(string name,
int[] shape,
TF_DataType dtype = TF_DataType.DtInvalid,
IInitializer initializer = null,
@@ -82,6 +82,8 @@ namespace Tensorflow.Keras.Engine
trainable: trainable.Value);
backend.track_variable(variable);
_trainable_weights.Add(variable);

return variable;
}
}
}

+ 32
- 1
src/TensorFlowNET.Core/Keras/Layers/Conv.cs View File

@@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.Text;
using Tensorflow.Keras.Engine;
using Tensorflow.Keras.Utils;
using Tensorflow.Operations;
using Tensorflow.Operations.Activation;

namespace Tensorflow.Keras.Layers
@@ -19,6 +21,9 @@ namespace Tensorflow.Keras.Layers
protected bool use_bias;
protected IInitializer kernel_initializer;
protected IInitializer bias_initializer;
protected RefVariable kernel;
protected RefVariable bias;
protected Convolution _convolution_op;

public Conv(int rank,
int filters,
@@ -53,11 +58,37 @@ namespace Tensorflow.Keras.Layers
int channel_axis = data_format == "channels_first" ? 1 : -1;
int input_dim = input_shape.Dimensions[input_shape.NDim - 1];
var kernel_shape = new int[] { kernel_size[0], kernel_size[1], input_dim, filters };
add_weight(name: "kernel",
kernel = add_weight(name: "kernel",
shape: kernel_shape,
initializer: kernel_initializer,
trainable: true,
dtype: _dtype);
if (use_bias)
bias = add_weight(name: "bias",
shape: new int[] { filters },
initializer: bias_initializer,
trainable: true,
dtype: _dtype);

var axes = new Dictionary<int, int>();
axes.Add(-1, input_dim);
input_spec = new InputSpec(ndim: rank + 2, axes: axes);

string op_padding;
if (padding == "causal")
op_padding = "valid";
else
op_padding = padding;

var df = conv_utils.convert_data_format(data_format, rank + 2);
_convolution_op = nn_ops.Convolution(input_shape,
kernel.shape,
op_padding.ToUpper(),
strides,
dilation_rate,
data_format: df);

built = true;
}
}
}

+ 33
- 0
src/TensorFlowNET.Core/Keras/Utils/conv_utils.cs View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Tensorflow.Keras.Utils
{
public class conv_utils
{
public static string convert_data_format(string data_format, int ndim)
{
if (data_format == "channels_last")
if (ndim == 3)
return "NWC";
else if (ndim == 4)
return "NHWC";
else if (ndim == 5)
return "NDHWC";
else
throw new ValueError($"Input rank not supported: {ndim}");
else if (data_format == "channels_first")
if (ndim == 3)
return "NCW";
else if (ndim == 4)
return "NCHW";
else if (ndim == 5)
return "NCDHW";
else
throw new ValueError($"Input rank not supported: {ndim}");
else
throw new ValueError($"Invalid data_format: {data_format}");
}
}
}

+ 10
- 4
src/TensorFlowNET.Core/Layers/Layer.cs View File

@@ -68,7 +68,7 @@ namespace Tensorflow.Layers
throw new NotImplementedException("");
}

protected virtual void add_weight(string name,
protected virtual RefVariable add_weight(string name,
int[] shape,
TF_DataType dtype = TF_DataType.DtInvalid,
IInitializer initializer = null,
@@ -93,14 +93,14 @@ namespace Tensorflow.Layers

_set_scope();
var reuse = built || (_reuse != null && _reuse.Value);
Python.with(tf.variable_scope(_scope,
return Python.with(tf.variable_scope(_scope,
reuse: reuse,
auxiliary_name_scope: false), scope =>
{
_current_scope = scope;
Python.with(ops.name_scope(_name_scope()), delegate
return Python.with(ops.name_scope(_name_scope()), delegate
{
base.add_weight(name,
var variable = base.add_weight(name,
shape,
dtype: dtype,
initializer: initializer,
@@ -113,6 +113,12 @@ namespace Tensorflow.Layers
initializer: initializer1,
trainable: trainable1);
});

if(init_graph != null)
{
var trainable_variables = variables.trainable_variables();
}
return variable;
});
});
}


+ 66
- 0
src/TensorFlowNET.Core/Operations/NnOps/Convolution.cs View File

@@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Tensorflow.Operations
{
public class Convolution
{
public TensorShape input_shape;
public TensorShape filter_shape;
public string data_format;
public int[] strides;
public string name;
public _WithSpaceToBatch conv_op;

public Convolution(TensorShape input_shape,
TensorShape filter_shape,
string padding,
int[] strides,
int[] dilation_rate,
string name = null,
string data_format = null)
{
var num_total_dims = filter_shape.NDim;
var num_spatial_dims = num_total_dims - 2;
int input_channels_dim;
int[] spatial_dims;
if (string.IsNullOrEmpty(data_format) || !data_format.StartsWith("NC"))
{
input_channels_dim = input_shape.Dimensions[num_spatial_dims + 1];
spatial_dims = Enumerable.Range(1, num_spatial_dims).ToArray();
}
else
{
input_channels_dim = input_shape.Dimensions[1];
spatial_dims = Enumerable.Range(2, num_spatial_dims).ToArray();
}

this.input_shape = input_shape;
this.filter_shape = filter_shape;
this.data_format = data_format;
this.strides = strides;
this.name = name;

conv_op = new _WithSpaceToBatch(
input_shape,
dilation_rate: dilation_rate,
padding: padding,
build_op: _build_op,
filter_shape: filter_shape,
spatial_dims: spatial_dims,
data_format: data_format);
}

public _NonAtrousConvolution _build_op(int _, string padding)
{
return new _NonAtrousConvolution(input_shape,
filter_shape: filter_shape,
padding: padding,
data_format: data_format,
strides: strides,
name: name);
}
}
}

+ 56
- 0
src/TensorFlowNET.Core/Operations/NnOps/_NonAtrousConvolution.cs View File

@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Tensorflow.Operations
{
public class _NonAtrousConvolution
{
public string padding;
public string name;
public int[] strides;
public string data_format;
private Func<object, Tensor> conv_op;

public _NonAtrousConvolution(TensorShape input_shape,
TensorShape filter_shape,
string padding,
string data_format,
int[] strides,
string name)
{
this.padding = padding;
this.name = name;
var conv_dims = input_shape.NDim - 2;
if (conv_dims == 1)
{
throw new NotImplementedException("_NonAtrousConvolution conv_dims 1");
}
else if (conv_dims == 2)
{
var list = strides.ToList();

if (string.IsNullOrEmpty(data_format) || data_format == "NHWC")
{
data_format = "NHWC";
list.Insert(0, 1);
list.Add(1);
}
else if (data_format == "NCHW")
list.InsertRange(0, new int[] { 1, 1 });
else
throw new ValueError("data_format must be \"NHWC\" or \"NCHW\".");

strides = list.ToArray();
this.strides = strides;
this.data_format = data_format;
conv_op = gen_nn_ops.conv2d;
}
else if (conv_dims == 3)
{
throw new NotImplementedException("_NonAtrousConvolution conv_dims 3");
}
}
}
}

+ 55
- 0
src/TensorFlowNET.Core/Operations/NnOps/_WithSpaceToBatch.cs View File

@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Tensorflow.Operations
{
public class _WithSpaceToBatch
{
private _NonAtrousConvolution call;

public _WithSpaceToBatch(TensorShape input_shape,
int[] dilation_rate,
string padding,
Func<int, string, _NonAtrousConvolution> build_op,
TensorShape filter_shape = null,
int[] spatial_dims = null,
string data_format = null)
{
var dilation_rate_tensor = ops.convert_to_tensor(dilation_rate, TF_DataType.TF_INT32, name: "dilation_rate");
var rate_shape = dilation_rate_tensor.getShape();
var num_spatial_dims = rate_shape.Dimensions[0];
int starting_spatial_dim = -1;
if (!string.IsNullOrEmpty(data_format) && data_format.StartsWith("NC"))
starting_spatial_dim = 2;
else
starting_spatial_dim = 1;

if (spatial_dims == null)
throw new NotImplementedException("_WithSpaceToBatch spatial_dims");

var orig_spatial_dims = spatial_dims;
spatial_dims = spatial_dims.OrderBy(x => x).ToArray();
if (!Enumerable.SequenceEqual(spatial_dims, orig_spatial_dims) || spatial_dims.Any(x => x < 1))
throw new ValueError("spatial_dims must be a montonically increasing sequence of positive integers");

int expected_input_rank = -1;
if (!string.IsNullOrEmpty(data_format) && data_format.StartsWith("NC"))
expected_input_rank = spatial_dims.Last();
else
expected_input_rank = spatial_dims.Last() + 1;

var const_rate = tensor_util.constant_value(dilation_rate_tensor);
var rate_or_const_rate = dilation_rate;
if(!(const_rate is null))
{
if (const_rate.Data<int>().Count(x => x == 1) == const_rate.size)
{
call = build_op(num_spatial_dims, padding);
return;
}
}
}
}
}

+ 14
- 0
src/TensorFlowNET.Core/Operations/NnOps/gen_nn_ops.cs View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Tensorflow.Operations
{
public class gen_nn_ops
{
public static Tensor conv2d(object parameters)
{
throw new NotImplementedException("gen_nn_op.conv2d");
}
}
}

+ 1
- 21
src/TensorFlowNET.Core/Operations/OpDefLibrary.cs View File

@@ -12,7 +12,7 @@ namespace Tensorflow
{
public class OpDefLibrary : Python
{
public Operation _apply_op_helper(string op_type_name, string name = null, dynamic args = null)
public Operation _apply_op_helper(string op_type_name, string name = null, object args = null)
{
Dictionary<string, object> keywords = ConvertToDict(args);
var g = ops.get_default_graph();
@@ -358,25 +358,5 @@ namespace Tensorflow
return false;
}
}

private Dictionary<string, object> ConvertToDict(dynamic dyn)
{
var dictionary = new Dictionary<string, object>();
foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(dyn))
{
object obj = propertyDescriptor.GetValue(dyn);
string name = propertyDescriptor.Name;
// avoid .net keyword
switch (name)
{
case "_ref_":
name = "ref";
break;
}
dictionary.Add(name, obj);
}
return dictionary;
}
}
}

+ 12
- 19
src/TensorFlowNET.Core/Operations/Operation.cs View File

@@ -164,7 +164,7 @@ namespace Tensorflow
return grouped_inputs.ToArray();
}

public object get_attr<T>(string name)
public object get_attr(string name)
{
AttrValue x = null;

@@ -175,24 +175,17 @@ namespace Tensorflow
x = AttrValue.Parser.ParseFrom(buf);
}

switch (name)
{
case "T":
case "dtype":
return x.Type;
case "shape":
return x.Shape;
default:
switch (typeof(T).Name)
{
case "Boolean":
return x.B;
case "String":
return x.S;
default:
throw new NotImplementedException($"Unsupported field type in {x.ToString()}");
}
}
string oneof_value = x.ValueCase.ToString();
if (string.IsNullOrEmpty(oneof_value))
return null;

if(oneof_value == "list")
throw new NotImplementedException($"Unsupported field type in {x.ToString()}");

if (oneof_value == "type")
return x.Type;

return x.GetType().GetProperty(oneof_value).GetValue(x);
}

public TF_AttrMetadata GetAttributeMetadata(string attr_name, Status s)


+ 2
- 2
src/TensorFlowNET.Core/Operations/gen_array_ops.cs View File

@@ -47,8 +47,8 @@ namespace Tensorflow
var _inputs_flat = _op.inputs;

var _attrs = new Dictionary<string, object>();
_attrs["dtype"] = _op.get_attr<DataType>("dtype");
_attrs["shape"] = _op.get_attr<int[]>("shape");
_attrs["dtype"] = _op.get_attr("dtype");
_attrs["shape"] = _op.get_attr("shape");

_execute.record_gradient("Placeholder", _inputs_flat, _attrs, _result, name);



+ 24
- 0
src/TensorFlowNET.Core/Operations/nn_ops.cs View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Text;
using Tensorflow.Operations;

namespace Tensorflow
{
public class nn_ops
{
public static Convolution Convolution(TensorShape input_shape,
TensorShape filter_shape,
string padding,
int[] strides,
int[] dilation_rate,
string name = null,
string data_format = null) => new Convolution(input_shape,
filter_shape,
padding,
strides,
dilation_rate,
name: name,
data_format: data_format);
}
}

+ 21
- 0
src/TensorFlowNET.Core/Python.cs View File

@@ -1,6 +1,7 @@
using NumSharp.Core;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;

namespace Tensorflow
@@ -109,6 +110,26 @@ namespace Tensorflow
for (int i = 0; i < values.Count; i++)
yield return (i, values[i]);
}

public static Dictionary<string, object> ConvertToDict(object dyn)
{
var dictionary = new Dictionary<string, object>();
foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(dyn))
{
object obj = propertyDescriptor.GetValue(dyn);
string name = propertyDescriptor.Name;
// avoid .net keyword
switch (name)
{
case "_ref_":
name = "ref";
break;
}

dictionary.Add(name, obj);
}
return dictionary;
}
}

public interface IPython : IDisposable


+ 4
- 0
src/TensorFlowNET.Core/TensorFlowNET.Core.csproj View File

@@ -51,4 +51,8 @@ Fixed import name scope issue.</PackageReleaseNotes>
<Content CopyToOutputDirectory="PreserveNewest" Include="./runtimes/win-x64/native/tensorflow.dll" Link="tensorflow.dll" Pack="true" PackagePath="runtimes/win-x64/native/tensorflow.dll" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\NumSharp\src\NumSharp.Core\NumSharp.Core.csproj" />
</ItemGroup>

</Project>

+ 5
- 0
src/TensorFlowNET.Core/Tensors/dtypes.cs View File

@@ -79,6 +79,11 @@ namespace Tensorflow
return (int)type;
}

public static Type as_numpy_dtype(this DataType type)
{
return type.as_tf_dtype().as_numpy_datatype();
}

public static DataType as_base_dtype(this DataType type)
{
return (int)type > 100 ?


+ 36
- 0
src/TensorFlowNET.Core/Tensors/tensor_util.cs View File

@@ -17,6 +17,42 @@ namespace Tensorflow
TF_DataType.TF_QUINT16, TF_DataType.TF_QINT32, TF_DataType.TF_UINT32, TF_DataType.TF_UINT64
};

/// <summary>
/// Returns the constant value of the given tensor, if efficiently calculable.
/// </summary>
/// <param name="tensor"></param>
/// <param name="partial"></param>
/// <returns></returns>
public static NDArray constant_value(Tensor tensor, bool partial = false)
{
NDArray ret = _ConstantValue(tensor, partial);
if (!(ret is null))
tensor.graph.prevent_feeding(tensor);

return ret;
}

private static NDArray _ConstantValue(Tensor tensor, bool partial)
{
if (tensor.op.type == "Const")
{
return MakeNdarray(tensor.op.get_attr("value") as TensorProto);
}
throw new NotImplementedException("_ConstantValue");
}

public static NDArray MakeNdarray(TensorProto tensor)
{
var shape = tensor.TensorShape.Dim.Select(x => (int)x.Size).ToArray();
long num_elements = np.prod(shape);
var tensor_dtype = tensor.Dtype.as_numpy_dtype();

if (tensor.TensorContent.Length > 0)
return np.frombuffer(tensor.TensorContent.ToByteArray(), tensor_dtype)
.reshape(shape);
throw new NotImplementedException("MakeNdarray");
}

/// <summary>
/// Create a TensorProto.
/// </summary>


+ 1
- 1
src/TensorFlowNET.Core/Variables/RefVariable.cs View File

@@ -113,7 +113,7 @@ namespace Tensorflow
_graph_key = ops.get_default_graph()._graph_key;

_trainable = trainable;
if (!collections.Contains(ops.GraphKeys.TRAINABLE_VARIABLES))
if (trainable && !collections.Contains(ops.GraphKeys.TRAINABLE_VARIABLES))
collections.Add(ops.GraphKeys.TRAINABLE_VARIABLES);

ops.init_scope();


+ 7
- 7
src/TensorFlowNET.Core/Variables/gen_state_ops.py.cs View File

@@ -29,10 +29,10 @@ namespace Tensorflow
var _inputs_flat = _op.inputs;

var _attrs = new Dictionary<string, object>();
_attrs["dtype"] = _op.get_attr<DataType>("dtype");
_attrs["shape"] = _op.get_attr<int[]>("shape");
_attrs["container"] = _op.get_attr<string>("container");
_attrs["shared_name"] = _op.get_attr<string>("shared_name");
_attrs["dtype"] = _op.get_attr("dtype");
_attrs["shape"] = _op.get_attr("shape");
_attrs["container"] = _op.get_attr("container");
_attrs["shared_name"] = _op.get_attr("shared_name");

_execute.record_gradient("VariableV2", _inputs_flat, _attrs, _result, name);

@@ -58,9 +58,9 @@ namespace Tensorflow
var _inputs_flat = _op.inputs;

var _attrs = new Dictionary<string, object>();
_attrs["T"] = _op.get_attr<DataType>("T");
_attrs["validate_shape"] = _op.get_attr<bool>("validate_shape");
_attrs["use_locking"] = _op.get_attr<bool>("use_locking");
_attrs["T"] = _op.get_attr("T");
_attrs["validate_shape"] = _op.get_attr("validate_shape");
_attrs["use_locking"] = _op.get_attr("use_locking");

_execute.record_gradient("Assign", _inputs_flat, _attrs, _result, name);



+ 1
- 0
src/TensorFlowNET.Core/Variables/variable_scope.py.cs View File

@@ -155,6 +155,7 @@ namespace Tensorflow
else
{
return new RefVariable(initial_value,
trainable: trainable.Value,
name: name,
dtype: dtype);
}


+ 1
- 0
test/TensorFlowNET.Examples/TensorFlowNET.Examples.csproj View File

@@ -12,6 +12,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\NumSharp\src\NumSharp.Core\NumSharp.Core.csproj" />
<ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" />
</ItemGroup>



+ 1
- 0
test/TensorFlowNET.UnitTest/TensorFlowNET.UnitTest.csproj View File

@@ -24,6 +24,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\NumSharp\src\NumSharp.Core\NumSharp.Core.csproj" />
<ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" />
</ItemGroup>



Loading…
Cancel
Save