Why can't I use numpy.logaddexp.reduce?
In [46]: a = np.array([1,5, 3, 2])
In [47]: np.logaddexp.reduce(a)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-47-701e5f4017fe> in <module>()
----> 1 np.logaddexp.reduce(a)
TypeError: No loop matching the specified signature was found for ufunc logaddexp
Looks like the reduce function doesn't accept an integer array. Use a floating point array:
In [28]: a = np.array([1.0, 5.0, 3.0, 2.0])
In [29]: np.logaddexp.reduce(a)
Out[29]: 5.1851824526038124
or use the dtype argument:
In [34]: a = np.array([1, 5, 3, 2])
In [35]: np.logaddexp.reduce(a, dtype=np.float64)
Out[35]: 5.1851824526038124
Related
I'm sure this question has an answer already somewhere, but I'm having trouble finding it since there are so many broadcasting questions, so perhaps someone can either point to it or answer directly.
I want to apply a function to each element of a NumPy array.
I have:
def test1(x):
return np.sum(x)
def test2(y):
return test1([5.0, y])
test2([1.0,2.0,3.0])
# I want the result to be [6.0, 7.0, 8.0]
# But I get TypeError: unsupported operand type(s) for +: 'float' and 'list'
How can I do this?
In Julia it would be:
test2.([1.0,2.0,3.0])
Thanks
Here's the full error message - which for some reason you decided wasn't relevant!
In [99]: def test1(x):
...: return np.sum(x)
...: def test2(y):
...: return test1([5.0, y])
...: test2([1.0,2.0,3.0])
/usr/local/lib/python3.8/dist-packages/numpy/core/fromnumeric.py:86: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
Traceback (most recent call last):
Input In [99] in <cell line: 5>
test2([1.0,2.0,3.0])
Input In [99] in test2
return test1([5.0, y])
Input In [99] in test1
return np.sum(x)
File <__array_function__ internals>:180 in sum
File /usr/local/lib/python3.8/dist-packages/numpy/core/fromnumeric.py:2298 in sum
return _wrapreduction(a, np.add, 'sum', axis, dtype, out, keepdims=keepdims,
File /usr/local/lib/python3.8/dist-packages/numpy/core/fromnumeric.py:86 in _wrapreduction
return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
TypeError: unsupported operand type(s) for +: 'float' and 'list'
Let's add a debugging print to test1:
In [100]: def test1(x):
...: print(x)
...: return np.sum(x)
...: test2([1.0,2.0,3.0])
[5.0, [1.0, 2.0, 3.0]]
....
Do you understand why x is this list - with a number and a list?
np.sum is a numpy function, and like most, it converts the input into an array first:
In [101]: np.array([5.0, [1.0, 2.0, 3.0]])
<ipython-input-101-79819e7b65b8>:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
np.array([5.0, [1.0, 2.0, 3.0]])
Out[101]: array([5.0, list([1.0, 2.0, 3.0])], dtype=object)
If we pass an array instead, we still get the ragged array warning, but it runs:
In [102]: test2(np.array([1,2,3]))
[5.0, array([1, 2, 3])]
/usr/local/lib/python3.8/dist-packages/numpy/core/fromnumeric.py:86: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
Out[102]: array([6., 7., 8.])
np.sum can operate on the 5.0 and np.array([1,2,3])
If we use the python sum instead, the number and array do add - without that intermediate step of creating a ragged array:
In [104]: sum([5, np.array([1,2,3])])
Out[104]: array([6, 7, 8])
Or the full function sequence:
In [105]: def test1(x):
...: return sum(x)
...: def test2(y):
...: return test1([5.0, y])
...: test2(np.array([1.0,2.0,3.0]))
Out[105]: array([6., 7., 8.])
Another version:
In [111]: def test1(x):
...: return np.add(*x)
...: def test2(y):
...: return test1([5.0, y])
...: test2([1.0,2.0,3.0])
Out[111]: array([6., 7., 8.])
np.sum takes an array(-like), and sums all the terms. np.add takes two arguments, and adds them (with broadcasting). *x is used to unpack the test2 list. np.add will convert the list y to array as needed.
Stripped of the function calls, what you are trying to do is:
In [112]: 5 + np.array([1,2,3])
Out[112]: array([6, 7, 8])
I have several RaggedTensors that I want to concatenate; I am using Keras. Vanilla Tensorflow will happily concatenate them, so I tried the code:
card_feature = layers.concatenate([ragged1, ragged2, ragged3])
but it gave the error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/timeroot/.local/lib/python3.8/site-packages/tensorflow/python/keras/engine/base_layer.py", line 925, in __call__
return self._functional_construction_call(inputs, args, kwargs,
File "/home/timeroot/.local/lib/python3.8/site-packages/tensorflow/python/keras/engine/base_layer.py", line 1084, in _functional_construction_call
base_layer_utils.create_keras_history(inputs)
File "/home/timeroot/.local/lib/python3.8/site-packages/tensorflow/python/keras/engine/base_layer_utils.py", line 191, in create_keras_history
_, created_layers = _create_keras_history_helper(tensors, set(), [])
File "/home/timeroot/.local/lib/python3.8/site-packages/tensorflow/python/keras/engine/base_layer_utils.py", line 222, in _create_keras_history_helper
raise ValueError('Tensorflow ops that generate ragged or sparse tensor '
ValueError: Tensorflow ops that generate ragged or sparse tensor outputs are currently not supported by Keras automatic op wrapping. Please wrap these ops in a Lambda layer:
```
weights_mult = lambda x: tf.sparse.sparse_dense_matmul(x, weights)
output = tf.keras.layers.Lambda(weights_mult)(input)
```
so then I tried:
concat_lambda = lambda xs: tf.concat(xs, axis=2)
card_feature = layers.Lambda(concat_lambda)([ragged1, ragged2, ragged3])
but it gave the exact same error, even though I had wrapped it. Is this a bug / is there a workaround?
Code to concatenate 3 Ragged Tensors is shown below:
import tensorflow as tf
print(tf.__version__)
Ragged_Tensor1 = tf.ragged.constant([[3, 1, 4, 1], [], [5, 9, 2], [6], []])
Ragged_Tensor2 = tf.ragged.constant([[5, 3]])
Ragged_Tensor3 = tf.ragged.constant([[6,7,8], [9,10]])
print(tf.concat([Ragged_Tensor1, Ragged_Tensor2, Ragged_Tensor3], axis=0))
Output is shown below:
2.3.0
<tf.RaggedTensor [[3, 1, 4, 1], [], [5, 9, 2], [6], [], [5, 3], [6, 7, 8], [9, 10]]>
But it looks like you are trying to concatenate Ragged Tensor Operations. Please share your complete code so that we can try to help you.
Having problems to implement a linear interpolation in numpy that works for n-D arrays. I would like a simple solution working for 1D and also 3D arrays.
For the linear interpolation, I'm using np.interp, which works great for 1D:
x = [1, 2, 3, 4, 5]
xp = [1, 3, 5]
fp = [10, 30, 50]
np.interp(x, xp, fp)
Out: array([10., 20., 30., 40., 50.])
Now if my fp has multiple columns:
fp_multicol = np.array([10, 30, 50, 100, 300, 500]).reshape((2,3))
Out:
array([[ 10, 30, 50],
[100, 300, 500]])
That doesn't work directly with np.interp since it can only handle 1D arrays:
np.interp(x, xp, fp_multicol)
Traceback (most recent call last):
blablabla
ValueError: object too deep for desired array
So I came up with a for-loop in a list comprehension:
np.array([np.interp(x, xp, col) for col in fp_multicol])
array([[ 10., 20., 30., 40., 50.],
[100., 200., 300., 400., 500.]])
But then that doesn't work for 1D arrays...
np.array([np.interp(x, xp, col) for col in fp])
Traceback (most recent call last):
blablabla
ValueError: object of too small depth for desired array
Any quick and simple solution that would work for both?
I'd expect numpy to have such interpolation function but so far could not find any.
I am trying to using tf.multinomial to sample, and I want to get the associated probability value of the sampled values. Here is my example code,
In [1]: import tensorflow as tf
In [2]: tf.enable_eager_execution()
In [3]: probs = tf.constant([[0.5, 0.2, 0.1, 0.2], [0.6, 0.1, 0.1, 0.1]], dtype=tf.float32)
In [4]: idx = tf.multinomial(probs, 1)
In [5]: idx # print the indices
Out[5]:
<tf.Tensor: id=43, shape=(2, 1), dtype=int64, numpy=
array([[3],
[2]], dtype=int64)>
In [6]: probs[tf.range(probs.get_shape()[0], tf.squeeze(idx)]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-8-56ef51f84ca2> in <module>
----> 1 probs[tf.range(probs.get_shape()[0]), tf.squeeze(idx)]
C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\ops\array_ops.py in _slice_helper(tensor, slice_spec, var)
616 new_axis_mask |= (1 << index)
617 else:
--> 618 _check_index(s)
619 begin.append(s)
620 end.append(s + 1)
C:\ProgramData\Anaconda3\lib\site-packages\tensorflow\python\ops\array_ops.py in _check_index(idx)
514 # TODO(slebedev): IndexError seems more appropriate here, but it
515 # will break `_slice_helper` contract.
--> 516 raise TypeError(_SLICE_TYPE_ERROR + ", got {!r}".format(idx))
517
518
TypeError: Only integers, slices (`:`), ellipsis (`...`), tf.newaxis (`None`) and scalar tf.int32/tf.int64 tensors are valid indices, got <tf.Tensor: id=7, shape=(2,), dtype=int32, numpy=array([3, 2])>
The expected result I want is [0.2, 0.1] as indicated by idx.
But in Numpy, this method works as answered in https://stackoverflow.com/a/23435869/5046896
How can I fix it?
You can try tf.gather_nd, you can try
>>> import tensorflow as tf
>>> tf.enable_eager_execution()
>>> probs = tf.constant([[0.5, 0.2, 0.1, 0.2], [0.6, 0.1, 0.1, 0.1]], dtype=tf.float32)
>>> idx = tf.multinomial(probs, 1)
>>> row_indices = tf.range(probs.get_shape()[0], dtype=tf.int64)
>>> full_indices = tf.stack([row_indices, tf.squeeze(idx)], axis=1)
>>> rs = tf.gather_nd(probs, full_indices)
Or, you can use tf.distributions.Multinomial, the advantage is you do not need to care about the batch_size in the above code. It works under varying batch_size when you set the batch_size=None. Here is a simple example,
multinomail = tf.distributions.Multinomial(
total_count=tf.constant(1, dtype=tf.float32), # sample one for each record in the batch, that is [1, batch_size]
probs=probs)
sampled_actions = multinomail.sample() # sample one action for data in the batch
predicted_actions = tf.argmax(sampled_actions, axis=-1)
action_probs = sampled_actions * predicted_probs
action_probs = tf.reduce_sum(action_probs, axis=-1)
I prefer the latter one because it is flexible and elegant.
the new higher order functions within TF is detailed here:
https://www.tensorflow.org/versions/r0.8/api_docs/python/functional_ops.html#map_fn
In particular, the map function looks useful. Here is what they wrote for the tutorial:
elems = [1, 2, 3, 4, 5, 6]
squares = map_fn(lambda x: x * x, elems)
# squares == [1, 4, 9, 16, 25, 36]
Thus I created an empty python file:
import tensorflow as tf
elems = [1, 2, 3, 4, 5, 6]
squares = tf.map_fn(lambda x: x * x, elems)
Running this gives this error:
/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/tensor_util.pyc in make_tensor_proto(values, dtype, shape)
323 else:
324 if values is None:
--> 325 raise ValueError("None values not supported.")
326 # if dtype is provided, forces numpy array to be the type
327 # provided if possible.
ValueError: None values not supported.
Does anyone know what's going on? Thanks!
Edit: I'm using TensorFlow version 0.8.
Your code seems OK, but I was able to fix it using the numpy array something like this:
import tensorflow as tf
import numpy as np
elems = np.array([1, 2, 3, 4, 5, 6], dtype="float32")
squares = tf.map_fn(lambda x: x * x, elems)
sess = tf.Session()
sess.run(squares)
This outputs:
[ 1. 4. 9. 16. 25. 36.]