diff --git a/data/dbpedia_subset.zip b/data/dbpedia_subset.zip
new file mode 100644
index 00000000..e4ab6dda
Binary files /dev/null and b/data/dbpedia_subset.zip differ
diff --git a/data/lstm_crf_ner.zip b/data/lstm_crf_ner.zip
new file mode 100644
index 00000000..9e47ca93
Binary files /dev/null and b/data/lstm_crf_ner.zip differ
diff --git a/graph/lstm_crf_ner.meta b/graph/lstm_crf_ner.meta
new file mode 100644
index 00000000..19a267e2
Binary files /dev/null and b/graph/lstm_crf_ner.meta differ
diff --git a/graph/vd_cnn_untrained.meta b/graph/vd_cnn.meta
similarity index 89%
rename from graph/vd_cnn_untrained.meta
rename to graph/vd_cnn.meta
index dce64714..b857fc6c 100644
Binary files a/graph/vd_cnn_untrained.meta and b/graph/vd_cnn.meta differ
diff --git a/src/TensorFlowNET.Core/Estimator/HyperParams.cs b/src/TensorFlowNET.Core/Estimator/HyperParams.cs
index cf1c9c00..c1777e44 100644
--- a/src/TensorFlowNET.Core/Estimator/HyperParams.cs
+++ b/src/TensorFlowNET.Core/Estimator/HyperParams.cs
@@ -1,27 +1,92 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Text;
namespace Tensorflow.Estimator
{
public class HyperParams
{
- public string data_dir { get; set; }
- public string result_dir { get; set; }
- public string model_dir { get; set; }
- public string eval_dir { get; set; }
+ ///
+ /// root dir
+ ///
+ public string data_root_dir { get; set; }
+
+ ///
+ /// results dir
+ ///
+ public string result_dir { get; set; } = "results";
+
+ ///
+ /// model dir
+ ///
+ public string model_dir { get; set; } = "model";
+
+ public string eval_dir { get; set; } = "eval";
+
+ public string test_dir { get; set; } = "test";
public int dim { get; set; } = 300;
public float dropout { get; set; } = 0.5f;
public int num_oov_buckets { get; set; } = 1;
public int epochs { get; set; } = 25;
+ public int epoch_no_imprv { get; set; } = 3;
public int batch_size { get; set; } = 20;
public int buffer { get; set; } = 15000;
public int lstm_size { get; set; } = 100;
+ public string lr_method { get; set; } = "adam";
+ public float lr { get; set; } = 0.001f;
+ public float lr_decay { get; set; } = 0.9f;
+
+ ///
+ /// lstm on chars
+ ///
+ public int hidden_size_char { get; set; } = 100;
+
+ ///
+ /// lstm on word embeddings
+ ///
+ public int hidden_size_lstm { get; set; } = 300;
+
+ ///
+ /// is clipping
+ ///
+ public bool clip { get; set; } = false;
+
+ public string filepath_dev { get; set; }
+ public string filepath_test { get; set; }
+ public string filepath_train { get; set; }
+
+ public string filepath_words { get; set; }
+ public string filepath_chars { get; set; }
+ public string filepath_tags { get; set; }
+ public string filepath_glove { get; set; }
+
+ public HyperParams(string dataDir)
+ {
+ data_root_dir = dataDir;
+
+ if (string.IsNullOrEmpty(data_root_dir))
+ throw new ValueError("Please specifiy the root data directory");
+
+ if (!Directory.Exists(data_root_dir))
+ Directory.CreateDirectory(data_root_dir);
+
+ result_dir = Path.Combine(data_root_dir, result_dir);
+ if (!Directory.Exists(result_dir))
+ Directory.CreateDirectory(result_dir);
+
+ model_dir = Path.Combine(result_dir, model_dir);
+ if (!Directory.Exists(model_dir))
+ Directory.CreateDirectory(model_dir);
+
+ test_dir = Path.Combine(result_dir, test_dir);
+ if (!Directory.Exists(test_dir))
+ Directory.CreateDirectory(test_dir);
- public string words { get; set; }
- public string chars { get; set; }
- public string tags { get; set; }
- public string glove { get; set; }
+ eval_dir = Path.Combine(result_dir, eval_dir);
+ if (!Directory.Exists(eval_dir))
+ Directory.CreateDirectory(eval_dir);
+ }
}
}
diff --git a/src/TensorFlowNET.Core/Framework/meta_graph.py.cs b/src/TensorFlowNET.Core/Framework/meta_graph.py.cs
index ceebdc6e..799af2fa 100644
--- a/src/TensorFlowNET.Core/Framework/meta_graph.py.cs
+++ b/src/TensorFlowNET.Core/Framework/meta_graph.py.cs
@@ -101,9 +101,18 @@ namespace Tensorflow
switch (col.Key)
{
case "cond_context":
- var proto = CondContextDef.Parser.ParseFrom(value);
- var condContext = new CondContext().from_proto(proto, import_scope);
- graph.add_to_collection(col.Key, condContext);
+ {
+ var proto = CondContextDef.Parser.ParseFrom(value);
+ var condContext = new CondContext().from_proto(proto, import_scope);
+ graph.add_to_collection(col.Key, condContext);
+ }
+ break;
+ case "while_context":
+ {
+ var proto = WhileContextDef.Parser.ParseFrom(value);
+ var whileContext = new WhileContext().from_proto(proto, import_scope);
+ graph.add_to_collection(col.Key, whileContext);
+ }
break;
default:
throw new NotImplementedException("import_scoped_meta_graph_with_return_elements");
diff --git a/src/TensorFlowNET.Core/Gradients/math_grad.cs b/src/TensorFlowNET.Core/Gradients/math_grad.cs
index b63ea061..cac1c85e 100644
--- a/src/TensorFlowNET.Core/Gradients/math_grad.cs
+++ b/src/TensorFlowNET.Core/Gradients/math_grad.cs
@@ -32,6 +32,22 @@ namespace Tensorflow.Gradients
return new Tensor[] { r1, r2 };
}
+ ///
+ /// Returns grad * exp(x).
+ ///
+ ///
+ ///
+ ///
+ public static Tensor[] _ExpGrad(Operation op, Tensor[] grads)
+ {
+ var grad = grads[0];
+ var y = op.outputs[0]; // y = e^x
+ return with(ops.control_dependencies(new Operation[] { grad }), dp => {
+ y = math_ops.conj(y);
+ return new Tensor[] { math_ops.mul_no_nan(y, grad) };
+ });
+ }
+
public static Tensor[] _IdGrad(Operation op, Tensor[] grads)
{
return new Tensor[] { grads[0] };
diff --git a/src/TensorFlowNET.Core/Gradients/ops.gradient_function_mapping.cs b/src/TensorFlowNET.Core/Gradients/ops.gradient_function_mapping.cs
index 0c63300d..d01d47be 100644
--- a/src/TensorFlowNET.Core/Gradients/ops.gradient_function_mapping.cs
+++ b/src/TensorFlowNET.Core/Gradients/ops.gradient_function_mapping.cs
@@ -22,6 +22,8 @@ namespace Tensorflow
return math_grad._AddGrad(oper, out_grads);
case "BiasAdd":
return nn_grad._BiasAddGrad(oper, out_grads);
+ case "Exp":
+ return math_grad._ExpGrad(oper, out_grads);
case "Identity":
return math_grad._IdGrad(oper, out_grads);
case "Log":
diff --git a/src/TensorFlowNET.Core/Graphs/Graph.cs b/src/TensorFlowNET.Core/Graphs/Graph.cs
index ab228c47..c84684e6 100644
--- a/src/TensorFlowNET.Core/Graphs/Graph.cs
+++ b/src/TensorFlowNET.Core/Graphs/Graph.cs
@@ -160,7 +160,14 @@ namespace Tensorflow
}
else if (!name.Contains(":") & !allow_operation)
{
- throw new NotImplementedException("_as_graph_element_locked");
+ // Looks like an Operation name but can't be an Operation.
+ if (_nodes_by_name.ContainsKey(name))
+ // Yep, it's an Operation name
+ throw new ValueError($"The name {name} refers to an Operation, not a {types_str}.");
+ else
+ throw new ValueError(
+ $"The name {name} looks like an (invalid) Operation name, not a {types_str}" +
+ " Tensor names must be of the form \":\".");
}
}
diff --git a/src/TensorFlowNET.Core/Operations/ControlFlows/ControlFlowContext.cs b/src/TensorFlowNET.Core/Operations/ControlFlows/ControlFlowContext.cs
index 21201179..84651423 100644
--- a/src/TensorFlowNET.Core/Operations/ControlFlows/ControlFlowContext.cs
+++ b/src/TensorFlowNET.Core/Operations/ControlFlows/ControlFlowContext.cs
@@ -198,6 +198,8 @@ namespace Tensorflow.Operations
{
case CtxtOneofCase.CondCtxt:
return new CondContext().from_proto(context_def.CondCtxt, import_scope: import_scope);
+ case CtxtOneofCase.WhileCtxt:
+ return new WhileContext().from_proto(context_def.WhileCtxt, import_scope: import_scope);
}
throw new NotImplementedException($"Unknown ControlFlowContextDef field: {context_def.CtxtCase}");
diff --git a/src/TensorFlowNET.Core/Operations/ControlFlows/WhileContext.cs b/src/TensorFlowNET.Core/Operations/ControlFlows/WhileContext.cs
index 966ac83f..c2fe376e 100644
--- a/src/TensorFlowNET.Core/Operations/ControlFlows/WhileContext.cs
+++ b/src/TensorFlowNET.Core/Operations/ControlFlows/WhileContext.cs
@@ -2,14 +2,70 @@
using System.Collections.Generic;
using System.Text;
using Tensorflow.Operations.ControlFlows;
+using static Tensorflow.Python;
namespace Tensorflow.Operations
{
+ ///
+ /// Creates a `WhileContext`.
+ ///
public class WhileContext : ControlFlowContext
{
- private bool _back_prop=true;
+ bool _back_prop=true;
+ GradLoopState _grad_state =null;
+ Tensor _maximum_iterations;
+ int _parallel_iterations;
+ bool _swap_memory;
+ Tensor _pivot_for_pred;
+ Tensor _pivot_for_body;
+ Tensor[] _loop_exits;
+ Tensor[] _loop_enters;
- private GradLoopState _grad_state =null;
+ public WhileContext(int parallel_iterations = 10,
+ bool back_prop = true,
+ bool swap_memory = false,
+ string name = "while_context",
+ GradLoopState grad_state = null,
+ WhileContextDef context_def = null,
+ string import_scope = null)
+ {
+ if (context_def != null)
+ {
+ _init_from_proto(context_def, import_scope: import_scope);
+ }
+ else
+ {
+
+ }
+
+ _grad_state = grad_state;
+ }
+
+ private void _init_from_proto(WhileContextDef context_def, string import_scope = null)
+ {
+ var g = ops.get_default_graph();
+ _name = ops.prepend_name_scope(context_def.ContextName, import_scope);
+ if (!string.IsNullOrEmpty(context_def.MaximumIterationsName))
+ _maximum_iterations = g.as_graph_element(ops.prepend_name_scope(context_def.MaximumIterationsName, import_scope)) as Tensor;
+ _parallel_iterations = context_def.ParallelIterations;
+ _back_prop = context_def.BackProp;
+ _swap_memory = context_def.SwapMemory;
+ _pivot_for_pred = g.as_graph_element(ops.prepend_name_scope(context_def.PivotForPredName, import_scope)) as Tensor;
+ // We use this node to control constants created by the body lambda.
+ _pivot_for_body = g.as_graph_element(ops.prepend_name_scope(context_def.PivotForBodyName, import_scope)) as Tensor;
+ // The boolean tensor for loop termination condition.
+ _pivot = g.as_graph_element(ops.prepend_name_scope(context_def.PivotName, import_scope)) as Tensor;
+ // The list of exit tensors for loop variables.
+ _loop_exits = new Tensor[context_def.LoopExitNames.Count];
+ foreach (var (i, exit_name) in enumerate(context_def.LoopExitNames))
+ _loop_exits[i] = g.as_graph_element(ops.prepend_name_scope(exit_name, import_scope)) as Tensor;
+ // The list of enter tensors for loop variables.
+ _loop_enters = new Tensor[context_def.LoopEnterNames.Count];
+ foreach (var (i, enter_name) in enumerate(context_def.LoopEnterNames))
+ _loop_enters[i] = g.as_graph_element(ops.prepend_name_scope(enter_name, import_scope)) as Tensor;
+
+ __init__(values_def: context_def.ValuesDef, import_scope: import_scope);
+ }
public override WhileContext GetWhileContext()
{
@@ -21,9 +77,15 @@ namespace Tensorflow.Operations
public override bool back_prop => _back_prop;
- public static WhileContext from_proto(object proto)
+ public WhileContext from_proto(WhileContextDef proto, string import_scope)
{
- throw new NotImplementedException();
+ var ret = new WhileContext(context_def: proto, import_scope: import_scope);
+
+ ret.Enter();
+ foreach (var nested_def in proto.NestedContexts)
+ from_control_flow_context_def(nested_def, import_scope: import_scope);
+ ret.Exit();
+ return ret;
}
public object to_proto()
diff --git a/src/TensorFlowNET.Core/Operations/gen_math_ops.cs b/src/TensorFlowNET.Core/Operations/gen_math_ops.cs
index aa18bf07..74056057 100644
--- a/src/TensorFlowNET.Core/Operations/gen_math_ops.cs
+++ b/src/TensorFlowNET.Core/Operations/gen_math_ops.cs
@@ -352,6 +352,13 @@ namespace Tensorflow
return _op.outputs[0];
}
+ public static Tensor mul_no_nan(Tx x, Ty y, string name = null)
+ {
+ var _op = _op_def_lib._apply_op_helper("MulNoNan", name, args: new { x, y });
+
+ return _op.outputs[0];
+ }
+
public static Tensor real_div(Tensor x, Tensor y, string name = null)
{
var _op = _op_def_lib._apply_op_helper("RealDiv", name, args: new { x, y });
diff --git a/src/TensorFlowNET.Core/Operations/math_ops.cs b/src/TensorFlowNET.Core/Operations/math_ops.cs
index ce91dbe9..9af59e1e 100644
--- a/src/TensorFlowNET.Core/Operations/math_ops.cs
+++ b/src/TensorFlowNET.Core/Operations/math_ops.cs
@@ -71,6 +71,9 @@ namespace Tensorflow
public static Tensor multiply(Tensor x, Tensor y, string name = null)
=> gen_math_ops.mul(x, y, name: name);
+ public static Tensor mul_no_nan(Tensor x, Tensor y, string name = null)
+ => gen_math_ops.mul_no_nan(x, y, name: name);
+
///
/// Computes the mean of elements across dimensions of a tensor.
/// Reduces `input_tensor` along the dimensions given in `axis`.
diff --git a/src/TensorFlowNET.Core/Sessions/BaseSession.cs b/src/TensorFlowNET.Core/Sessions/BaseSession.cs
index 022d378c..22339226 100644
--- a/src/TensorFlowNET.Core/Sessions/BaseSession.cs
+++ b/src/TensorFlowNET.Core/Sessions/BaseSession.cs
@@ -1,5 +1,6 @@
using NumSharp;
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
@@ -18,7 +19,7 @@ namespace Tensorflow
public BaseSession(string target = "", Graph graph = null)
{
- if(graph is null)
+ if (graph is null)
{
_graph = ops.get_default_graph();
}
@@ -40,6 +41,13 @@ namespace Tensorflow
return _run(fetches, feed_dict);
}
+ public virtual NDArray run(object fetches, Hashtable feed_dict = null)
+ {
+ var feed_items = feed_dict == null ? new FeedItem[0] :
+ feed_dict.Keys.OfType