| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 954713f commit d3002c0
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,6 +14,8 @@ namespace Tensorflow.Keras.Layers | |||
| 14 | 14 | /// A layer is a class implementing common neural networks operations, such | |
| 15 | 15 | /// as convolution, batch norm, etc. These operations require managing weights, | |
| 16 | 16 | /// losses, updates, and inter-layer connectivity. | |
| 17 | + /// | ||
| 18 | + /// tensorflow\python\keras\engine\base_layer.py | ||
| 17 | 19 | /// </summary> | |
| 18 | 20 | public class Layer : AutoTrackable | |
| 19 | 21 | { | |
@@ -55,9 +57,14 @@ public Layer(bool trainable = true, | |||
| 55 | 57 | { | |
| 56 | 58 | this.trainable = trainable; | |
| 57 | 59 | this._dtype = dtype; | |
| 60 | + // A stateful layer is a layer whose updates are run during inference too, | ||
| 61 | + // for instance stateful RNNs. | ||
| 58 | 62 | stateful = false; | |
| 63 | + // Indicates whether `build` needs to be called upon layer call, to create | ||
| 64 | + // the layer's weights. | ||
| 59 | 65 | built = false; | |
| 60 | 66 | this.supports_masking = false; | |
| 67 | + | ||
| 61 | 68 | _init_set_name(name); | |
| 62 | 69 | _trainable_weights = new List<RefVariable>(); | |
| 63 | 70 | _compute_previous_mask = false; | |
@@ -154,7 +161,8 @@ protected void _maybe_build(Tensor input) | |||
| 154 | 161 | if (_dtype == TF_DataType.DtInvalid) | |
| 155 | 162 | _dtype = input.dtype; | |
| 156 | 163 | ||
| 157 | - build(input.GetShape()); | ||
| 164 | + var input_shapes = input.GetShape(); | ||
| 165 | + build(input_shapes); | ||
| 158 | 166 | built = true; | |
| 159 | 167 | } | |
| 160 | 168 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,8 +22,13 @@ public Layer(bool trainable = true, | |||
| 22 | 22 | TF_DataType dtype = TF_DataType.DtInvalid, | |
| 23 | 23 | bool? _reuse = null) : base(trainable: trainable, name: name, dtype: dtype) | |
| 24 | 24 | { | |
| 25 | + // For backwards compatibility, legacy layers do not use `ResourceVariable` | ||
| 26 | + // by default. | ||
| 25 | 27 | this._use_resource_variables = false; | |
| 26 | 28 | this._reuse = _reuse; | |
| 29 | + | ||
| 30 | + // Avoid an incorrect lint error | ||
| 31 | + _trainable_weights = new List<RefVariable>(); | ||
| 27 | 32 | this.built = false; | |
| 28 | 33 | _keras_style = false; | |
| 29 | 34 | } | |
@@ -130,13 +135,12 @@ protected virtual RefVariable add_weight(string name, | |||
| 130 | 135 | initializer: initializer, | |
| 131 | 136 | trainable: trainable, | |
| 132 | 137 | getter: (name1, shape1, dtype1, initializer1, trainable1) => | |
| 133 | - { | ||
| 134 | - return tf.get_variable(name1, | ||
| 138 | + tf.get_variable(name1, | ||
| 135 | 139 | shape: new TensorShape(shape1), | |
| 136 | 140 | dtype: dtype1, | |
| 137 | 141 | initializer: initializer1, | |
| 138 | - trainable: trainable1); | ||
| 139 | - }); | ||
| 142 | + trainable: trainable1) | ||
| 143 | + ); | ||
| 140 | 144 | ||
| 141 | 145 | //if (init_graph != null) | |
| 142 | 146 | //var trainable_variables = variables.trainable_variables(); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -15,7 +15,7 @@ public partial class Tensor | |||
| 15 | 15 | public static Tensor operator -(Tensor x, Tensor y) => BinaryOpWrapper("sub", x, y); | |
| 16 | 16 | public static Tensor operator -(Tensor x, int y) => BinaryOpWrapper("sub", x, y); | |
| 17 | 17 | public static Tensor operator -(Tensor x, double y) => BinaryOpWrapper("sub", x, y); | |
| 18 | - public static Tensor operator -(float x, Tensor y) => BinaryOpWrapper("Sub", x, y); | ||
| 18 | + public static Tensor operator -(float x, Tensor y) => BinaryOpWrapper("sub", x, y); | ||
| 19 | 19 | ||
| 20 | 20 | public static Tensor operator *(float x, Tensor y) => BinaryOpWrapper("mul", x, y); | |
| 21 | 21 | public static Tensor operator *(double x, Tensor y) => BinaryOpWrapper("mul", x, y); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,5 +1,6 @@ | |||
| 1 | 1 | using System; | |
| 2 | 2 | using System.Collections.Generic; | |
| 3 | + using System.Linq; | ||
| 3 | 4 | using System.Text; | |
| 4 | 5 | ||
| 5 | 6 | namespace Tensorflow | |
@@ -16,7 +17,8 @@ public class PureVariableScope : IPython | |||
| 16 | 17 | private _VariableScopeStore _var_scope_store; | |
| 17 | 18 | private VariableScope variable_scope_object; | |
| 18 | 19 | private VariableScope _cached_variable_scope_object; | |
| 19 | - | ||
| 20 | + VariableScope _last_variable_scope_object; | ||
| 21 | + Dictionary<string, int> _old_subscopes; | ||
| 20 | 22 | public PureVariableScope(string name, | |
| 21 | 23 | string old_name_scope = null, | |
| 22 | 24 | TF_DataType dtype = TF_DataType.DtInvalid) | |
@@ -51,6 +53,7 @@ public void __enter__() | |||
| 51 | 53 | if(_scope != null) | |
| 52 | 54 | { | |
| 53 | 55 | _var_scope_store.open_variable_scope(_new_name); | |
| 56 | + _old_subscopes = _var_scope_store.variable_scopes_count.ToDictionary(kv => kv.Key, kv => kv.Value); | ||
| 54 | 57 | variable_scope_object = _cached_variable_scope_object; | |
| 55 | 58 | } | |
| 56 | 59 | else | |
@@ -66,6 +69,7 @@ public void __enter__() | |||
| 66 | 69 | _var_scope_store.open_variable_scope(_new_name); | |
| 67 | 70 | } | |
| 68 | 71 | _var_scope_store.current_scope = variable_scope_object; | |
| 72 | + _last_variable_scope_object = variable_scope_object; | ||
| 69 | 73 | } | |
| 70 | 74 | ||
| 71 | 75 | public void Dispose() | |
@@ -75,7 +79,12 @@ public void Dispose() | |||
| 75 | 79 | ||
| 76 | 80 | public void __exit__() | |
| 77 | 81 | { | |
| 78 | - | ||
| 82 | + // If jumping out from a non-prolonged scope, restore counts. | ||
| 83 | + if (_scope != null) | ||
| 84 | + _var_scope_store.variable_scopes_count = _old_subscopes; | ||
| 85 | + else | ||
| 86 | + _var_scope_store.close_variable_subscopes(_new_name); | ||
| 87 | + _var_scope_store.current_scope = _old; | ||
| 79 | 88 | } | |
| 80 | 89 | ||
| 81 | 90 | public static implicit operator VariableScope(PureVariableScope scope) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -7,7 +7,7 @@ namespace Tensorflow | |||
| 7 | 7 | public class _VariableScopeStore | |
| 8 | 8 | { | |
| 9 | 9 | public VariableScope current_scope { get; set; } | |
| 10 | - private Dictionary<string, int> variable_scopes_count; | ||
| 10 | + public Dictionary<string, int> variable_scopes_count; | ||
| 11 | 11 | ||
| 12 | 12 | public _VariableScopeStore() | |
| 13 | 13 | { | |
@@ -23,6 +23,13 @@ public void open_variable_scope(string scope_name) | |||
| 23 | 23 | variable_scopes_count[scope_name] = 1; | |
| 24 | 24 | } | |
| 25 | 25 | ||
| 26 | + public void close_variable_subscopes(string scope_name) | ||
| 27 | + { | ||
| 28 | + foreach (var k in variable_scopes_count.Keys) | ||
| 29 | + if (scope_name == null || k.StartsWith(scope_name + "/")) | ||
| 30 | + variable_scopes_count[k] = 0; | ||
| 31 | + } | ||
| 32 | + | ||
| 26 | 33 | public int variable_scope_count(string scope_name) | |
| 27 | 34 | { | |
| 28 | 35 | if (variable_scopes_count.ContainsKey(scope_name)) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -106,13 +106,13 @@ private VariableScope _enter_scope_uncached() | |||
| 106 | 106 | ||
| 107 | 107 | if (_name != null || _scope != null) | |
| 108 | 108 | { | |
| 109 | - var name_scope = _name == null ? _scope.name.Split('/').Last() : _name; | ||
| 109 | + var name_scope = _scope.name.Split('/').Last(); | ||
| 110 | 110 | if (current_name_scope == null) | |
| 111 | 111 | current_name_scope = ops.name_scope(name_scope); | |
| 112 | 112 | current_name_scope.__enter__(); | |
| 113 | 113 | var current_name_scope_name = current_name_scope; | |
| 114 | 114 | _current_name_scope = current_name_scope; | |
| 115 | - string old_name_scope = current_name_scope_name; | ||
| 115 | + string old_name_scope = _scope.original_name_scope; | ||
| 116 | 116 | ||
| 117 | 117 | if(_scope == null) | |
| 118 | 118 | pure_variable_scope = new PureVariableScope(_name, old_name_scope: old_name_scope); | |
@@ -139,14 +139,22 @@ private VariableScope _enter_scope_uncached() | |||
| 139 | 139 | } | |
| 140 | 140 | } | |
| 141 | 141 | ||
| 142 | + /// <summary> | ||
| 143 | + /// Get a name with the given prefix unique in the current variable scope. | ||
| 144 | + /// </summary> | ||
| 145 | + /// <param name="prefix"></param> | ||
| 146 | + /// <returns></returns> | ||
| 142 | 147 | public static string _get_unique_variable_scope(string prefix) | |
| 143 | 148 | { | |
| 144 | 149 | var var_scope_store = get_variable_scope_store(); | |
| 145 | 150 | var current_scope = get_variable_scope(); | |
| 146 | 151 | string name = !string.IsNullOrEmpty(current_scope.name) ? current_scope.name + "/" + prefix : prefix; | |
| 147 | 152 | if (var_scope_store.variable_scope_count(name) == 0) | |
| 148 | 153 | return prefix; | |
| 149 | - throw new NotImplementedException("_get_unique_variable_scope"); | ||
| 154 | + var idx = 1; | ||
| 155 | + while (var_scope_store.variable_scope_count($"{name}_{idx}") > 0) | ||
| 156 | + idx += 1; | ||
| 157 | + return $"{prefix}_{idx}"; | ||
| 150 | 158 | } | |
| 151 | 159 | ||
| 152 | 160 | public static RefVariable default_variable_creator(object initial_value, | |
@@ -250,6 +258,7 @@ public static implicit operator VariableScope(variable_scope scope) | |||
| 250 | 258 | ||
| 251 | 259 | public void __exit__() | |
| 252 | 260 | { | |
| 261 | + _cached_pure_variable_scope.__exit__(); | ||
| 253 | 262 | if (_current_name_scope != null) | |
| 254 | 263 | _current_name_scope.__exit__(); | |
| 255 | 264 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments