@@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Examples", "t | |||
EndProject | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TensorFlowNET.Core", "src\TensorFlowNET.Core\TensorFlowNET.Core.csproj", "{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TensorFlowNET.Utility", "src\TensorFlowNET.Utility\TensorFlowNET.Utility.csproj", "{00D9085C-0FC7-453C-A0CC-BAD98F44FEA0}" | |||
EndProject | |||
Global | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
Debug|Any CPU = Debug|Any CPU | |||
@@ -27,6 +29,10 @@ Global | |||
{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{FD682AC0-7B2D-45D3-8B0D-C6D678B04144}.Release|Any CPU.Build.0 = Release|Any CPU | |||
{00D9085C-0FC7-453C-A0CC-BAD98F44FEA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{00D9085C-0FC7-453C-A0CC-BAD98F44FEA0}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{00D9085C-0FC7-453C-A0CC-BAD98F44FEA0}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{00D9085C-0FC7-453C-A0CC-BAD98F44FEA0}.Release|Any CPU.Build.0 = Release|Any CPU | |||
EndGlobalSection | |||
GlobalSection(SolutionProperties) = preSolution | |||
HideSolutionNode = FALSE | |||
@@ -0,0 +1,23 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace Tensorflow | |||
{ | |||
public static partial class tf | |||
{ | |||
/// <summary> | |||
/// Inserts a dimension of 1 into a tensor's shape. | |||
/// </summary> | |||
/// <param name="input"></param> | |||
/// <param name="axis"></param> | |||
/// <param name="name"></param> | |||
/// <param name="dim"></param> | |||
/// <returns> | |||
/// A `Tensor` with the same data as `input`, but its shape has an additional | |||
/// dimension of size 1 added. | |||
/// </returns> | |||
public static Tensor expand_dims(Tensor input, int axis = -1, string name = "", int dim = -1) | |||
=> array_ops.expand_dims(input, axis, name, dim); | |||
} | |||
} |
@@ -0,0 +1,13 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace Tensorflow | |||
{ | |||
public partial class tf | |||
{ | |||
public static Tensor read_file(string filename, string name = "") => gen_io_ops.read_file(filename, name); | |||
public static gen_image_ops image => new gen_image_ops(); | |||
} | |||
} |
@@ -6,9 +6,6 @@ namespace Tensorflow | |||
{ | |||
public static partial class tf | |||
{ | |||
public static unsafe Tensor matmul(Tensor a, Tensor b) | |||
{ | |||
return gen_math_ops.mat_mul(a, b); | |||
} | |||
public static unsafe Tensor matmul(Tensor a, Tensor b) => gen_math_ops.mat_mul(a, b); | |||
} | |||
} |
@@ -6,25 +6,19 @@ namespace Tensorflow | |||
{ | |||
public static partial class tf | |||
{ | |||
public static Tensor add(Tensor a, Tensor b) | |||
{ | |||
return gen_math_ops.add(a, b); | |||
} | |||
public static Tensor sub(Tensor a, Tensor b) | |||
{ | |||
return gen_math_ops.sub(a, b); | |||
} | |||
public static Tensor multiply(Tensor x, Tensor y) | |||
{ | |||
return gen_math_ops.mul(x, y); | |||
} | |||
public static Tensor pow(Tensor x, double y) | |||
{ | |||
return gen_math_ops.pow(x, y); | |||
} | |||
public static Tensor add(Tensor a, Tensor b) => gen_math_ops.add(a, b); | |||
public static Tensor sub(Tensor a, Tensor b) => gen_math_ops.sub(a, b); | |||
public static Tensor subtract<T>(Tensor x, T[] y, string name = "") where T : struct | |||
=> gen_math_ops.sub(x, ops.convert_to_tensor(y, dtype: x.dtype.as_base_dtype(), name: "y"), name); | |||
public static Tensor multiply(Tensor x, Tensor y) => gen_math_ops.mul(x, y); | |||
public static Tensor divide<T>(Tensor x, T[] y, string name = "") where T : struct | |||
=> x / ops.convert_to_tensor(y, dtype: x.dtype.as_base_dtype(), name: "y"); | |||
public static Tensor pow(Tensor x, double y) => gen_math_ops.pow(x, y); | |||
/// <summary> | |||
/// Computes the sum of elements across dimensions of a tensor. | |||
@@ -32,9 +26,9 @@ namespace Tensorflow | |||
/// <param name="input"></param> | |||
/// <param name="axis"></param> | |||
/// <returns></returns> | |||
public static Tensor reduce_sum(Tensor input, int[] axis = null) | |||
{ | |||
return math_ops.reduce_sum(input); | |||
} | |||
public static Tensor reduce_sum(Tensor input, int[] axis = null) => math_ops.reduce_sum(input); | |||
public static Tensor cast(Tensor x, TF_DataType dtype = TF_DataType.DtInvalid, string name = "") | |||
=> math_ops.cast(x, dtype, name); | |||
} | |||
} |
@@ -28,8 +28,8 @@ namespace Tensorflow | |||
var graph = ops.get_default_graph(); | |||
Python.with<ops.name_scope>(new ops.name_scope(name, "import", input_map.Values), scope => | |||
{ | |||
/*prefix = scope; | |||
if (!string.IsNullOrEmpty(prefix)) | |||
prefix = scope; | |||
/*if (!string.IsNullOrEmpty(prefix)) | |||
prefix = prefix.Substring(0, prefix.Length - 1); | |||
else | |||
prefix = "";*/ | |||
@@ -113,9 +113,16 @@ namespace Tensorflow | |||
var key = attr_def.Name; | |||
if(attr_def.DefaultValue != null) | |||
{ | |||
var value = node_def.Attr[key]; | |||
if (value == null) | |||
if (node_def.Attr.ContainsKey(key)) | |||
{ | |||
var value = node_def.Attr[key]; | |||
if (value == null) | |||
node_def.Attr[key] = attr_def.DefaultValue; | |||
} | |||
else | |||
{ | |||
node_def.Attr[key] = attr_def.DefaultValue; | |||
} | |||
} | |||
} | |||
} | |||
@@ -24,6 +24,9 @@ namespace Tensorflow | |||
return c_api.TF_NewOperation(_handle, opType, opName); | |||
} | |||
public Operation get_operation_by_name(string name) | |||
=> as_graph_element(name, allow_tensor: false, allow_operation: true) as Operation; | |||
public ITensorOrOperation _get_operation_by_name_unsafe(string name) | |||
{ | |||
return _nodes_by_name.ContainsKey(name) ? _nodes_by_name[name] : null; | |||
@@ -46,6 +46,10 @@ namespace Tensorflow | |||
} | |||
} | |||
public static Tensor expand_dims(Tensor input, int axis = -1, string name = "", int dim = -1) => expand_dims_v2(input, axis, name); | |||
private static Tensor expand_dims_v2(Tensor input, int axis, string name = "") => gen_array_ops.expand_dims(input, axis, name); | |||
public static Tensor rank(Tensor input, string name = "") | |||
{ | |||
return math_ops.rank_internal(input, name, optimize: true); | |||
@@ -12,6 +12,13 @@ namespace Tensorflow | |||
public static OpDefLibrary _op_def_lib = new OpDefLibrary(); | |||
public static Execute _execute = new Execute(); | |||
public static Tensor expand_dims(Tensor input, int axis, string name = "") | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("ExpandDims", name: name, args: new { input, dim = axis }); | |||
return _op.outputs[0]; | |||
} | |||
public static Tensor greater<Tx, Ty>(Tx x, Ty y, string name = "") | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("Greater", name: name, args: new { x, y }); | |||
@@ -0,0 +1,61 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace Tensorflow | |||
{ | |||
public class gen_image_ops | |||
{ | |||
public static OpDefLibrary _op_def_lib = new OpDefLibrary(); | |||
public Tensor decode_jpeg(Tensor contents, | |||
int channels = 0, | |||
int ratio = 1, | |||
bool fancy_upscaling = true, | |||
bool try_recover_truncated = false, | |||
float acceptable_fraction = 1, | |||
string dct_method = "", | |||
string name = "") | |||
{ | |||
// Add nodes to the TensorFlow graph. | |||
if (tf.context.executing_eagerly()) | |||
{ | |||
throw new NotImplementedException("decode_jpeg"); | |||
} | |||
else | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("DecodeJpeg", name: name, args: new | |||
{ | |||
contents, | |||
channels, | |||
ratio, | |||
fancy_upscaling, | |||
try_recover_truncated, | |||
acceptable_fraction, | |||
dct_method | |||
}); | |||
return _op.outputs[0]; | |||
} | |||
} | |||
public Tensor resize_bilinear(Tensor images, int[] size, bool align_corners = false, string name = "") | |||
{ | |||
if (tf.context.executing_eagerly()) | |||
{ | |||
throw new NotImplementedException("resize_bilinear"); | |||
} | |||
else | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("ResizeBilinear", name: name, args: new | |||
{ | |||
images, | |||
size, | |||
align_corners | |||
}); | |||
return _op.outputs[0]; | |||
} | |||
} | |||
} | |||
} |
@@ -21,5 +21,12 @@ namespace Tensorflow | |||
return _op.outputs; | |||
} | |||
public static Tensor read_file(string filename, string name = "") | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("ReadFile", name: name, args: new { filename }); | |||
return _op.outputs[0]; | |||
} | |||
} | |||
} |
@@ -17,6 +17,13 @@ namespace Tensorflow | |||
return _op.outputs[0]; | |||
} | |||
public static Tensor cast(Tensor x, TF_DataType DstT, bool Truncate= false, string name= "") | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("Cast", name, args: new { x, DstT, Truncate }); | |||
return _op.outputs[0]; | |||
} | |||
public static Tensor neg(Tensor x, string name = "") | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("Neg", name, args: new { x }); | |||
@@ -4,7 +4,7 @@ using System.Text; | |||
namespace Tensorflow | |||
{ | |||
public class math_ops | |||
public class math_ops : Python | |||
{ | |||
public static Tensor add(Tensor x, Tensor y, string name = "") => gen_math_ops.add(x, y, name); | |||
@@ -14,7 +14,14 @@ namespace Tensorflow | |||
if(base_type == x.dtype) | |||
return x; | |||
throw new NotImplementedException("math_ops.cast"); | |||
return with<ops.name_scope, Tensor>(new ops.name_scope(name, "Cast", new { x }), scope => | |||
{ | |||
x = ops.convert_to_tensor(x, name: "x"); | |||
if (x.dtype.as_base_dtype() != base_type) | |||
x = gen_math_ops.cast(x, base_type, name: name); | |||
return x; | |||
}); | |||
} | |||
/// <summary> | |||
@@ -35,8 +35,7 @@ namespace Tensorflow | |||
c_api.TF_DeleteSessionOptions(opts); | |||
} | |||
public virtual NDArray run(object fetches, FeedItem[] feed_dict = null) | |||
public virtual NDArray run(object fetches, params FeedItem[] feed_dict) | |||
{ | |||
return _run(fetches, feed_dict); | |||
} | |||
@@ -62,6 +61,9 @@ namespace Tensorflow | |||
var subfeed_dtype = subfeed_t.dtype.as_numpy_datatype(); | |||
switch (subfeed_val) | |||
{ | |||
case NDArray nd: | |||
feed_dict_tensor[subfeed_t] = nd; | |||
break; | |||
case float floatVal: | |||
feed_dict_tensor[subfeed_t] = (NDArray)floatVal; | |||
break; | |||
@@ -193,25 +195,25 @@ namespace Tensorflow | |||
case TF_DataType.TF_INT16: | |||
var shorts = new short[tensor.size]; | |||
for (ulong i = 0; i < tensor.size; i++) | |||
shorts[i] = *(short*)(c_api.TF_TensorData(output) + (int)(tensor.dataTypeSize * i)); | |||
shorts[i] = *(short*)(c_api.TF_TensorData(output) + (int)(tensor.itemsize * i)); | |||
nd = np.array(shorts).reshape(ndims); | |||
break; | |||
case TF_DataType.TF_INT32: | |||
var ints = new int[tensor.size]; | |||
for (ulong i = 0; i < tensor.size; i++) | |||
ints[i] = *(int*)(c_api.TF_TensorData(output) + (int)(tensor.dataTypeSize * i)); | |||
ints[i] = *(int*)(c_api.TF_TensorData(output) + (int)(tensor.itemsize * i)); | |||
nd = np.array(ints).reshape(ndims); | |||
break; | |||
case TF_DataType.TF_FLOAT: | |||
var floats = new float[tensor.size]; | |||
for (ulong i = 0; i < tensor.size; i++) | |||
floats[i] = *(float*)(c_api.TF_TensorData(output) + (int)(tensor.dataTypeSize * i)); | |||
floats[i] = *(float*)(c_api.TF_TensorData(output) + (int)(tensor.itemsize * i)); | |||
nd = np.array(floats).reshape(ndims); | |||
break; | |||
case TF_DataType.TF_DOUBLE: | |||
var doubles = new double[tensor.size]; | |||
for (ulong i = 0; i < tensor.size; i++) | |||
doubles[i] = *(double*)(c_api.TF_TensorData(output) + (int)(tensor.dataTypeSize * i)); | |||
doubles[i] = *(double*)(c_api.TF_TensorData(output) + (int)(tensor.itemsize * i)); | |||
nd = np.array(doubles).reshape(ndims); | |||
break; | |||
default: | |||
@@ -35,8 +35,8 @@ namespace Tensorflow | |||
private TF_DataType _dtype = TF_DataType.DtInvalid; | |||
public TF_DataType dtype => _handle == IntPtr.Zero ? _dtype : c_api.TF_TensorType(_handle); | |||
public ulong bytesize => _handle == IntPtr.Zero ? 0 : c_api.TF_TensorByteSize(_handle); | |||
public ulong dataTypeSize => _handle == IntPtr.Zero ? 0 : c_api.TF_DataTypeSize(dtype); | |||
public ulong size => _handle == IntPtr.Zero ? 0 : bytesize / dataTypeSize; | |||
public ulong itemsize => _handle == IntPtr.Zero ? 0 : c_api.TF_DataTypeSize(dtype); | |||
public ulong size => _handle == IntPtr.Zero ? 0 : bytesize / itemsize; | |||
public IntPtr buffer => _handle == IntPtr.Zero ? IntPtr.Zero : c_api.TF_TensorData(_handle); | |||
public int num_consumers(TF_Output oper_out) => _handle == IntPtr.Zero ? 0 : c_api.TF_OperationOutputNumConsumers(oper_out); | |||
@@ -122,7 +122,7 @@ namespace Tensorflow | |||
for (ulong i = 0; i < size; i++) | |||
{ | |||
data[i] = Marshal.PtrToStructure<T>(buffer + (int)(i * dataTypeSize)); | |||
data[i] = Marshal.PtrToStructure<T>(buffer + (int)(i * itemsize)); | |||
} | |||
return data; | |||
@@ -21,7 +21,7 @@ namespace Tensorflow | |||
case TF_DataType.TF_STRING: | |||
return typeof(string); | |||
default: | |||
throw new NotImplementedException("as_numpy_datatype failed"); | |||
return null; | |||
} | |||
} | |||
@@ -44,6 +44,7 @@ namespace Tensorflow | |||
// We first convert value to a numpy array or scalar. | |||
NDArray nparray = null; | |||
var np_dt = dtype.as_numpy_datatype(); | |||
if (values is NDArray nd) | |||
{ | |||
@@ -54,31 +55,61 @@ namespace Tensorflow | |||
if (values == null) | |||
throw new ValueError("None values not supported."); | |||
switch (values) | |||
if(np_dt == null) | |||
{ | |||
case bool boolVal: | |||
nparray = boolVal; | |||
break; | |||
case int intVal: | |||
nparray = intVal; | |||
break; | |||
case int[] intVals: | |||
nparray = np.array(intVals); | |||
break; | |||
case float floatVal: | |||
nparray = floatVal; | |||
break; | |||
case double doubleVal: | |||
nparray = doubleVal; | |||
break; | |||
case string strVal: | |||
nparray = strVal; | |||
break; | |||
case string[] strVals: | |||
nparray = strVals; | |||
break; | |||
default: | |||
throw new Exception("make_tensor_proto Not Implemented"); | |||
switch (values) | |||
{ | |||
case bool boolVal: | |||
nparray = boolVal; | |||
break; | |||
case int intVal: | |||
nparray = intVal; | |||
break; | |||
case int[] intVals: | |||
nparray = np.array(intVals); | |||
break; | |||
case float floatVal: | |||
nparray = floatVal; | |||
break; | |||
case double doubleVal: | |||
nparray = doubleVal; | |||
break; | |||
case string strVal: | |||
nparray = strVal; | |||
break; | |||
case string[] strVals: | |||
nparray = strVals; | |||
break; | |||
default: | |||
throw new NotImplementedException("make_tensor_proto Not Implemented"); | |||
} | |||
} | |||
else | |||
{ | |||
// convert data type | |||
switch (np_dt.Name) | |||
{ | |||
case "Int32": | |||
if (values.GetType().IsArray) | |||
nparray = np.array((int[])values, np_dt); | |||
else | |||
nparray = (int)values; | |||
break; | |||
case "Single": | |||
if (values.GetType().IsArray) | |||
nparray = np.array((float[])values, np_dt); | |||
else | |||
nparray = (float)values; | |||
break; | |||
case "Double": | |||
nparray = (double)values; | |||
break; | |||
case "String": | |||
nparray = values.ToString(); | |||
break; | |||
default: | |||
throw new NotImplementedException("make_tensor_proto Not Implemented"); | |||
} | |||
} | |||
} | |||
@@ -169,9 +169,9 @@ namespace Tensorflow | |||
if (!_is_empty) | |||
{ | |||
model_checkpoint_path = sess.run(_saver_def.SaveTensorName, new FeedItem[] { | |||
model_checkpoint_path = sess.run(_saver_def.SaveTensorName, | |||
new FeedItem(_saver_def.FilenameTensorName, checkpoint_file) | |||
}); | |||
); | |||
if (write_state) | |||
{ | |||
@@ -227,10 +227,8 @@ namespace Tensorflow | |||
if (tf.context.executing_eagerly()) | |||
; | |||
else | |||
sess.run(_saver_def.RestoreOpName, new FeedItem[] | |||
{ | |||
new FeedItem(_saver_def.FilenameTensorName, save_path) | |||
}); | |||
sess.run(_saver_def.RestoreOpName, | |||
new FeedItem(_saver_def.FilenameTensorName, save_path)); | |||
} | |||
/// <summary> | |||
@@ -418,6 +418,9 @@ namespace Tensorflow | |||
string name = "", TF_DataType preferred_dtype = TF_DataType.DtInvalid, | |||
bool as_ref = false) | |||
{ | |||
if (dtype == TF_DataType.DtInvalid) | |||
dtype = preferred_dtype; | |||
switch (value) | |||
{ | |||
case Tensor tensor: | |||
@@ -432,6 +435,8 @@ namespace Tensorflow | |||
return constant_op.constant(intArray, dtype: dtype, name: name); | |||
case float floatVal: | |||
return constant_op.constant(floatVal, dtype: dtype, name: name); | |||
case float[] floatArray: | |||
return constant_op.constant(floatArray, dtype: dtype, name: name); | |||
case double doubleVal: | |||
return constant_op.constant(doubleVal, dtype: dtype, name: name); | |||
case RefVariable varVal: | |||
@@ -0,0 +1,37 @@ | |||
using ICSharpCode.SharpZipLib.GZip; | |||
using ICSharpCode.SharpZipLib.Tar; | |||
using System; | |||
using System.IO; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
namespace TensorFlowNET.Utility | |||
{ | |||
public class Compress | |||
{ | |||
public static void ExtractTGZ(String gzArchiveName, String destFolder) | |||
{ | |||
Console.WriteLine($"Extracting."); | |||
var task = Task.Run(() => | |||
{ | |||
using (var inStream = File.OpenRead(gzArchiveName)) | |||
{ | |||
using (var gzipStream = new GZipInputStream(inStream)) | |||
{ | |||
using (TarArchive tarArchive = TarArchive.CreateInputTarArchive(gzipStream)) | |||
tarArchive.ExtractContents(destFolder); | |||
} | |||
} | |||
}); | |||
while (!task.IsCompleted) | |||
{ | |||
Thread.Sleep(200); | |||
Console.Write("."); | |||
} | |||
Console.WriteLine(""); | |||
Console.WriteLine("Extracting is completed."); | |||
} | |||
} | |||
} |
@@ -0,0 +1,13 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>netstandard2.0</TargetFramework> | |||
<AssemblyName>TensorFlowNET.Utility</AssemblyName> | |||
<RootNamespace>TensorFlowNET.Utility</RootNamespace> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<PackageReference Include="SharpZipLib" Version="1.1.0" /> | |||
</ItemGroup> | |||
</Project> |
@@ -0,0 +1,35 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using System.Net; | |||
using System.Text; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
namespace TensorFlowNET.Utility | |||
{ | |||
public class Web | |||
{ | |||
public static bool Download(string url, string file) | |||
{ | |||
if (File.Exists(file)) | |||
{ | |||
Console.WriteLine($"{file} already exists."); | |||
return false; | |||
} | |||
var wc = new WebClient(); | |||
Console.WriteLine($"Downloading {file}"); | |||
var download = Task.Run(() => wc.DownloadFile(url, file)); | |||
while (!download.IsCompleted) | |||
{ | |||
Thread.Sleep(1000); | |||
Console.Write("."); | |||
} | |||
Console.WriteLine(""); | |||
Console.WriteLine($"Downloaded {file}"); | |||
return true; | |||
} | |||
} | |||
} |
@@ -0,0 +1,120 @@ | |||
using ICSharpCode.SharpZipLib.GZip; | |||
using ICSharpCode.SharpZipLib.Tar; | |||
using NumSharp.Core; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.IO; | |||
using System.Linq; | |||
using System.Net; | |||
using System.Text; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
using Tensorflow; | |||
namespace TensorFlowNET.Examples | |||
{ | |||
/// <summary> | |||
/// Port from tensorflow\examples\label_image\label_image.py | |||
/// </summary> | |||
public class LabelImage : Python, IExample | |||
{ | |||
string dir = "label_image_data"; | |||
string pbFile = "inception_v3_2016_08_28_frozen.pb"; | |||
string labelFile = "imagenet_slim_labels.txt"; | |||
string picFile = "grace_hopper.jpg"; | |||
int input_height = 299; | |||
int input_width = 299; | |||
int input_mean = 0; | |||
int input_std = 255; | |||
string input_layer = "input"; | |||
string output_layer = "InceptionV3/Predictions/Reshape_1"; | |||
public void Run() | |||
{ | |||
PrepareData(); | |||
var graph = LoadGraph(Path.Join(dir, pbFile)); | |||
var t = ReadTensorFromImageFile(Path.Join(dir, picFile), | |||
input_height: input_height, | |||
input_width: input_width, | |||
input_mean: input_mean, | |||
input_std: input_std); | |||
var input_name = "import/" + input_layer; | |||
var output_name = "import/" + output_layer; | |||
var input_operation = graph.get_operation_by_name(input_name); | |||
var output_operation = graph.get_operation_by_name(output_name); | |||
NDArray results = null; | |||
with<Session>(tf.Session(graph), sess => | |||
{ | |||
results = sess.run(output_operation.outputs[0], new FeedItem(input_operation.outputs[0], t)); | |||
}); | |||
// equivalent np.squeeze | |||
results.reshape(results.shape.Where(x => x > 1).ToArray()); | |||
// top_k = results.argsort()[-5:][::-1] | |||
var top_k = results.Data<int>().Take(5).ToArray(); | |||
var labels = LoadLabels(Path.Join(dir, labelFile)); | |||
foreach (var i in top_k) | |||
Console.WriteLine($"{labels[i]}, {results[i]}"); | |||
} | |||
private string[] LoadLabels(string file) | |||
{ | |||
return File.ReadAllLines(file); | |||
} | |||
private Graph LoadGraph(string modelFile) | |||
{ | |||
var graph = tf.Graph(); | |||
var graph_def = GraphDef.Parser.ParseFrom(File.ReadAllBytes(modelFile)); | |||
importer.import_graph_def(graph_def); | |||
return graph; | |||
} | |||
private NDArray ReadTensorFromImageFile(string file_name, | |||
int input_height = 299, | |||
int input_width = 299, | |||
int input_mean = 0, | |||
int input_std = 255) | |||
{ | |||
string input_name = "file_reader"; | |||
string output_name = "normalized"; | |||
Tensor image_reader = null; | |||
var file_reader = tf.read_file(file_name, input_name); | |||
image_reader = tf.image.decode_jpeg(file_reader, channels: 3, name: "jpeg_reader"); | |||
var float_caster = tf.cast(image_reader, tf.float32); | |||
var dims_expander = tf.expand_dims(float_caster, 0); | |||
var resized = tf.image.resize_bilinear(dims_expander, new int[] { input_height, input_width }); | |||
var normalized = tf.divide(tf.subtract(resized, new float[] { input_mean }), new float[] { input_std }); | |||
return with<Session, NDArray>(tf.Session(), sess => | |||
{ | |||
var result = sess.run(normalized); | |||
return result; | |||
}); | |||
} | |||
private void PrepareData() | |||
{ | |||
Directory.CreateDirectory(dir); | |||
// get model file | |||
string url = "https://storage.googleapis.com/download.tensorflow.org/models/inception_v3_2016_08_28_frozen.pb.tar.gz"; | |||
string zipFile = Path.Join(dir, $"{pbFile}.tar.gz"); | |||
Utility.Web.Download(url, zipFile); | |||
if (!File.Exists(Path.Join(dir, pbFile))) | |||
Utility.Compress.ExtractTGZ(zipFile, dir); | |||
// download sample picture | |||
string pic = "grace_hopper.jpg"; | |||
Utility.Web.Download($"https://raw.githubusercontent.com/tensorflow/tensorflow/master/tensorflow/examples/label_image/data/{pic}", Path.Join(dir, pic)); | |||
} | |||
} | |||
} |
@@ -65,21 +65,17 @@ namespace TensorFlowNET.Examples | |||
{ | |||
foreach (var (x, y) in Python.zip<double>(train_X, train_Y)) | |||
{ | |||
sess.run(optimizer, feed_dict: new FeedItem[] | |||
{ | |||
sess.run(optimizer, | |||
new FeedItem(X, x), | |||
new FeedItem(Y, y) | |||
}); | |||
new FeedItem(Y, y)); | |||
} | |||
// Display logs per epoch step | |||
if ((epoch + 1) % display_step == 0) | |||
{ | |||
var c = sess.run(cost, feed_dict: new FeedItem[] | |||
{ | |||
var c = sess.run(cost, | |||
new FeedItem(X, train_X), | |||
new FeedItem(Y, train_Y) | |||
}); | |||
new FeedItem(Y, train_Y)); | |||
var rW = sess.run(W); | |||
Console.WriteLine($"Epoch: {epoch + 1} cost={c} " + | |||
$"W={rW} b={sess.run(b)}"); | |||
@@ -12,6 +12,7 @@ | |||
<ItemGroup> | |||
<ProjectReference Include="..\..\src\TensorFlowNET.Core\TensorFlowNET.Core.csproj" /> | |||
<ProjectReference Include="..\..\src\TensorFlowNET.Utility\TensorFlowNET.Utility.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@@ -33,11 +33,9 @@ namespace TensorFlowNET.UnitTest | |||
using(var sess = tf.Session()) | |||
{ | |||
var o = sess.run(c, feed_dict: new FeedItem[] | |||
{ | |||
var o = sess.run(c, | |||
new FeedItem(a, 3.0f), | |||
new FeedItem(b, 2.0f) | |||
}); | |||
new FeedItem(b, 2.0f)); | |||
Assert.AreEqual((float)o, 5.0f); | |||
} | |||
} | |||
@@ -17,10 +17,8 @@ namespace TensorFlowNET.UnitTest | |||
Python.with<Session>(tf.Session(), sess => | |||
{ | |||
var result = sess.run(y, feed_dict: new FeedItem[] | |||
{ | |||
new FeedItem(x, 2) | |||
}); | |||
var result = sess.run(y, | |||
new FeedItem(x, 2)); | |||
Assert.AreEqual((int)result, 6); | |||
}); | |||
} | |||