Update tensor value using `assign` function on tensor 2DIM

Issue

Let’s say I have 2-dimensional tensor using tf.Variable, [[10,9],[9,8]]. So I can change it’s value using index. In this case, I want to change 10 to 8, then I wrote this code, using assign function.

changeAbleTensor = tf.Variable([[10,9],[9,8]]);
changeAbleTensor[0][0].assign(10)

Code above, give me an error

AttributeError: ‘tensorflow.python.framework.ops.EagerTensor’ object has no attribute ‘assign’

But, when I change my code from changeAbleTensor[0][0].assign(10) to changeAbleTensor[0,0].assign(10) the 10 is changed to 8 successfully.

I’m wondering about that behavior, cause when I check the type of variable that using [0][0] and [0,0] it shows the same type.

type(changeAbleTensor[0][0]), type(changeAbleTensor[0,0])
# result
# (tensorflow.python.framework.ops.EagerTensor,
# tensorflow.python.framework.ops.EagerTensor)

Can you tell me why we [0][0] drive to error that said EagerTensor doesn’t have assign attribute and on the other side [0,0] has assign attribute even though both has the same type.

Thanks

Solution

Just an assumption

Applying the slice operation on a tf.Variable will return a Tensor that inherits the method assign of tf.Variable. The problem is changeAbleTensor[0][0] is first slicing a tf.Variable and then slicing a tf.Tensor and thus you appear to lose the context of the tf.Variable. For example, when slicing once, both options have the same methods including assign:

import tensorflow as tf

changeAbleTensor = tf.Variable([[1,9],[9,8]]);

print(dir(changeAbleTensor[0]))
print(dir(changeAbleTensor[0,0]))
['OVERLOADABLE_OPERATORS', '_USE_EQUALITY', '__abs__', '__add__', '__and__', '__array__', '__array_priority__', '__bool__', '__class__', '__complex__', '__copy__', '__deepcopy__', '__delattr__', '__dict__', '__dir__', '__div__', '__doc__', '__eq__', '__float__', '__floordiv__', '__format__', '__ge__', '__getattr__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__iter__', '__le__', '__len__', '__long__', '__lt__', '__matmul__', '__mod__', '__module__', '__mul__', '__ne__', '__neg__', '__new__', '__nonzero__', '__or__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rmatmul__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__tf_tracing_type__', '__truediv__', '__weakref__', '__xor__', '_add_consumer', '_as_node_def_input', '_as_tf_output', '_c_api_shape', '_copy', '_copy_nograd', '_copy_to_device', '_create_with_tf_output', '_datatype_enum', '_disallow_bool_casting', '_disallow_in_graph_mode', '_disallow_iteration', '_disallow_when_autograph_disabled', '_disallow_when_autograph_enabled', '_disallow_when_autograph_unavailable', '_handle_data', '_id', '_matmul', '_num_elements', '_numpy', '_numpy_internal', '_numpy_style_getitem', '_override_operator', '_prefer_custom_summarizer', '_rank', '_shape', '_shape_as_list', '_shape_tuple', '_summarize_value', '_tensor_shape', '_tf_api_names', '_tf_api_names_v1', '_with_index_add', '_with_index_max', '_with_index_min', '_with_index_update', 'assign', 'backing_device', 'consumers', 'cpu', 'device', 'dtype', 'eval', 'experimental_ref', 'get_shape', 'gpu', 'graph', 'is_packed', 'name', 'ndim', 'numpy', 'op', 'ref', 'set_shape', 'shape', 'value_index']
['OVERLOADABLE_OPERATORS', '_USE_EQUALITY', '__abs__', '__add__', '__and__', '__array__', '__array_priority__', '__bool__', '__class__', '__complex__', '__copy__', '__deepcopy__', '__delattr__', '__dict__', '__dir__', '__div__', '__doc__', '__eq__', '__float__', '__floordiv__', '__format__', '__ge__', '__getattr__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__iter__', '__le__', '__len__', '__long__', '__lt__', '__matmul__', '__mod__', '__module__', '__mul__', '__ne__', '__neg__', '__new__', '__nonzero__', '__or__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rmatmul__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__tf_tracing_type__', '__truediv__', '__weakref__', '__xor__', '_add_consumer', '_as_node_def_input', '_as_tf_output', '_c_api_shape', '_copy', '_copy_nograd', '_copy_to_device', '_create_with_tf_output', '_datatype_enum', '_disallow_bool_casting', '_disallow_in_graph_mode', '_disallow_iteration', '_disallow_when_autograph_disabled', '_disallow_when_autograph_enabled', '_disallow_when_autograph_unavailable', '_handle_data', '_id', '_matmul', '_num_elements', '_numpy', '_numpy_internal', '_numpy_style_getitem', '_override_operator', '_prefer_custom_summarizer', '_rank', '_shape', '_shape_as_list', '_shape_tuple', '_summarize_value', '_tensor_shape', '_tf_api_names', '_tf_api_names_v1', '_with_index_add', '_with_index_max', '_with_index_min', '_with_index_update', 'assign', 'backing_device', 'consumers', 'cpu', 'device', 'dtype', 'eval', 'experimental_ref', 'get_shape', 'gpu', 'graph', 'is_packed', 'name', 'ndim', 'numpy', 'op', 'ref', 'set_shape', 'shape', 'value_index']

whereas:

print(dir(changeAbleTensor[0][0]) == dir(changeAbleTensor[0,0]))

returns False, since the assign method is no longer there.

Answered By – AloneTogether

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published