Browse Source

merge from master

tags/v0.12
Oceania2018 6 years ago
parent
commit
07bed359b9
13 changed files with 85 additions and 72 deletions
  1. +2
    -2
      src/TensorFlowHub/TensorFlowHub.csproj
  2. +7
    -15
      src/TensorFlowHub/Utils.cs
  3. +3
    -0
      src/TensorFlowNET.Core/APIs/tf.math.cs
  4. +9
    -2
      src/TensorFlowNET.Core/Graphs/DefaultGraphStack.cs
  5. +19
    -21
      src/TensorFlowNET.Core/Graphs/Graph.cs
  6. +1
    -1
      src/TensorFlowNET.Core/Operations/Operation.cs
  7. +7
    -0
      src/TensorFlowNET.Core/Operations/gen_math_ops.cs
  8. +2
    -3
      src/TensorFlowNET.Core/Sessions/BaseSession.cs
  9. +2
    -2
      src/TensorFlowNET.Core/Sessions/Session.cs
  10. +1
    -1
      src/TensorFlowNET.Core/TensorFlowNET.Core.csproj
  11. +18
    -23
      test/TensorFlowNET.Examples/ImageProcessing/RetrainImageClassifier.cs
  12. +4
    -1
      test/TensorFlowNET.UnitTest/NameScopeTest.cs
  13. +10
    -1
      test/TensorFlowNET.UnitTest/OperationsTest.cs

+ 2
- 2
src/TensorFlowHub/TensorFlowHub.csproj View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<RootNamespace>Tensorflow.Hub</RootNamespace>
<TargetFramework>netstandard2.0</TargetFramework>
<Version>0.0.1</Version>
<Version>0.0.2</Version>
<Authors>Kerry Jiang</Authors>
<Company>SciSharp STACK</Company>
<Copyright>Apache 2.0</Copyright>
@@ -13,7 +13,7 @@
<Description>TensorFlow Hub is a library to foster the publication, discovery, and consumption of reusable parts of machine learning models.</Description>
<PackageId>SciSharp.TensorFlowHub</PackageId>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageReleaseNotes>1. Add MNIST loader.</PackageReleaseNotes>
<PackageReleaseNotes></PackageReleaseNotes>
<PackageIconUrl>https://avatars3.githubusercontent.com/u/44989469?s=200&amp;v=4</PackageIconUrl>
</PropertyGroup>
<ItemGroup>


+ 7
- 15
src/TensorFlowHub/Utils.cs View File

@@ -28,20 +28,13 @@ namespace Tensorflow.Hub
var fileSaveTo = Path.Combine(dirSaveTo, fileName);

if (File.Exists(fileSaveTo))
return;
Directory.CreateDirectory(dirSaveTo);
using (var wc = new WebClient())
{
//TODO:maybe you can check file's hashcode and "donglowad.info" to complete file ...
Console.WriteLine($"{fileSaveTo} already exists.");
}
else
{
if (!Directory.Exists(dirSaveTo))
Directory.CreateDirectory(dirSaveTo);

using (var wc = new WebClient())
{
await wc.DownloadFileTaskAsync(url, fileSaveTo);
}

await wc.DownloadFileTaskAsync(url, fileSaveTo);
}

}
@@ -52,8 +45,7 @@ namespace Tensorflow.Hub
if (!Path.IsPathRooted(saveTo))
saveTo = Path.Combine(AppContext.BaseDirectory, saveTo);

if (!Directory.Exists(saveTo))
Directory.CreateDirectory(saveTo);
Directory.CreateDirectory(saveTo);

if (!Path.IsPathRooted(zipFile))
zipFile = Path.Combine(AppContext.BaseDirectory, zipFile);


+ 3
- 0
src/TensorFlowNET.Core/APIs/tf.math.cs View File

@@ -192,6 +192,9 @@ namespace Tensorflow
public static Tensor logical_and(Tensor x, Tensor y, string name = null)
=> gen_math_ops.logical_and(x, y, name);

public static Tensor logical_not(Tensor x, string name = null)
=> gen_math_ops.logical_not(x, name);

/// <summary>
/// Clips tensor values to a specified min and max.
/// </summary>


+ 9
- 2
src/TensorFlowNET.Core/Graphs/DefaultGraphStack.cs View File

@@ -34,10 +34,17 @@ namespace Tensorflow

public Graph get_controller()
{
if (stack.Count == 0)
if (stack.Count(x => x.IsDefault) == 0)
stack.Add(new StackModel { Graph = tf.Graph(), IsDefault = true });

return stack.First(x => x.IsDefault).Graph;
return stack.Last(x => x.IsDefault).Graph;
}

public bool remove(Graph g)
{
var sm = stack.FirstOrDefault(x => x.Graph == g);
if (sm == null) return false;
return stack.Remove(sm);
}

public void reset()


+ 19
- 21
src/TensorFlowNET.Core/Graphs/Graph.cs View File

@@ -73,9 +73,8 @@ namespace Tensorflow
all variables that are created during the construction of a graph. The caller
may define additional collections by specifying a new name.
*/
public partial class Graph : IPython, IDisposable, IEnumerable<Operation>
public partial class Graph : DisposableObject, IEnumerable<Operation>
{
private IntPtr _handle;
private Dictionary<int, ITensorOrOperation> _nodes_by_id;
public Dictionary<string, ITensorOrOperation> _nodes_by_name;
private Dictionary<string, int> _names_in_use;
@@ -121,10 +120,6 @@ namespace Tensorflow
_graph_key = $"grap-key-{ops.uid()}/";
}
public void __enter__()
{
}

public ITensorOrOperation as_graph_element(object obj, bool allow_tensor = true, bool allow_operation = true)
{
return _as_graph_element_locked(obj, allow_tensor, allow_operation);
@@ -443,14 +438,15 @@ namespace Tensorflow
_unfetchable_ops.Add(op);
}
public void Dispose()
{
/*if (_handle != IntPtr.Zero)
c_api.TF_DeleteGraph(_handle);

_handle = IntPtr.Zero;

GC.SuppressFinalize(this);*/
protected override void DisposeManagedState()
{
ops.default_graph_stack.remove(this);
}
protected override void DisposeUnManagedState(IntPtr handle)
{
Console.WriteLine($"Destroy graph {handle}");
c_api.TF_DeleteGraph(handle);
}

/// <summary>
@@ -481,17 +477,19 @@ namespace Tensorflow
return new TensorShape(dims.Select(x => (int)x).ToArray());
}
string debugString = string.Empty;
public override string ToString()
{
int len = 0;
return c_api.TF_GraphDebugString(_handle, out len);
return $"{graph_key}, ({_handle})";
/*if (string.IsNullOrEmpty(debugString))
{
int len = 0;
debugString = c_api.TF_GraphDebugString(_handle, out len);
}
return debugString;*/
}

public void __exit__()
{
}
private IEnumerable<Operation> GetEnumerable()
=> c_api_util.tf_operations(this);



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

@@ -84,7 +84,7 @@ namespace Tensorflow

// Dict mapping op name to file and line information for op colocation
// context managers.
_control_flow_context = graph._get_control_flow_context();
_control_flow_context = _graph._get_control_flow_context();

// Note: _control_flow_post_processing() must not be called here, the caller is responsible for calling it when using this constructor.
}


+ 7
- 0
src/TensorFlowNET.Core/Operations/gen_math_ops.cs View File

@@ -357,6 +357,13 @@ namespace Tensorflow
return _op.outputs[0];
}
public static Tensor logical_not(Tensor x, string name = null)
{
var _op = _op_def_lib._apply_op_helper("LogicalNot", name, args: new { x });
return _op.outputs[0];
}
public static Tensor squared_difference(Tensor x, Tensor y, string name = null)
{
var _op = _op_def_lib._apply_op_helper("SquaredDifference", name, args: new { x, y, name });


+ 2
- 3
src/TensorFlowNET.Core/Sessions/BaseSession.cs View File

@@ -31,7 +31,6 @@ namespace Tensorflow
protected bool _closed;
protected int _current_version;
protected byte[] _target;
protected IntPtr _session;
public Graph graph => _graph;
public BaseSession(string target = "", Graph g = null, SessionOptions opts = null)
@@ -46,7 +45,7 @@ namespace Tensorflow
var status = new Status();
_session = c_api.TF_NewSession(_graph, opts ?? newOpts, status);
_handle = c_api.TF_NewSession(_graph, opts ?? newOpts, status);
// dispose newOpts
if (opts == null)
@@ -216,7 +215,7 @@ namespace Tensorflow
var output_values = fetch_list.Select(x => IntPtr.Zero).ToArray();
c_api.TF_SessionRun(_session,
c_api.TF_SessionRun(_handle,
run_options: null,
inputs: feed_dict.Select(f => f.Key).ToArray(),
input_values: feed_dict.Select(f => (IntPtr)f.Value).ToArray(),


+ 2
- 2
src/TensorFlowNET.Core/Sessions/Session.cs View File

@@ -30,7 +30,7 @@ namespace Tensorflow
public Session(IntPtr handle, Graph g = null)
: base("", g, null)
{
_session = handle;
_handle = handle;
}

public Session(Graph g, SessionOptions opts = null, Status s = null)
@@ -73,7 +73,7 @@ namespace Tensorflow
return new Session(sess, g: new Graph(graph).as_default());
}

public static implicit operator IntPtr(Session session) => session._session;
public static implicit operator IntPtr(Session session) => session._handle;
public static implicit operator Session(IntPtr handle) => new Session(handle);

public void __enter__()


+ 1
- 1
src/TensorFlowNET.Core/TensorFlowNET.Core.csproj View File

@@ -37,7 +37,7 @@ Docs: https://tensorflownet.readthedocs.io</Description>
15. Fix Tensor memory leak.
16. Rename with to tf_with that is only used to build graph purpose.</PackageReleaseNotes>
<LangVersion>7.3</LangVersion>
<FileVersion>0.10.9.0</FileVersion>
<FileVersion>0.10.10.0</FileVersion>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<SignAssembly>true</SignAssembly>


+ 18
- 23
test/TensorFlowNET.Examples/ImageProcessing/RetrainImageClassifier.cs View File

@@ -52,7 +52,8 @@ namespace TensorFlowNET.Examples
// The location where variable checkpoints will be stored.
string CHECKPOINT_NAME = Path.Join(data_dir, "_retrain_checkpoint");
string tfhub_module = "https://tfhub.dev/google/imagenet/inception_v3/feature_vector/3";
string final_tensor_name = "final_result";
string input_tensor_name = "Placeholder";
string final_tensor_name = "Score";
float testing_percentage = 0.1f;
float validation_percentage = 0.1f;
float learning_rate = 0.01f;
@@ -81,13 +82,13 @@ namespace TensorFlowNET.Examples
PrepareData();

#region For debug purpose
// predict images
// Predict(null);

// load saved pb and test new images.
// Test(null);
#endregion

var graph = IsImportingGraph ? ImportGraph() : BuildGraph();
@@ -276,16 +277,13 @@ namespace TensorFlowNET.Examples
private (Graph, Tensor, Tensor, bool) create_module_graph()
{
var (height, width) = (299, 299);

return tf_with(tf.Graph().as_default(), graph =>
{
tf.train.import_meta_graph("graph/InceptionV3.meta");
Tensor resized_input_tensor = graph.OperationByName("Placeholder"); //tf.placeholder(tf.float32, new TensorShape(-1, height, width, 3));
// var m = hub.Module(module_spec);
Tensor bottleneck_tensor = graph.OperationByName("module_apply_default/hub_output/feature_vector/SpatialSqueeze");// m(resized_input_tensor);
var wants_quantization = false;
return (graph, bottleneck_tensor, resized_input_tensor, wants_quantization);
});
var graph = tf.Graph().as_default();
tf.train.import_meta_graph("graph/InceptionV3.meta");
Tensor resized_input_tensor = graph.OperationByName(input_tensor_name); //tf.placeholder(tf.float32, new TensorShape(-1, height, width, 3));
// var m = hub.Module(module_spec);
Tensor bottleneck_tensor = graph.OperationByName("module_apply_default/hub_output/feature_vector/SpatialSqueeze");// m(resized_input_tensor);
var wants_quantization = false;
return (graph, bottleneck_tensor, resized_input_tensor, wants_quantization);
}

private (NDArray, long[], string[]) get_random_cached_bottlenecks(Session sess, Dictionary<string, Dictionary<string, string[]>> image_lists,
@@ -594,13 +592,10 @@ namespace TensorFlowNET.Examples
create_module_graph();

// Add the new layer that we'll be training.
tf_with(graph.as_default(), delegate
{
(train_step, cross_entropy, bottleneck_input,
ground_truth_input, final_tensor) = add_final_retrain_ops(
class_count, final_tensor_name, bottleneck_tensor,
wants_quantization, is_training: true);
});
(train_step, cross_entropy, bottleneck_input,
ground_truth_input, final_tensor) = add_final_retrain_ops(
class_count, final_tensor_name, bottleneck_tensor,
wants_quantization, is_training: true);

return graph;
}
@@ -734,15 +729,15 @@ namespace TensorFlowNET.Examples
var labels = File.ReadAllLines(output_labels);

// predict image
var img_path = Path.Join(image_dir, "roses", "12240303_80d87f77a3_n.jpg");
var img_path = Path.Join(image_dir, "daisy", "5547758_eea9edfd54_n.jpg");
var fileBytes = ReadTensorFromImageFile(img_path);

// import graph and variables
var graph = new Graph();
graph.Import(output_graph, "");

Tensor input = graph.OperationByName("Placeholder");
Tensor output = graph.OperationByName("final_result");
Tensor input = graph.OperationByName(input_tensor_name);
Tensor output = graph.OperationByName(final_tensor_name);

using (var sess = tf.Session(graph))
{


+ 4
- 1
test/TensorFlowNET.UnitTest/NameScopeTest.cs View File

@@ -7,12 +7,13 @@ namespace TensorFlowNET.UnitTest
[TestClass]
public class NameScopeTest
{
Graph g = ops.get_default_graph();
string name = "";

[TestMethod]
public void NestedNameScope()
{
Graph g = tf.Graph().as_default();

tf_with(new ops.NameScope("scope1"), scope1 =>
{
name = scope1;
@@ -37,6 +38,8 @@ namespace TensorFlowNET.UnitTest
Assert.AreEqual("scope1/Const_1:0", const3.name);
});

g.Dispose();

Assert.AreEqual("", g._name_stack);
}
}


+ 10
- 1
test/TensorFlowNET.UnitTest/OperationsTest.cs View File

@@ -131,7 +131,7 @@ namespace TensorFlowNET.UnitTest
}

[TestMethod]
public void logicalAndTest()
public void logicalOpsTest()
{
var a = tf.constant(new[] {1f, 2f, 3f, 4f, -4f, -3f, -2f, -1f});
var b = tf.less(a, 0f);
@@ -144,6 +144,15 @@ namespace TensorFlowNET.UnitTest
var o = sess.run(d);
Assert.IsTrue(o.array_equal(check));
}

d = tf.cast(tf.logical_not(b), tf.int32);
check = np.array(new[] { 1, 1, 1, 1, 0, 0, 0, 0 });

using (var sess = tf.Session())
{
var o = sess.run(d);
Assert.IsTrue(o.array_equal(check));
}
}

[TestMethod]


Loading…
Cancel
Save