@@ -18,8 +18,11 @@ namespace Tensorflow | |||
{ | |||
public static partial class tf | |||
{ | |||
public static object get_collection(string key, string scope = "") => get_default_graph() | |||
.get_collection(key, scope: scope); | |||
public static Tensor assign(Tensor @ref, object value, bool validate_shape = true, bool use_locking = true, string name = null) | |||
=> state_ops.assign(@ref, value, validate_shape, use_locking, name); | |||
public static object get_collection(string key, string scope = "") | |||
=> get_default_graph().get_collection(key, scope: scope); | |||
/// <summary> | |||
/// Returns a context manager that creates hierarchical names for operations. | |||
@@ -28,8 +31,7 @@ namespace Tensorflow | |||
/// <param name="default_name">The default name to use if the name argument is None.</param> | |||
/// <param name="values">The list of Tensor arguments that are passed to the op function.</param> | |||
/// <returns>The scope name.</returns> | |||
public static ops.NameScope name_scope(string name, | |||
string default_name = "", | |||
object values = null) => new ops.NameScope(name, default_name, values); | |||
public static ops.NameScope name_scope(string name, string default_name = "", object values = null) | |||
=> new ops.NameScope(name, default_name, values); | |||
} | |||
} |
@@ -0,0 +1,39 @@ | |||
using System.Linq; | |||
using NumSharp; | |||
using Tensorflow.Framework; | |||
namespace Tensorflow.Contrib.Learn.Estimators | |||
{ | |||
public static class tensor_signature | |||
{ | |||
public static bool is_compatible_with(this Tensor self, Tensor other) | |||
{ | |||
bool _shape_is_compatible_0dim(Shape _this, Shape _other) | |||
{ | |||
var __other = tensor_shape.as_shape(_other); | |||
if (_this.Dimensions == null || __other.Dimensions == null) | |||
return true; | |||
if (_this.NDim != __other.NDim) | |||
return false; | |||
foreach (var (x_dim, y_dim) in _this.Dimensions.Zip(__other.Dimensions, (x_dim, y_dim) => (x_dim, y_dim))) | |||
{ | |||
if (x_dim != y_dim) | |||
return false; | |||
} | |||
return true; | |||
} | |||
if (other.is_sparse()) | |||
{ | |||
return self.dtype.is_compatible_with(other.dtype); | |||
} | |||
return self.dtype.is_compatible_with(other.dtype) && | |||
_shape_is_compatible_0dim(self.shape, other.shape) && | |||
!self.is_sparse(); | |||
} | |||
} | |||
} |
@@ -1,8 +1,19 @@ | |||
namespace Tensorflow.Framework | |||
{ | |||
public static class SparseTensor | |||
public interface _TensorLike | |||
{ } | |||
public class SparseTensor : CompositeTensor, _TensorLike | |||
{ | |||
private static Tensor _dense_shape { get; set; } | |||
} | |||
public static class sparse_tensor | |||
{ | |||
public static bool is_sparse(this _TensorLike x) | |||
{ | |||
return x is SparseTensor; | |||
} | |||
} | |||
} |
@@ -0,0 +1,34 @@ | |||
using System; | |||
using System.Linq; | |||
using System.Text; | |||
using NumSharp; | |||
using Tensorflow.Contrib.Learn.Estimators; | |||
namespace Tensorflow.Framework | |||
{ | |||
public static class tensor_shape | |||
{ | |||
public static void assert_is_compatible_with(this Tensor self, Tensor other) | |||
{ | |||
if (!self.is_compatible_with(other)) | |||
{ | |||
var selfDim = self.shape | |||
.Aggregate(new StringBuilder("{"), (sb, i) => sb.Append(i).Append(", "), sb => sb.ToString()) | |||
.Replace(", }", "}"); | |||
var otherDim = other.shape | |||
.Aggregate(new StringBuilder("{"), (sb, i) => sb.Append(i).Append(", "), sb => sb.ToString()) | |||
.Replace(", }", "}"); | |||
throw new ArgumentException($"Dimensions {selfDim} and {otherDim} are not compatible"); | |||
} | |||
} | |||
public static TensorShape as_shape(this Shape shape) | |||
{ | |||
if (shape is TensorShape tshape) | |||
return tshape; | |||
return new TensorShape(shape); | |||
} | |||
} | |||
} |
@@ -14,12 +14,15 @@ | |||
limitations under the License. | |||
******************************************************************************/ | |||
using System; | |||
using Tensorflow.Framework; | |||
namespace Tensorflow | |||
{ | |||
/// <summary> | |||
/// tensorflow\python\ops\resource_variable_ops.py | |||
/// </summary> | |||
public class resource_variable_ops | |||
public static class resource_variable_ops | |||
{ | |||
public static ITensorOrOperation shape_safe_assign_variable_handle(Tensor handle, int[] shape, Tensor value, string name = null) | |||
{ | |||
@@ -29,9 +32,61 @@ namespace Tensorflow | |||
name: name); | |||
} | |||
/// <summary> | |||
/// | |||
/// </summary> | |||
/// <param name="self"></param> | |||
/// <param name="value"></param> | |||
/// <param name="use_locking"></param> | |||
/// <param name="read_value"></param> | |||
/// <returns> | |||
/// If `read_value` is `True`, this method will return the new value of the | |||
/// variable after the assignment has completed.Otherwise, when in graph mode | |||
/// it will return the `Operation` that does the assignment, and when in eager | |||
/// mode it will return `None`. | |||
/// </returns> | |||
public static Operation assign(this Tensor self, Tensor value, bool use_locking = false, string name = null, bool read_value = true) | |||
{ | |||
var value_tensor = ops.convert_to_tensor(value, dtype: self.dtype); | |||
self.assert_is_compatible_with(value_tensor); | |||
var assign_op = gen_resource_variable_ops.assign_variable_op(self, value_tensor, name: name); | |||
if (read_value) | |||
{ | |||
return self._lazy_read(assign_op); | |||
} | |||
return assign_op; | |||
} | |||
public static Operation _lazy_read(this Tensor self, Operation op) | |||
{ | |||
variable_accessed(self); | |||
throw new NotImplementedException(); | |||
} | |||
public static void variable_accessed(this Tensor variable) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
public static bool is_resource_variable(VariableV1 var) | |||
{ | |||
return var is ResourceVariable; | |||
} | |||
/// <summary> | |||
/// Represents a future for a read of a variable. | |||
/// Pretends to be the tensor if anyone looks. | |||
/// </summary> | |||
public class _UnreadVariable : BaseResourceVariable | |||
{ | |||
} | |||
/// <summary> | |||
/// A python variable from an existing handle. | |||
/// </summary> | |||
public class BaseResourceVariable : VariableV1 | |||
{ | |||
} | |||
} | |||
} |
@@ -19,6 +19,7 @@ using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Runtime.InteropServices; | |||
using Tensorflow.Framework; | |||
using static Tensorflow.Python; | |||
namespace Tensorflow | |||
@@ -27,7 +28,7 @@ namespace Tensorflow | |||
/// A tensor is a generalization of vectors and matrices to potentially higher dimensions. | |||
/// Internally, TensorFlow represents tensors as n-dimensional arrays of base datatypes. | |||
/// </summary> | |||
public partial class Tensor : IDisposable, ITensorOrOperation | |||
public partial class Tensor : IDisposable, ITensorOrOperation, _TensorLike | |||
{ | |||
private IntPtr _handle; | |||
@@ -109,6 +110,8 @@ namespace Tensorflow | |||
this.shape = shape.Dimensions; | |||
} | |||
public int[] dims => shape; | |||
/// <summary> | |||
/// number of dimensions | |||
/// 0 Scalar (magnitude only) | |||
@@ -205,5 +205,10 @@ namespace Tensorflow | |||
{ | |||
return (int)type > 100; | |||
} | |||
public static bool is_compatible_with(this TF_DataType self, TF_DataType other) | |||
{ | |||
return self.as_datatype_enum() == other.as_datatype_enum(); | |||
} | |||
} | |||
} |
@@ -214,6 +214,12 @@ namespace Tensorflow | |||
else | |||
nparray = Convert.ToString(values); | |||
break; | |||
case "Boolean": | |||
if (values.GetType().IsArray) | |||
nparray = np.array((bool[])values, np_dt); | |||
else | |||
nparray = Convert.ToBoolean(values); | |||
break; | |||
default: | |||
throw new NotImplementedException($"make_tensor_proto: Support for type {np_dt.Name} Not Implemented"); | |||
} | |||
@@ -40,6 +40,8 @@ namespace Tensorflow | |||
public override string name => _variable.name; | |||
public Tensor eval() => _variable; | |||
public RefVariable(object initial_value = null, | |||
bool trainable = true, | |||
List<string> collections = null, | |||
@@ -12,102 +12,102 @@ | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
******************************************************************************/ | |||
using System.Collections.Generic; | |||
using Tensorflow.Eager; | |||
namespace Tensorflow | |||
{ | |||
public class gen_state_ops | |||
{ | |||
public static OpDefLibrary _op_def_lib = new OpDefLibrary(); | |||
public static Execute _execute = new Execute(); | |||
/// <summary> | |||
/// Holds state in the form of a tensor that persists across steps. | |||
/// Outputs a ref to the tensor state so it may be read or modified. | |||
/// </summary> | |||
/// <param name="shape">The shape of the variable tensor.</param> | |||
/// <param name="dtype">The type of elements in the variable tensor.</param> | |||
/// <param name="name"></param> | |||
/// <param name="container"></param> | |||
/// <param name="shared_name"></param> | |||
/// <returns></returns> | |||
public static Tensor variable_v2(int[] shape, TF_DataType dtype, string name = null, string container = "", string shared_name = "") | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("VariableV2", name: name, args: new { dtype, shape, container, shared_name }); | |||
var _result = _op.outputs; | |||
var _inputs_flat = _op.inputs; | |||
var _attrs = new Dictionary<string, object>(); | |||
_attrs["dtype"] = _op.get_attr("dtype"); | |||
_attrs["shape"] = _op.get_attr("shape"); | |||
_attrs["container"] = _op.get_attr("container"); | |||
_attrs["shared_name"] = _op.get_attr("shared_name"); | |||
_execute.record_gradient("VariableV2", _inputs_flat, _attrs, _result, name); | |||
return _result[0]; | |||
} | |||
/// <summary> | |||
/// Update 'ref' by assigning 'value' to it | |||
/// </summary> | |||
/// <param name="REF"></param> | |||
/// <param name="value"></param> | |||
/// <param name="validate_shape"></param> | |||
/// <param name="use_locking"></param> | |||
/// <param name="name"></param> | |||
public static Tensor assign(Tensor @ref, object value, | |||
bool validate_shape = true, | |||
bool use_locking = true, | |||
string name = null) | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("Assign", name: name, args: new { @ref, value, validate_shape, use_locking }); | |||
var _result = _op.outputs; | |||
var _inputs_flat = _op.inputs; | |||
var _attrs = new Dictionary<string, object>(); | |||
_attrs["T"] = _op.get_attr("T"); | |||
_attrs["validate_shape"] = _op.get_attr("validate_shape"); | |||
_attrs["use_locking"] = _op.get_attr("use_locking"); | |||
_execute.record_gradient("Assign", _inputs_flat, _attrs, _result, name); | |||
return _result[0]; | |||
} | |||
******************************************************************************/ | |||
using System.Collections.Generic; | |||
using Tensorflow.Eager; | |||
namespace Tensorflow | |||
{ | |||
public class gen_state_ops | |||
{ | |||
public static OpDefLibrary _op_def_lib = new OpDefLibrary(); | |||
public static Execute _execute = new Execute(); | |||
/// <summary> | |||
/// Holds state in the form of a tensor that persists across steps. | |||
/// Outputs a ref to the tensor state so it may be read or modified. | |||
/// </summary> | |||
/// <param name="shape">The shape of the variable tensor.</param> | |||
/// <param name="dtype">The type of elements in the variable tensor.</param> | |||
/// <param name="name"></param> | |||
/// <param name="container"></param> | |||
/// <param name="shared_name"></param> | |||
/// <returns></returns> | |||
public static Tensor variable_v2(int[] shape, TF_DataType dtype, string name = null, string container = "", string shared_name = "") | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("VariableV2", name: name, args: new { dtype, shape, container, shared_name }); | |||
var _result = _op.outputs; | |||
var _inputs_flat = _op.inputs; | |||
var _attrs = new Dictionary<string, object>(); | |||
_attrs["dtype"] = _op.get_attr("dtype"); | |||
_attrs["shape"] = _op.get_attr("shape"); | |||
_attrs["container"] = _op.get_attr("container"); | |||
_attrs["shared_name"] = _op.get_attr("shared_name"); | |||
_execute.record_gradient("VariableV2", _inputs_flat, _attrs, _result, name); | |||
return _result[0]; | |||
} | |||
/// <summary> | |||
/// Update 'ref' by assigning 'value' to it | |||
/// </summary> | |||
/// <param name="REF"></param> | |||
/// <param name="value"></param> | |||
/// <param name="validate_shape"></param> | |||
/// <param name="use_locking"></param> | |||
/// <param name="name"></param> | |||
public static Tensor assign(Tensor @ref, object value, | |||
bool validate_shape = true, | |||
bool use_locking = true, | |||
string name = null) | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("Assign", name: name, args: new { @ref, value, validate_shape, use_locking }); | |||
var _result = _op.outputs; | |||
var _inputs_flat = _op.inputs; | |||
var _attrs = new Dictionary<string, object>(); | |||
_attrs["T"] = _op.get_attr("T"); | |||
_attrs["validate_shape"] = _op.get_attr("validate_shape"); | |||
_attrs["use_locking"] = _op.get_attr("use_locking"); | |||
_execute.record_gradient("Assign", _inputs_flat, _attrs, _result, name); | |||
return _result[0]; | |||
} | |||
public static Tensor assign(RefVariable @ref, object value, | |||
bool validate_shape = true, | |||
bool use_locking = true, | |||
string name = null) | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("Assign", name: name, args: new { @ref, value, validate_shape, use_locking }); | |||
var _result = _op.outputs; | |||
var _inputs_flat = _op.inputs; | |||
var _attrs = new Dictionary<string, object>(); | |||
_attrs["T"] = _op.get_attr("T"); | |||
_attrs["validate_shape"] = _op.get_attr("validate_shape"); | |||
_attrs["use_locking"] = _op.get_attr("use_locking"); | |||
_execute.record_gradient("Assign", _inputs_flat, _attrs, _result, name); | |||
return _result[0]; | |||
} | |||
public static Tensor assign_sub(RefVariable @ref, | |||
Tensor value, | |||
bool use_locking = false, | |||
string name = null) | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("AssignSub", name: name, args: new { @ref, value, use_locking }); | |||
return _op.outputs[0]; | |||
bool use_locking = true, | |||
string name = null) | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("Assign", name: name, args: new { @ref, value, validate_shape, use_locking }); | |||
var _result = _op.outputs; | |||
var _inputs_flat = _op.inputs; | |||
var _attrs = new Dictionary<string, object>(); | |||
_attrs["T"] = _op.get_attr("T"); | |||
_attrs["validate_shape"] = _op.get_attr("validate_shape"); | |||
_attrs["use_locking"] = _op.get_attr("use_locking"); | |||
_execute.record_gradient("Assign", _inputs_flat, _attrs, _result, name); | |||
return _result[0]; | |||
} | |||
public static Tensor assign_sub(RefVariable @ref, | |||
Tensor value, | |||
bool use_locking = false, | |||
string name = null) | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("AssignSub", name: name, args: new { @ref, value, use_locking }); | |||
return _op.outputs[0]; | |||
} | |||
@@ -125,10 +125,10 @@ namespace Tensorflow | |||
// name: A name for the operation(optional). | |||
// Returns: | |||
// A mutable `Tensor`. Has the same type as `ref`. | |||
public static Tensor assign_add(RefVariable @ref, Tensor value, bool use_locking = false, string name = null) | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("AssignAdd", name: name, args: new { @ref, value, use_locking }); | |||
return _op.outputs[0]; | |||
public static Tensor assign_add(RefVariable @ref, Tensor value, bool use_locking = false, string name = null) | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("AssignAdd", name: name, args: new { @ref, value, use_locking }); | |||
return _op.outputs[0]; | |||
} | |||
/// <summary> | |||
@@ -142,8 +142,8 @@ namespace Tensorflow | |||
/// <returns></returns> | |||
public static Tensor scatter_add(RefVariable @ref, Tensor indices, Tensor updates, bool use_locking = false, string name = null) | |||
{ | |||
var _op = _op_def_lib._apply_op_helper("ScatterAdd", name: name, args: new { @ref, indices, updates, use_locking }); | |||
var _op = _op_def_lib._apply_op_helper("ScatterAdd", name: name, args: new { @ref, indices, updates, use_locking }); | |||
return _op.outputs[0]; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -12,99 +12,99 @@ | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
******************************************************************************/ | |||
using System; | |||
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(int[] 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); | |||
public static Tensor assign(Tensor @ref, object value, | |||
bool validate_shape = true, | |||
bool use_locking = true, | |||
string name = null) | |||
{ | |||
if (@ref.dtype.is_ref_dtype()) | |||
return gen_state_ops.assign(@ref, | |||
value, | |||
validate_shape: validate_shape, | |||
use_locking: use_locking, | |||
name: name); | |||
throw new NotImplementedException("state_ops.assign"); | |||
//return @ref.assign(value, name: name); | |||
} | |||
public static Tensor assign(RefVariable @ref, object value, | |||
bool validate_shape = true, | |||
bool use_locking = true, | |||
string name = null) | |||
******************************************************************************/ | |||
using System; | |||
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(int[] 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); | |||
public static Tensor assign(Tensor @ref, object value, | |||
bool validate_shape = true, | |||
bool use_locking = true, | |||
string name = null) | |||
{ | |||
if (@ref.dtype.is_ref_dtype()) | |||
return gen_state_ops.assign(@ref, | |||
value, | |||
validate_shape: validate_shape, | |||
use_locking: use_locking, | |||
name: name); | |||
return @ref.assign((Tensor)value, name: name); | |||
} | |||
public static Tensor assign(RefVariable @ref, object value, | |||
bool validate_shape = true, | |||
bool use_locking = true, | |||
string name = null) | |||
{ | |||
return gen_state_ops.assign(@ref, | |||
value, | |||
validate_shape: validate_shape, | |||
use_locking: use_locking, | |||
name: name); | |||
} | |||
public static Tensor assign_sub(RefVariable @ref, | |||
Tensor value, | |||
bool use_locking = false, | |||
string name = null) => gen_state_ops.assign_sub(@ref, | |||
value, | |||
use_locking: use_locking, | |||
name: name); | |||
//"""Update 'ref' by adding 'value' to it. | |||
// | |||
// This operation outputs "ref" after the update is done. | |||
// This makes it easier to chain operations that need to use the reset value. | |||
// | |||
// Args: | |||
// ref: A mutable `Tensor`. Must be one of the following types: | |||
// `float32`, `float64`, `int64`, `int32`, `uint8`, `uint16`, `int16`, | |||
// `int8`, `complex64`, `complex128`, `qint8`, `quint8`, `qint32`, `half`. | |||
// Should be from a `Variable` node. | |||
// value: A `Tensor`. Must have the same type as `ref`. | |||
// The value to be added to the variable. | |||
// use_locking: An optional `bool`. Defaults to `False`. | |||
// If True, the addition will be protected by a lock; | |||
// otherwise the behavior is undefined, but may exhibit less contention. | |||
// name: A name for the operation (optional). | |||
name: name); | |||
} | |||
public static Tensor assign_sub(RefVariable @ref, | |||
Tensor value, | |||
bool use_locking = false, | |||
string name = null) => gen_state_ops.assign_sub(@ref, | |||
value, | |||
use_locking: use_locking, | |||
name: name); | |||
//"""Update 'ref' by adding 'value' to it. | |||
// | |||
// This operation outputs "ref" after the update is done. | |||
// This makes it easier to chain operations that need to use the reset value. | |||
// | |||
// Args: | |||
// ref: A mutable `Tensor`. Must be one of the following types: | |||
// `float32`, `float64`, `int64`, `int32`, `uint8`, `uint16`, `int16`, | |||
// `int8`, `complex64`, `complex128`, `qint8`, `quint8`, `qint32`, `half`. | |||
// Should be from a `Variable` node. | |||
// value: A `Tensor`. Must have the same type as `ref`. | |||
// The value to be added to the variable. | |||
// use_locking: An optional `bool`. Defaults to `False`. | |||
// If True, the addition will be protected by a lock; | |||
// otherwise the behavior is undefined, but may exhibit less contention. | |||
// name: A name for the operation (optional). | |||
// | |||
// Returns: | |||
// Same as "ref". Returned as a convenience for operations that want | |||
// to use the new value after the variable has been updated. | |||
public static Tensor assign_add(RefVariable @ref, | |||
Tensor value, | |||
bool use_locking = false, | |||
string name = null) => gen_state_ops.assign_add(@ref, value, use_locking: use_locking, name: name); | |||
public static Tensor assign_add(RefVariable @ref, | |||
Tensor value, | |||
bool use_locking = false, | |||
string name = null) => gen_state_ops.assign_add(@ref, value, use_locking: use_locking, name: name); | |||
public static Tensor scatter_add(RefVariable @ref, Tensor indices, Tensor updates, bool use_locking = false, string name = null) | |||
{ | |||
if (@ref.dtype.is_ref_dtype()) | |||
return gen_state_ops.scatter_add(@ref, indices, updates, use_locking: use_locking, name: name); | |||
throw new NotImplementedException("scatter_add"); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -46,7 +46,7 @@ namespace Tensorflow | |||
trainable: trainable, | |||
validate_shape: validate_shape, | |||
name: name, | |||
dtype: TF_DataType.DtInvalid); | |||
dtype: dtype); | |||
} | |||
public static unsafe Tensor placeholder(TF_DataType dtype, TensorShape shape = null, string name = null) | |||