theano is a very strict typed library.
There is no powerful type inference like python, so of course you will want to take advantage of the cast.
The cast of theano is implemented by theano.tensor.cast ().
Let's use cast immediately. By default, a matrix defined in float64 type is converted to int32 type.
python
import theano.tensor as T
x = T.matrix()
x_as_int = T.cast(x, 'int32')
type(x), type(x_as_int)
Output result
(theano.tensor.var.TensorVariable, theano.tensor.var.TensorVariable)
In the above results, both show the same type (TensorVariable).
This is because Theano's specification defines symbols as variables, not values.
Use theano.printing.debugprint () to see the type of the symbol's contents.
type of x
import theano
theano.printing.debugprint(x)
Output result
<TensorType(float64, matrix)> [id A]
x_as_int type
theano.printing.debugprint(x_as_int)
Output result
Elemwise{Cast{int32}} [id A] ''
|<TensorType(float64, matrix)> [id B]
I see, it was originally a float64 type, but in x_as_int it seems to be cast to int32.
Let's actually enter the value and check the behavior.
To put a value in a symbol, you need to define a function.
By defining a formula using symbols as a function and entering a value in that function, the processing result of the formula is returned as the return value of the function.
At this time, the type of the input value depends on the symbol type.
If you put in an inappropriate type, you will get an error, so
If you set the int32 symbol x_as_int as input, you should get an error if you enter a decimal.
Function definition
import numpy as np
mat = np.array([[1.0, 0.0], [0.0, 1.0]], dtype="float64")
mat_int = np.array([[1, 0], [0, 1]], dtype="int32")
y = x * 2
f = theano.function(inputs=[x], outputs=y)
y_as_int = x_as_int * 2
f_as_int = theano.function(inputs=[x_as_int], outputs=y_as_int)
f(x)
f(mat)
Execution result
array([[ 2., 0.],
[ 0., 2.]])
f(x_as_int)
f(mat_int)
Execution result
array([[ 2., 0.],
[ 0., 2.]])
f_as_int(x)
f_as_int(mat)
Execution result
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-56-31692f0163e9> in <module>()
----> 1 f_as_int(mat)
/home/ubuntu/anaconda3/lib/python3.5/site-packages/theano/compile/function_module.py in __call__(self, *args, **kwargs)
786 s.storage[0] = s.type.filter(
787 arg, strict=s.strict,
--> 788 allow_downcast=s.allow_downcast)
789
790 except Exception as e:
/home/ubuntu/anaconda3/lib/python3.5/site-packages/theano/tensor/type.py in filter(self, data, strict, allow_downcast)
138 '"function".'
139 % (self, data.dtype, self.dtype))
--> 140 raise TypeError(err_msg, data)
141 elif (allow_downcast is None and
142 type(data) is float and
TypeError: ('Bad input argument to theano function with name "<ipython-input-54-50af382d0dd4>:2" at index 0 (0-based)', 'TensorType(int32, matrix) cannot store a value of dtype float64 without risking loss of precision. If you do not mind this loss, you can: 1) explicitly cast your data to int32, or 2) set "allow_input_downcast=True" when calling "function".', array([[ 1., 0.],
[ 0., 1.]]))
f_as_int(x_as_int)
array([[2, 0],
[0, 2]], dtype=int32)
As expected, f_as_int (mat) with the input value set to float64 type while specifying the int32 type as the input symbol threw an error.
Now you can see the cast movement in theano safely.
Recommended Posts