What is "Const:0" in Tensor Object [duplicate] - python

I wonder if this is the correct understanding:
All tensors are derived from some operation, and operations are either given a name in the constructor, or given the default name for a particular kind of operation. If the name is not unique, TensorFlow automatically handles this by appending "_1", "_2", etc. An operation with n tensor outputs name these tensors "op_name:0", "op_name:1", ..., "op_name:n-1".
One problem seems to arise: if x is a tf.Variable, then x.name gives "variable_name:0". This is confusing: to what does "variable_name" refer?

Your observations on Tensor naming are absolutely correct: the name of a Tensor is the concatenation of
the name of the operation that produced it,
a colon (:), and
the index of that tensor in the outputs of the operation that produced it.
Therefore the tensor named "foo:2" is the output of the op named "foo" at position 2 (with indices starting from zero).
The naming of tf.Variable objects is slightly strange. Every tf.Variable contains a mutable tensor object that holds the state of the variable (and a few other tensors). A "Variable" op (which has the name "variable_name" in your example) "produces" this mutable tensor each time it is run as its 0th output, so the name of the mutable tensor is "variable_name:0".
Since a tf.Variable is mostly indistinguishable from a tf.Tensor—in that it can be used in the same places—we took the decision to make variable names resemble tensor names, so the Variable.name property returns the name of the mutable tensor. (This contrasts with tf.QueueBase and tf.ReaderBase objects, which are not usable directly as tensors (instead you have to call methods on them to create ops that operate on their state), so these do not have a tensor-like name.)

Related

Tensorflow set_shape function doesn't throw an error with a different shape at runtime

So I loaded some images of resolution 1024x1024 into a list of tensors, and then used the function set_shape to change the shape of every tensor of the list to [128,128,3]:
see code example here
However, when I call eval() and check the shape of the image coming from the tensor, it says that the shape is [1024,1024,3].
see code example here
Then why didn't set_shape throw an error?
I think you may be using set_shape() incorrectly. See Clarification on tf.Tensor.set_shape().
"One analogy is that tf.set_shape() is like a run-time cast in an object-oriented language like Java. For example, if you have a pointer to an Object but know that, in fact, it is a String, you might do the cast (String) obj in order to pass obj to a method that expects a String argument. However, if you have a String s and try to cast it to a java.util.Vector, the compiler will give you an error, because these two types are unrelated."
Basically this function provides a shape definition for a tensor that has an unspecified shape (I think). It does not resize a tensor into a tensor with a different number of elements, so if you attempt to use it this way it will fail. So why doesn't it throw an error? I'm not 100% sure but I'd guess it has a similar reason to why casting an integer as a string doesn't cause an error. It is a valid operation, but may cause issues later in your code when you attempt to use the variable assuming that the shape is actually as specified during your set_shape() call.
Consider using tf.image.resize() instead. This function is designed to do what you are attempting to do here. It accepts a batch of images and returns a resized batch.
new_list = tf.image.resize(lista,[128,128])

Why does `/=` raise an error but not `x = x / y` with a read-only numpy array?

I've always thought x /= y is equal to x = x / y. But now I'm facing a situation that I'll have an error when I use /= but not when using x = x / y. so definitely they shouldn't be the same in python.
The code is this. (is a simple deep learning code in Tensorflow, read code comments for some details).
import tensorflow as tf
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.fashion_mnist.load_data()
# x_train is a (60000, 28, 28) numpy matrix
x_train /= 1 # this will raise error "ValueError: output array is read-only"
x_train = x_train / 1 # but this will work fine
ValueError Traceback (most recent call last)
<ipython-input-44-fceb080f135a> in <module>()
1
----> 2 x_train /= 1
ValueError: output array is read-only
I want to ask the difference between them. Why I'm getting this error from /=?
As given in Immutable numpy array?, numpy arrays can be explicitly marked read-only.
When you run somearray =/ value, you're asking that array to be modified, in a way that (for typical mutable objects, like most numpy arrays) changes not just the individual reference, but the object itself; this means all copies of somearray (including ones internal to the tensorflow library that provided it) are subject to the change.
By contrast, when you run somearray = somearray / value, you're creating a new object, not modifying the old one, so there's no conflict with somearray being marked read-only.
The implementation of __itruediv__ in use could return a completely new object instead of modifying a read-only array, thus making =/ on read-only arrays work the same way += works for integers; however, this would mean having the operation allocate memory -- potentially expensive; for numpy, it makes sense to not do expensive things unless the author knows they're being done, so people don't write unnecessarily slow code by mistake. (Having the read-only flag significantly change performance and memory usage characteristics of an object would be a fair bit of extra state that a developer needs to keep in their head to write correct code!)
It has to do with python operator semantics and the principle of least surprise.
The expression x = x + 1 is approximately equivalent to x = type(x).__add__(x, 1)
The expression x += 1 is approximately equivalent to x = type(x).__iadd__(x, 1)
By convention, __add__ never mutates the object it is invoked on. __iadd__ sometimes does and sometimes doesn't. There are examples of both among Python's built-ins:
int and str are immutable, so always return a new object. The re-assignment step is very important in this case, since otherwise the name wouldn't get bound to the new value.
list adds in-place. The reassignment is effectively a no-op in this case (but it still happens).
Numpy arrays are usually mutable. Operations like +=, -=, *=, /=, etc. are truly in-place. In fact, they are supported by the same ufuncs that support the regular operations (add, subtract, multiply, true_divide), using the out parameter.
The developers had a choice to make for read-only arrays: either change the semantics of __iadd__, or raise an error. The principle of least surprise dictated the latter: a function should not change its fundamental behavior under certain circumstances without telling you. It's safe to assume that you used __iadd__ rather than __add__ because you wanted an in-place operation. The function notifies you when it can't do that, because the alternative is to do something you specifically didn't ask for.

What's the difference between list[::] and list?

This is a question rotating a matrix 90 degrees clockwise, i don't understand why i cannot use:
matrix = zip(*matrix[::-1])
but:
class Solution:
def rotate(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: void Do not return anything, modify matrix in-place instead.
"""
matrix[::] = zip(*matrix[::-1])
matrix in your method is a reference to a matrix object. Assignment to matrix will change matrix to reference your newly created object, but not change the contents of the original object. matrix[::] = invokes __setitem__ on the object referenced by matrix which changes the contents of the object accordingly.
In Python, all assignments bind a reference to a name. Operators call a method of an existing reference1. In your case, the statement
matrix = ...
is purely an assignment2. It computes the right hand side, and binds it to the name matrix in the local function scope. Whatever object matrix referred to when you passed it in remains untouched.
This is why you don't see the changes you made. It's not that the function doesn't work this way, it's that it doesn't do anything with the rotated list. The data is discarded as soon as the function exits.
The operation
matrix[:] = ...
on the other hand is not an assignment in the semantic sense, despite the = symbol3. It's a call to matrix.__setitem__(...)4. The__setitem__ method, like any other method, operates directly on the object without changing it's name bindings.
As far as indexing goes, [:] is equivalent to [::]. They are shorthand for [0:len(matrix)] and [0:len(matrix):1], respectively. In both cases, the default step size will be used. In general, any index with colons in it will be converted to a slice object. Missing elements are set to None and replaced by the sequence-specific defaults shown here.
1 Some operators, like += perform an assignment after calling a method. These are called augmented assignments. But that's not a case we're interested in right now.
2 Besides literal assignment statements (=), some other types of assignments are def (which binds a function object to its name), class (which does the same for a class object), import (which binds a module or element of a module to a name), passing arguments to a function (which binds objects to the local argument names or kwarg dictionary keys), and for (which binds an element from an iterator to the loop variable at each iteration).
3 It's still an assignment from the point of view of the parser, but the statement is handled completely differently. A similar statement that is not actually an assignment is using the = operator on an attribute implemented as a descriptor, such as a property.
4 Technically, it's more of an equivalent to type(matrix).__setitem__(matrix, ...), but with some additional optimizations. For example, the metaclass of type(matrix) won't ever be searched.

How to define a matrix with a data type of a class in python? [duplicate]

I'm creating a numpy array which is to be filled with objects of a particular class I've made. I'd like to initialize the array such that it will only ever contain objects of that class. For example, here's what I'd like to do, and what happens if I do it.
class Kernel:
pass
>>> L = np.empty(4,dtype=Kernel)
TypeError: data type not understood
I can do this:
>>> L = np.empty(4,dtype=object)
and then assign each element of L as a Kernel object (or any other type of object). It would be so neat were I able to have an array of Kernels, though, from both a programming point of view (type checking) and a mathematical one (operations on sets of functions).
Is there any way for me to specify the data type of a numpy array using an arbitrary class?
If your Kernel class has a predictable amount of member data, then you could define a dtype for it instead of a class. e.g. if it's parameterized by 9 floats and an int, you could do
kerneldt = np.dtype([('myintname', np.int32), ('myfloats', np.float64, 9)])
arr = np.empty(dims, dtype=kerneldt)
You'll have to do some coercion to turn them into objects of class Kernel every time you want to manipulate methods of a single kernel but that's one way to store the actual data in a NumPy array. If you want to only store a reference, then the object dtype is the best you can do without subclassing ndarray.
It has to be a Numpy scalar type:
http://docs.scipy.org/doc/numpy/reference/arrays.scalars.html#arrays-scalars-built-in
or a subclass of ndarray:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html#numpy.ndarray
As far as I know, enforcing a single type for elements in a numpy.ndarray has to be done manually (unless the array contains Numpy scalars): there is no built-in checking mechanism (your array has dtype=object). If you really want to enforce a single type, you have to subclass ndarray and implement the checks in the appropriate methods (__setitem__, etc.).
If you want to implement operations on a set of functions (Kernel objects), you might be able to do so by defining the proper operations directly in your Kernel class. This is what I did for my uncertainties.py module, which handles numpy.ndarrays of numbers with uncertainties.

What is the identity of "ndim, shape, size, ..etc" of ndarray in numpy

I'm quite new at Python.
After using Matlab for many many years, recently, I started studying numpy/scipy
It seems like the most basic element of numpy seems to be ndarray.
In ndarray, there are following attributes:
ndarray.ndim
ndarray.shape
ndarray.size
...etc
I'm quite familiar with C++/JAVA classes, but I'm a novice at Python OOP.
Q1: My first question is what is the identity of the above attributes?
At first, I assumed that the above attribute might be public member variables. But soon, I found that a.ndim = 10 doesn't work (assuming a is an object of ndarray) So, it seems it is not a public member variable.
Next, I guessed that they might be public methods similar to getter methods in C++. However, when I tried a.nidm() with a parenthesis, it doesn't work. So, it seems that it is not a public method.
The other possibility might be that they are private member variables, but but print a.ndim works, so they cannot be private data members.
So, I cannot figure out what is the true identity of the above attributes.
Q2. Where I can find the Python code implementation of ndarray? Since I installed numpy/scipy on my local PC, I guess there might be some ways to look at the source code, then I think everything might be clear.
Could you give some advice on this?
numpy is implemented as a mix of C code and Python code. The source is available for browsing on github, and can be downloaded as a git repository. But digging your way into the C source takes some work. A lot of the files are marked as .c.src, which means they pass through one or more layers of perprocessing before compiling.
And Python is written in a mix of C and Python as well. So don't try to force things into C++ terms.
It's probably better to draw on your MATLAB experience, with adjustments to allow for Python. And numpy has a number of quirks that go beyond Python. It is using Python syntax, but because it has its own C code, it isn't simply a Python class.
I use Ipython as my usual working environment. With that I can use foo? to see the documentation for foo (same as the Python help(foo), and foo?? to see the code - if it is writen in Python (like the MATLAB/Octave type(foo))
Python objects have attributes, and methods. Also properties which look like attributes, but actually use methods to get/set. Usually you don't need to be aware of the difference between attributes and properties.
x.ndim # as noted, has a get, but no set; see also np.ndim(x)
x.shape # has a get, but can also be set; see also np.shape(x)
x.<tab> in Ipython shows me all the completions for a ndarray. There are 4*18. Some are methods, some attributes. x._<tab> shows a bunch more that start with __. These are 'private' - not meant for public consumption, but that's just semantics. You can look at them and use them if needed.
Off hand x.shape is the only ndarray property that I set, and even with that I usually use reshape(...) instead. Read their docs to see the difference. ndim is the number of dimensions, and it doesn't make sense to change that directly. It is len(x.shape); change the shape to change ndim. Likewise x.size shouldn't be something you change directly.
Some of these properties are accessible via functions. np.shape(x) == x.shape, similar to MATLAB size(x). (MATLAB doesn't have . attribute syntax).
x.__array_interface__ is a handy property, that gives a dictionary with a number of the attributes
In [391]: x.__array_interface__
Out[391]:
{'descr': [('', '<f8')],
'version': 3,
'shape': (50,),
'typestr': '<f8',
'strides': None,
'data': (165646680, False)}
The docs for ndarray(shape, dtype=float, buffer=None, offset=0,
strides=None, order=None), the __new__ method lists these attributes:
`Attributes
----------
T : ndarray
Transpose of the array.
data : buffer
The array's elements, in memory.
dtype : dtype object
Describes the format of the elements in the array.
flags : dict
Dictionary containing information related to memory use, e.g.,
'C_CONTIGUOUS', 'OWNDATA', 'WRITEABLE', etc.
flat : numpy.flatiter object
Flattened version of the array as an iterator. The iterator
allows assignments, e.g., ``x.flat = 3`` (See `ndarray.flat` for
assignment examples; TODO).
imag : ndarray
Imaginary part of the array.
real : ndarray
Real part of the array.
size : int
Number of elements in the array.
itemsize : int
The memory use of each array element in bytes.
nbytes : int
The total number of bytes required to store the array data,
i.e., ``itemsize * size``.
ndim : int
The array's number of dimensions.
shape : tuple of ints
Shape of the array.
strides : tuple of ints
The step-size required to move from one element to the next in
memory. For example, a contiguous ``(3, 4)`` array of type
``int16`` in C-order has strides ``(8, 2)``. This implies that
to move from element to element in memory requires jumps of 2 bytes.
To move from row-to-row, one needs to jump 8 bytes at a time
(``2 * 4``).
ctypes : ctypes object
Class containing properties of the array needed for interaction
with ctypes.
base : ndarray
If the array is a view into another array, that array is its `base`
(unless that array is also a view). The `base` array is where the
array data is actually stored.
All of these should be treated as properties, though I don't think numpy actually uses the property mechanism. In general they should be considered to be 'read-only'. Besides shape, I only recall changing data (pointer to a data buffer), and strides.
Regarding your first question, Python has syntactic sugar for properties, including fine-grained control of getting, setting, deleting them, as well as restricting any of the above.
So, for example, if you have
class Foo(object):
#property
def shmip(self):
return 3
then you can write Foo().shmip to obtain 3, but, if that is the class definition, you've disabled setting Foo().shmip = 4.
In other words, those are read-only properties.
Question 1
The list you're mentioning is one that contains attributes for a Numpy array.
For example:
a = np.array([1, 2, 3])
print(type(a))
>><class 'numpy.ndarray'>
Since a is an nump.ndarray you're able to use those attributes to find out more about it. (i.e a.size will result in 3). To get information about what each one does visit SciPy's documentation about the attributes.
Question 2
You can start here to get yourself familiar with some of the basics tools of Numpy as well as the Reference Manual assuming you're using v1.9. For information specific to Numpy Array you can go to Array Objects.
Their documentation is very extensive and very helpful. Examples are provided throughout the website showing multiple examples.

Categories

Resources