Browse Source

_name_stack isn't correct before entering random_uniform

tags/v0.8.0
Oceania2018 6 years ago
parent
commit
50ef868eeb
12 changed files with 309 additions and 16 deletions
  1. +105
    -0
      src/TensorFlowNET.Core/APIs/tf.init.cs
  2. +35
    -1
      src/TensorFlowNET.Core/Operations/random_ops.py.cs
  3. +5
    -5
      src/TensorFlowNET.Core/TensorFlowNET.Core.csproj
  4. +58
    -0
      src/TensorFlowNET.Core/Variables/PureVariableScope.cs
  5. +13
    -4
      src/TensorFlowNET.Core/Variables/VariableScope.cs
  6. +11
    -1
      src/TensorFlowNET.Core/Variables/_VariableScopeStore.cs
  7. +8
    -0
      src/TensorFlowNET.Core/Variables/_VariableStore.cs
  8. +2
    -2
      src/TensorFlowNET.Core/Variables/tf.variable.cs
  9. +58
    -1
      src/TensorFlowNET.Core/Variables/variable_scope.py.cs
  10. +1
    -1
      src/TensorFlowNET.Core/tf.cs
  11. +1
    -1
      test/TensorFlowNET.UnitTest/TensorFlowNET.UnitTest.csproj
  12. +12
    -0
      test/TensorFlowNET.UnitTest/VariableTest.cs

+ 105
- 0
src/TensorFlowNET.Core/APIs/tf.init.cs View File

@@ -7,7 +7,12 @@ namespace Tensorflow
public static partial class tf
{
public static IInitializer zeros_initializer => new Zeros();
public static IInitializer glorot_uniform => new GlorotUniform();
public static variable_scope variable_scope(string name_or_scope,
string default_name = null,
object values = null) => new variable_scope(name_or_scope, default_name, values);

public class Zeros : IInitializer
{
private TF_DataType dtype;
@@ -30,5 +35,105 @@ namespace Tensorflow
return new { dtype = dtype.name() };
}
}

/// <summary>
/// Initializer capable of adapting its scale to the shape of weights tensors.
/// </summary>
public class VarianceScaling : IInitializer
{
protected float _scale;
protected string _mode;
protected string _distribution;
protected int? _seed;
protected TF_DataType _dtype;

public VarianceScaling(float scale = 1.0f,
string mode = "fan_in",
string distribution= "truncated_normal",
int? seed = null,
TF_DataType dtype = TF_DataType.TF_FLOAT)
{
if (scale < 0)
throw new ValueError("`scale` must be positive float.");
_scale = scale;
_mode = mode;
_distribution = distribution;
_seed = seed;
_dtype = dtype;
}

public Tensor call(TensorShape shape, TF_DataType dtype)
{
var (fan_in, fan_out) = _compute_fans(shape);
if (_mode == "fan_in")
_scale /= Math.Max(1, fan_in);
else if (_mode == "fan_out")
_scale /= Math.Max(1, fan_out);
else
_scale /= Math.Max(1, (fan_in + fan_out) / 2);

if (_distribution == "normal" || _distribution == "truncated_normal")
{
throw new NotImplementedException("truncated_normal");
}
else if(_distribution == "untruncated_normal")
{
throw new NotImplementedException("truncated_normal");
}
else
{
var limit = Math.Sqrt(3.0f * _scale);
return random_ops.random_uniform(shape, (float)-limit, (float)limit, dtype, seed: _seed);
}
}

private (int, int) _compute_fans(int[] shape)
{
if (shape.Length < 1)
return (1, 1);
if (shape.Length == 1)
return (shape[0], shape[0]);
if (shape.Length == 2)
return (shape[0], shape[1]);
else
throw new NotImplementedException("VarianceScaling._compute_fans");
}

public virtual object get_config()
{
return new
{
scale = _scale,
mode = _mode,
distribution = _distribution,
seed = _seed,
dtype = _dtype
};
}
}

public class GlorotUniform : VarianceScaling
{
public GlorotUniform(float scale = 1.0f,
string mode = "fan_avg",
string distribution = "uniform",
int? seed = null,
TF_DataType dtype = TF_DataType.TF_FLOAT) : base(scale, mode, distribution, seed, dtype)
{

}

public object get_config()
{
return new
{
scale = _scale,
mode = _mode,
distribution = _distribution,
seed = _seed,
dtype = _dtype
};
}
}
}
}

+ 35
- 1
src/TensorFlowNET.Core/Operations/random_ops.py.cs View File

@@ -4,8 +4,18 @@ using System.Text;

namespace Tensorflow
{
public class random_ops
public class random_ops : Python
{
/// <summary>
///
/// </summary>
/// <param name="shape"></param>
/// <param name="mean"></param>
/// <param name="stddev"></param>
/// <param name="dtype"></param>
/// <param name="seed"></param>
/// <param name="name"></param>
/// <returns></returns>
public static Tensor random_normal(int[] shape,
float mean = 0.0f,
float stddev = 1.0f,
@@ -26,6 +36,30 @@ namespace Tensorflow
});
}

/// <summary>
/// Outputs random values from a uniform distribution.
/// </summary>
/// <param name="shape"></param>
/// <param name="minval"></param>
/// <param name="maxval"></param>
/// <param name="dtype">The type of the output</param>
/// <param name="seed">Used to create a random seed for the distribution.</param>
/// <param name="name">A name for the operation</param>
/// <returns>A tensor of the specified shape filled with random uniform values.</returns>
public static Tensor random_uniform(int[] shape,
float minval = 0,
float? maxval = null,
TF_DataType dtype = TF_DataType.TF_FLOAT,
int? seed = null,
string name = null)
{
return with<ops.name_scope, Tensor>(new ops.name_scope(name, "random_uniform", new { shape, minval, maxval }), scope =>
{
name = scope;
return null;
});
}

private static Tensor _ShapeTensor(int[] shape)
{
return ops.convert_to_tensor(shape, name: "shape");


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

@@ -4,7 +4,7 @@
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>TensorFlow.NET</AssemblyName>
<RootNamespace>Tensorflow</RootNamespace>
<Version>0.4.0</Version>
<Version>0.4.1</Version>
<Authors>Haiping Chen</Authors>
<Company>SciSharp STACK</Company>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
@@ -16,11 +16,11 @@
<PackageTags>TensorFlow, NumSharp, SciSharp, MachineLearning, TensorFlow.NET</PackageTags>
<Description>Google's TensorFlow binding in .NET Standard.
Docs: https://tensorflownet.readthedocs.io</Description>
<AssemblyVersion>0.4.0.0</AssemblyVersion>
<PackageReleaseNotes>Added Linear Regression example.
</PackageReleaseNotes>
<AssemblyVersion>0.4.1.0</AssemblyVersion>
<PackageReleaseNotes>Added ConfigProto to control CPU and GPU resource.
Fixed import name scope issue.</PackageReleaseNotes>
<LangVersion>7.2</LangVersion>
<FileVersion>0.4.0.0</FileVersion>
<FileVersion>0.4.1.0</FileVersion>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">


+ 58
- 0
src/TensorFlowNET.Core/Variables/PureVariableScope.cs View File

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

namespace Tensorflow
{
public class PureVariableScope : IPython
{
private string _name_or_scope;
private string _new_name;
private string _old_name_scope;
private bool _reuse;
private _VariableStore _var_store;
private VariableScope _old;
private _VariableScopeStore _var_scope_store;
private VariableScope variable_scope_object;

public PureVariableScope(string name_or_scope,
string old_name_scope = null,
TF_DataType dtype = TF_DataType.DtInvalid)
{
_name_or_scope = name_or_scope;
_old_name_scope = old_name_scope;
_var_store = variable_scope._get_default_variable_store();
_var_scope_store = variable_scope.get_variable_scope_store();
}

public void __enter__()
{
_old = _var_scope_store.current_scope;
_new_name = string.IsNullOrEmpty(_old.name) ? _name_or_scope : _old.name + "/" + _name_or_scope;
_reuse = _reuse || _old.resue;
string name_scope = _old_name_scope == null ? _name_or_scope : _old_name_scope;
variable_scope_object = new VariableScope(_reuse,
name: _new_name,
name_scope: name_scope);

_var_scope_store.open_variable_scope(_new_name);
_var_scope_store.current_scope = variable_scope_object;
}

public void Dispose()
{
}

public void __exit__()
{
}

public static implicit operator VariableScope(PureVariableScope scope)
{
return scope.variable_scope_object;
}
}
}

+ 13
- 4
src/TensorFlowNET.Core/Variables/VariableScope.cs View File

@@ -4,17 +4,26 @@ using System.Text;

namespace Tensorflow
{
/// <summary>
/// Variable scope object to carry defaults to provide to `get_variable`
/// </summary>
public class VariableScope
{
public bool use_resource { get; set; }
private _ReuseMode _reuse { get; set; }
private _ReuseMode _reuse;
public bool resue;

private object _regularizer;
private TF_DataType _dtype;
public string name { get; set; }
public string name_scope { get; set; }

public VariableScope(TF_DataType dtype = TF_DataType.TF_FLOAT)
public VariableScope(bool reuse,
string name = "",
string name_scope = "",
TF_DataType dtype = TF_DataType.TF_FLOAT)
{
this.name = name;
this.name_scope = name_scope;
_reuse = _ReuseMode.AUTO_REUSE;
_dtype = dtype;
}
@@ -29,7 +38,7 @@ namespace Tensorflow
VariableAggregation aggregation= VariableAggregation.NONE)
{
string full_name = !string.IsNullOrEmpty(this.name) ? this.name + "/" + name : name;
return Python.with<ops.name_scope, RefVariable>(new ops.name_scope(""), scope =>
return Python.with<ops.name_scope, RefVariable>(new ops.name_scope(null), scope =>
{
if (dtype == TF_DataType.DtInvalid)
dtype = _dtype;


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

@@ -7,10 +7,20 @@ namespace Tensorflow
public class _VariableScopeStore
{
public VariableScope current_scope { get; set; }
private Dictionary<string, int> variable_scopes_count;

public _VariableScopeStore()
{
current_scope = new VariableScope();
current_scope = new VariableScope(false);
variable_scopes_count = new Dictionary<string, int>();
}

public void open_variable_scope(string scope_name)
{
if (variable_scopes_count.ContainsKey(scope_name))
variable_scopes_count[scope_name] += 1;
else
variable_scopes_count[scope_name] = 1;
}
}
}

+ 8
- 0
src/TensorFlowNET.Core/Variables/_VariableStore.cs View File

@@ -87,6 +87,14 @@ namespace Tensorflow
}

Tensor init_val = null;

// Create the tensor to initialize the variable with default value.
if (initializer == null)
{
if (dtype.is_floating())
initializer = tf.glorot_uniform;
}

ops.init_scope();
{
if (initializing_from_value)


+ 2
- 2
src/TensorFlowNET.Core/Variables/tf.variable.cs View File

@@ -20,8 +20,8 @@ namespace Tensorflow
VariableSynchronization synchronization = VariableSynchronization.AUTO,
VariableAggregation aggregation = VariableAggregation.NONE)
{
var scope = variable_scope.get_variable_scope();
var store = variable_scope._get_default_variable_store();
var scope = Tensorflow.variable_scope.get_variable_scope();
var store = Tensorflow.variable_scope._get_default_variable_store();
return scope.get_variable(store,
name,
shape: shape,


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

@@ -4,12 +4,59 @@ using System.Text;

namespace Tensorflow
{
public class variable_scope
public class variable_scope : IPython
{
public static string _VARSTORE_KEY = "__variable_store";
public static string _VARSCOPESTORE_KEY = "__varscope";
public static bool _DEFAULT_USE_RESOURCE = false;

private bool _use_resource;
public bool UseResource => _use_resource;
private string _name_or_scope;
private string _default_name;
private object _values;
private string _current_name_scope;
private PureVariableScope _cached_pure_variable_scope;

public variable_scope(string name_or_scope, string default_name = "", object values = null)
{
_name_or_scope = name_or_scope;
_default_name = default_name;
_values = values;
_current_name_scope = null;

_use_resource = false;
if (_default_name == null && _name_or_scope == null)
throw new TypeError("If default_name is None then name_or_scope is required");
}

public void __enter__()
{
_enter_scope_uncached();
}

public VariableScope _enter_scope_uncached()
{
ops.name_scope current_name_scope = null;
if(_name_or_scope != null)
{
var name_scope = _name_or_scope;
if (name_scope != null || current_name_scope != null)
current_name_scope = new ops.name_scope(name_scope);
current_name_scope.__enter__();
string current_name_scope_name = current_name_scope;
_current_name_scope = current_name_scope;
string old_name_scope = current_name_scope_name;
var pure_variable_scope = new PureVariableScope(_name_or_scope, old_name_scope: old_name_scope);
pure_variable_scope.__enter__();
VariableScope entered_pure_variable_scope = pure_variable_scope;
_cached_pure_variable_scope = pure_variable_scope;
return entered_pure_variable_scope;
}

throw new NotImplementedException("_enter_scope_uncached");
}

public static RefVariable default_variable_creator(object initial_value,
string name = null,
bool? trainable = null,
@@ -101,5 +148,15 @@ namespace Tensorflow
return trainable.Value;
}

public void __exit__()
{
}

public void Dispose()
{
}
}
}

+ 1
- 1
src/TensorFlowNET.Core/tf.cs View File

@@ -20,7 +20,7 @@ namespace Tensorflow

public static RefVariable Variable<T>(T data, string name = null, TF_DataType dtype = TF_DataType.DtInvalid)
{
return variable_scope.default_variable_creator(data, name: name, dtype: TF_DataType.DtInvalid);
return Tensorflow.variable_scope.default_variable_creator(data, name: name, dtype: TF_DataType.DtInvalid);
}

public static unsafe Tensor placeholder(TF_DataType dtype, TensorShape shape = null)


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

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>netcoreapp2.2</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>


+ 12
- 0
test/TensorFlowNET.UnitTest/VariableTest.cs View File

@@ -30,6 +30,18 @@ namespace TensorFlowNET.UnitTest
var mammal2 = tf.Variable("Tiger");
}

[TestMethod]
public void SimpleScope()
{
with(tf.variable_scope("foo"), delegate
{
with(tf.variable_scope("bar"), delegate
{
var v = tf.get_variable("v", new TensorShape(1));
});
});
}

[TestMethod]
public void ScalarVar()
{


Loading…
Cancel
Save