@@ -66,7 +66,7 @@ using(var sess = tf.Session()) | |||
Read the docs & book [The Definitive Guide to Tensorflow.NET](https://tensorflownet.readthedocs.io/en/latest/FrontCover.html). | |||
More examples: | |||
### More examples: | |||
* [Hello World](test/TensorFlowNET.Examples/HelloWorld.cs) | |||
* [Basic Operations](test/TensorFlowNET.Examples/BasicOperations.cs) | |||
@@ -7,7 +7,7 @@ namespace Tensorflow | |||
public static partial class tf | |||
{ | |||
public static IInitializer zeros_initializer => new Zeros(); | |||
public static IInitializer glorot_uniform => new GlorotUniform(); | |||
public static IInitializer glorot_uniform_initializer => new GlorotUniform(); | |||
public static variable_scope variable_scope(string name_or_scope, | |||
string default_name = null, | |||
@@ -24,10 +24,34 @@ namespace Tensorflow | |||
if (!seed2.HasValue) | |||
seed2 = 0; | |||
var _op = _op_def_lib._apply_op_helper("RandomStandardNormal", name: name, | |||
var _op = _op_def_lib._apply_op_helper("RandomStandardNormal", | |||
name: name, | |||
args: new { shape, dtype, seed, seed2 }); | |||
return _op.outputs[0]; | |||
} | |||
/// <summary> | |||
/// Outputs random values from a uniform distribution. | |||
/// </summary> | |||
/// <param name="shape"></param> | |||
/// <param name="dtype"></param> | |||
/// <param name="seed"></param> | |||
/// <param name="seed2"></param> | |||
/// <param name="name"></param> | |||
/// <returns></returns> | |||
public static Tensor random_uniform(Tensor shape, TF_DataType dtype, int? seed = 0, int? seed2 = 0, string name = null) | |||
{ | |||
if (!seed.HasValue) | |||
seed = 0; | |||
if (!seed2.HasValue) | |||
seed2 = 0; | |||
var _op = _op_def_lib._apply_op_helper("RandomUniform", | |||
name: name, | |||
args: new { shape, dtype, seed, seed2}); | |||
return _op.outputs[0]; | |||
} | |||
} | |||
} |
@@ -56,7 +56,11 @@ namespace Tensorflow | |||
return with<ops.name_scope, Tensor>(new ops.name_scope(name, "random_uniform", new { shape, minval, maxval }), scope => | |||
{ | |||
name = scope; | |||
return null; | |||
var tensorShape = _ShapeTensor(shape); | |||
var minTensor = ops.convert_to_tensor(minval, dtype: dtype, name: "min"); | |||
var maxTensor = ops.convert_to_tensor(maxval, dtype: dtype, name: "max"); | |||
var rnd = gen_random_ops.random_uniform(tensorShape, dtype); | |||
return math_ops.add(rnd * (maxTensor - minTensor), minTensor, name: name); | |||
}); | |||
} | |||
@@ -77,6 +77,11 @@ namespace Tensorflow | |||
return null; | |||
} | |||
public TensorShape getShape() | |||
{ | |||
return tensor_util.to_shape(shape); | |||
} | |||
/// <summary> | |||
/// number of dimensions | |||
/// 0 Scalar (magnitude only) | |||
@@ -1,4 +1,6 @@ | |||
using System; | |||
using Google.Protobuf; | |||
using Google.Protobuf.Collections; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
@@ -99,7 +101,7 @@ namespace Tensorflow | |||
if (initial_value is null) | |||
throw new ValueError("initial_value must be specified."); | |||
var init_from_fn = false; | |||
var init_from_fn = initial_value.GetType().Name == "Func`1"; | |||
if(collections == null) | |||
{ | |||
@@ -115,12 +117,27 @@ namespace Tensorflow | |||
collections.Add(ops.GraphKeys.TRAINABLE_VARIABLES); | |||
ops.init_scope(); | |||
var values = init_from_fn ? new List<object>() : new List<object> { initial_value }; | |||
Python.with<ops.name_scope>(new ops.name_scope(name, "Variable", values), scope => | |||
var values = init_from_fn ? new object[0] : new object[] { initial_value }; | |||
with<ops.name_scope>(new ops.name_scope(name, "Variable", values), scope => | |||
{ | |||
name = scope; | |||
if (init_from_fn) | |||
{ | |||
// Use attr_scope and device(None) to simulate the behavior of | |||
// colocate_with when the variable we want to colocate with doesn't | |||
// yet exist. | |||
string true_name = ops._name_from_scope_name(name); | |||
var attr = new AttrValue | |||
{ | |||
List = new AttrValue.Types.ListValue() | |||
}; | |||
attr.List.S.Add(ByteString.CopyFromUtf8($"loc:{true_name}")); | |||
with<ops.name_scope>(new ops.name_scope("Initializer"), scope2 => | |||
{ | |||
_initial_value = (initial_value as Func<Tensor>)(); | |||
_initial_value = ops.convert_to_tensor(_initial_value, name: "initial_value", dtype: dtype); | |||
_variable = state_ops.variable_op_v2(_initial_value.shape, _initial_value.dtype.as_base_dtype(), name: name); | |||
}); | |||
} | |||
// Or get the initial value from a Tensor or Python object. | |||
else | |||
@@ -135,7 +152,9 @@ namespace Tensorflow | |||
// Manually overrides the variable's shape with the initial value's. | |||
if (validate_shape) | |||
{ | |||
var initial_value_shape = _initial_value.shape; | |||
var initial_value_shape = _initial_value.getShape(); | |||
if (!initial_value_shape.is_fully_defined()) | |||
throw new ValueError($"initial_value must have a shape specified: {_initial_value}"); | |||
} | |||
// If 'initial_value' makes use of other variables, make sure we don't | |||
@@ -74,7 +74,9 @@ namespace Tensorflow | |||
VariableSynchronization synchronization = VariableSynchronization.AUTO, | |||
VariableAggregation aggregation = VariableAggregation.NONE) | |||
{ | |||
bool initializing_from_value = false; | |||
bool initializing_from_value = true; | |||
if (use_resource == null) | |||
use_resource = false; | |||
if (_vars.ContainsKey(name)) | |||
{ | |||
@@ -86,15 +88,18 @@ namespace Tensorflow | |||
throw new NotImplementedException("_get_single_variable"); | |||
} | |||
Tensor init_val = null; | |||
RefVariable v = null; | |||
// Create the tensor to initialize the variable with default value. | |||
if (initializer == null) | |||
{ | |||
if (dtype.is_floating()) | |||
initializer = tf.glorot_uniform; | |||
{ | |||
initializer = tf.glorot_uniform_initializer; | |||
initializing_from_value = false; | |||
} | |||
} | |||
// Create the variable. | |||
ops.init_scope(); | |||
{ | |||
if (initializing_from_value) | |||
@@ -103,23 +108,19 @@ namespace Tensorflow | |||
} | |||
else | |||
{ | |||
init_val = initializer.call(shape, dtype); | |||
Func<Tensor> init_val = () => initializer.call(shape, dtype); | |||
var variable_dtype = dtype.as_base_dtype(); | |||
v = variable_scope.default_variable_creator(init_val, | |||
name: name, | |||
trainable: trainable, | |||
dtype: TF_DataType.DtInvalid, | |||
validate_shape: validate_shape, | |||
synchronization: synchronization, | |||
aggregation: aggregation); | |||
} | |||
} | |||
// Create the variable. | |||
if (use_resource == null) | |||
use_resource = false; | |||
var v = variable_scope.default_variable_creator(init_val, | |||
name: name, | |||
trainable: trainable, | |||
dtype: TF_DataType.DtInvalid, | |||
validate_shape: validate_shape, | |||
synchronization: synchronization, | |||
aggregation: aggregation); | |||
_vars[name] = v; | |||
return v; | |||
@@ -0,0 +1,28 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Text; | |||
namespace Tensorflow | |||
{ | |||
public class state_ops | |||
{ | |||
/// <summary> | |||
/// Create a variable Operation. | |||
/// </summary> | |||
/// <param name="shape"></param> | |||
/// <param name="dtype"></param> | |||
/// <param name="name"></param> | |||
/// <param name="container"></param> | |||
/// <param name="shared_name"></param> | |||
/// <returns></returns> | |||
public static Tensor variable_op_v2(long[] shape, | |||
TF_DataType dtype, | |||
string name = "Variable", | |||
string container = "", | |||
string shared_name = "") => gen_state_ops.variable_v2(shape, | |||
dtype, | |||
name: name, | |||
container: container, | |||
shared_name: shared_name); | |||
} | |||
} |
@@ -16,7 +16,7 @@ namespace TensorFlowNET.Examples | |||
// Parameters | |||
float learning_rate = 0.01f; | |||
int training_epochs = 10000; | |||
int training_epochs = 1000; | |||
int display_step = 50; | |||
public void Run() | |||
@@ -30,14 +30,18 @@ namespace TensorFlowNET.UnitTest | |||
var mammal2 = tf.Variable("Tiger"); | |||
} | |||
/// <summary> | |||
/// https://www.tensorflow.org/api_docs/python/tf/variable_scope | |||
/// </summary> | |||
[TestMethod] | |||
public void SimpleScope() | |||
public void VarCreation1() | |||
{ | |||
with(tf.variable_scope("foo"), delegate | |||
{ | |||
with(tf.variable_scope("bar"), delegate | |||
{ | |||
var v = tf.get_variable("v", new TensorShape(1)); | |||
Assert.AreEqual(v.name, "foo/bar/v:0"); | |||
}); | |||
}); | |||
} | |||