'bool' object has no attribute 'shape' - python-3.x

I am training a neural network and a part of my code has returned the following error:
def plot_confusion_matrix(truth,
predictions,
classes,
normalize=False,
save=False,
cmap=plt.cm.Oranges,
path="confusion_matrix.png"):
acc = (np.array(truth) == np.array(predictions))
size = float(acc.shape[0]) #error
acc = np.sum(acc.astype("int32")) / size
(...)
AttributeError: 'bool' object has no attribute 'shape'
function call
pred = pred.numpy()
plot_confusion_matrix(truth=labels.numpy(),
predictions=pred,
save=False,
path="logref_confusion_matrix.png",
classes=["forward", "left", "right"])
Where the thuth represents the labels of Y and predictions the array of prediction, both with shape 32, 3. I checked the update on numpy, ipython etc and all are updated, tried some modification, but without success.

The only reason that acc would be a boolean and not a numpy array of booleans is that you are passing in a singular value for truth and predictions. In the code you provided, there would be no error for an actual array of 32x3. Look at the rest of your code and make sure you actually pass in an array to np.array() instead of singular values.

Related

Turning variable into a torch Tensor. Afterwards tensor is empty / has no element

The following is my Code. The "sequences" are my training data in the form [139 rows x 4 columns], 0) where the 139x4 are my signals and the 0 is my encoded label.
def __getitem__(self, idx):
sequence, label = self.sequences[idx]
#converting sequence and label to tensors
sequence = torch.Tensor(sequence.to_numpy())
print("label before tensor", label)
label = torch.Tensor(label).long()
print("numel() labels :", label.numel())
print("label shape :", shape(label))
return (sequence, label)
The Code output is:
>>label bevore tensor 0 (This is my encoded label)
>>numel() labels : 0
>>label shape : torch.Size([0])
Why is my label tensor empty?
Because torch.Tensor expects either an array (in which case this array becomes the underlying values) or several ints which will be the size of the tensor. Hence torch.Tensor(0) instantiates a tensor of size 0.
Either you use torch.Tensor([0]) or torch.tensor(0). Why these two objects behave in a different manner I don't know, but I'd recommend using the tensor (not capitalized) since it's better documented (the Tensor one seems to be part of the C port)
edit : found this useful thread about their difference

AttributeError: 'numpy.ndarray' object has no attribute 'unsqueeze'

I'm running a training code using pyhtorch and numpy.
This is the plot_example function:
def plot_example(low_res_folder, gen):
files=os.listdir(low_res_folder)
gen.eval()
for file in files:
image=Image.open("test_images/" + file)
with torch.no_grad():
upscaled_img=gen(
config1.both_transform(image=np.asarray(image))["image"]
.unsqueeze(0)
.to(config1.DEVICE)
)
save_image(upscaled_img * 0.5 + 0.5, f"saved/{file}")
gen.train()
The problem I have is that the unsqueeze attribute raises the error:
File "E:\Downloads\esrgan-tf2-masteren\modules\train1.py", line 58, in train_fn
plot_example("test_images/", gen)
File "E:\Downloads\esrgan-tf2-masteren\modules\utils1.py", line 46, in plot_example
config1.both_transform(image=np.asarray(image))["image"]
AttributeError: 'numpy.ndarray' object has no attribute 'unsqueeze'
The network is GAN network and gen() represents the Generator.
Make sure image is a tensor in the shape of [batch size, channels, height, width] before entering any Pytorch layers.
Here you have
image=np.asarray(image)
I would remove this numpy conversion and keep it a torch.tensor.
Or if you really want it to be a numpy array, then right before it enters your generator make sure to use torch.from_numpy() as shown in this documentation on your numpy image before it gets unsqueezed: https://pytorch.org/docs/stable/generated/torch.from_numpy.html
This function is ofcourse an alternative if you don't want to get rid of that original conversion.
Sarthak Jain

comparing torch.nn.CrossEntropyLoss with label as int and prob tensor produces an error

I have this criterion:
criterion = nn.CrossEntropyLoss()
And during training phase i have:
label = tensor([0.])
outputs = tensor([[0.0035, 0.0468]], grad_fn=<AddmmBackward>)
When i try to compare them:
criterion(outputs, label)
I get this error:
ret = torch._C._nn.nll_loss(input, target, weight, _Reduction.get_enum(reduction), ignore_index)
RuntimeError: Expected object of scalar type Long but got scalar type Float for argument #2 'target' in call to _thnn_nll_loss_forward
nn.CrossEntropyLoss expects its label input to be of type torch.Long and not torch.Float.
Note that this behavior is opposite to nn.BCELoss where target is expected to be of the same type as the input.
If you simply remove the . from your label:
label = torch.tensor([0]) # no . after 0 - now it is an integer
pytorch will automatically create label as torch.Long type, and you are okay:
In [*]: criterion(outputs, torch.tensor([0]))
Out[*]: tensor(0.7150)
Commenting on the other answers by planet_pluto and Craig.Li:
A more general way of casting an existing tensor is to use .to(...):
label = torch.tensor([0]).to(dtype=torch.long)
However, creating-and-casting is not very efficient way of doing stuff:
Think of it, you make pytroch create a torch.float tensor and then cast it to torch.long.
Alternatively, you can explicitly define the desired dtype upon creation of the tensor:
label = torch.tensor([0.], dtype=torch.long)
This way pytorch creates label with the desired dtype and no 2nd phase of casting is required.
You need to convert your label to a torch.LongTensor tensor.
label = tensor([0.]).type(torch.LongTensor)
nn.CrossEntropyLoss() expects targets of type torch.LongTensor. Just do this:
label = tensor([0.]).long()

error in converting tensor to numpy array

I'm trying to convert input_image which is a tensor to numpy array.Following the already answered questions here and several others that suggested to use input_image.eval() or equivalently sess.run() for this conversion, I did the same, but it throws an error and apparently expects a feed_dict value for the sess.run(). But since here I'm not trying to run an operation dependent on unknown values, I don't see the need for the feed_dict here because all I'm doing here is just conversion.
Besides, just so as to check I also tried converting a tf.constant([1,2,3]) value right above it using the same method and it got successfully compiled despite its data type being the same as input_image. Here's my code which is the part of larger script:
def call(self, x):
input_image = Input(shape=(None, None, 3))
print(input_image.shape)
print(type(tf.constant([1,2,3])))
print(type(input_image))
print(type(K.get_session().run(tf.constant([1,2,3]))))
print(type(K.get_session().run(input_image)))
and here's the error:
(?, ?, ?, 3)
<class 'tensorflow.python.framework.ops.Tensor'>
<class 'tensorflow.python.framework.ops.Tensor'>
<class 'numpy.ndarray'>
Traceback (most recent call last):
File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/client/session.py", line 1365, in _do_call
return fn(*args)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/client/session.py", line 1350, in _run_fn
target_list, run_metadata)
File "/usr/local/lib/python3.6/dist-packages/tensorflow_core/python/client/session.py", line 1443, in _call_tf_sessionrun
run_metadata)
tensorflow.python.framework.errors_impl.InvalidArgumentError: 2 root error(s) found.
(0) Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float and shape [?,?,?,3]
[[{{node input_1}}]]
[[input_1/_1051]]
(1) Invalid argument: You must feed a value for placeholder tensor 'input_1' with dtype float and shape [?,?,?,3]
[[{{node input_1}}]]
0 successful operations.
0 derived errors ignored.
I wonder why the former would work and the latter won't.
There is no such thing as "converting" a symbolic tensor to a numpy array, as the latter cannot hold the same kind of information as the former.
When you use eval() or session.run(), what you are doing is evaluating a symbolic expression to get a numerical result, which is a numpy array, but this is not a conversion. Evaluating an expression might or might not require additional input data (that's what the feed_dict is for), depending on the expression.
Evaluating a constant (tf.constant) does not require any input data, but evaluating your other expression does require the input data, so you cannot "convert" this to a numpy array.
Just adding to (or elaborating on) what #MatiasValdenegro said,
TensorFlow follows something called graph execution (or define-then-run). In other words, when you write a TensorFlow program it defines something called a data-flow graph which shows how the operations you defined are related to each other. And then you execute bits and pieces of that graph depending on the results you're after.
Let's consider two examples. (I am switching to a simple TensorFlow program instead of Keras bits as it makes things more clear - After all K.get_session() returns a Session object).
Example 1
Say you have the following program.
import tensorflow as tf
a = tf.placeholder(shape=[2,2], dtype=tf.float32)
b = tf.constant(1, dtype=tf.float32)
c = a * b
# Wrong: This is what you're doing essentially when you do sess.run(input_image)
with tf.Session() as sess:
print(sess.run(c))
# Right: You need to feed values that c is dependent on
with tf.Session() as sess:
print(sess.run(c, feed_dict={a: np.array([[1,2],[2,3]])}))
Whenever a resulting tensor (e.g. c) is dependent on a placeholder you cannot execute it and get the result without feeding values to all the dependent placeholders.
Example 2
When you define a tf.constant(1) this is not dependent on anything. In other words you don't need a feed_dict and can directly run eval() or sess.run() on it.
Update: Further explanation on why you need a feed_dict for input_image
TLDR: You need a feed_dict because your resulting Tensor is produced by an Input layer.
Your input_image is basically the resulting tensor you get by feeding something to the Input layer. Usually in Keras, you are not exposed to the internal placeholder level details. But you would do that via using model.fit() or model.evaluate(). You can see that Keras Input layer in fact uses a placeholder by analysing this line.
Hope I made my point clear that you do need to feed in a value to the placeholder to successfully evaluate the output of an Input layer. Because that basically holds a placeholder.
Update 2: How to feed to your Input layer
So, appears you can use feed_dict with Keras Input layer in the following manner. Instead of defining shape argument you straight away pass a placeholder to the tensor argument, which will bypass the internal placeholder creation in the layer.
from tensorflow.keras.layers import InputLayer
import numpy as np
import tensorflow.keras.backend as K
x = tf.placeholder(shape=[None, None, None, 3], dtype=tf.float32)
input_image = Input(tensor=x)
arr = np.array([[[[1,1,1]]]])
print(arr.shape)
print(K.get_session().run(input_image, feed_dict={x: arr}))

sklearn Ridgecv cross validation iterable

I am confused about the parameter cv in RidgeCV of sklearn.linear_model
Indeed, I already have my data splitted into a training set and validation set, and the documentation of RidgeCV says the parameter cv can be an iterable yielding train/test splits. So I write the following:
m = linear_model.RidgeCV(cv=zip(x_validation, y_validation))
m.fit(x_train, y_train)
But it does not work.
Python throws the following error
IndexError: arrays used as indices must be of integer (or boolean) type
What is wrong with my understanding of the parameter cv and is there an easy manner to use my own and already splitted validation set?
it seems the parameter cv expects a list of indices for use as training set and list of indices for use as validation set, so a solution
x = np.concatenate(x_train, x_validation)
y = np.concatenate(y_train, y_validation)
train_fraction = 0.9
train_indices = range(int(train_fraction * x.shape[0]))
validation_indices = range(int(train_fraction * x.shape[0]), x.shape[0])
m = linear_model.RidgeCV(cv=zip(train_indices, validation_indices))
m.fit(x, y)

Resources