pic should be PIL Image or ndarray. Got <class 'tuple'> - pytorch

Im trying to download cifar10 images and put it in dataloader, however the problem
'pic should be PIL Image or ndarray. Got <class 'tuple'>' keeps occur. Please help me.
transform_list={'train':transforms.Compose([transforms.Resize(256),
transforms.RandomHorizontalFlip(),
transforms.FiveCrop(size=224),
transforms.ToTensor(),
transforms.Normalize(mean=(0.5,0.5,0.5), std=(0.5,0.5,0.5))]),
'test':transforms.Compose([transforms.Resize(224),
transforms.ToTensor(),
transforms.Normalize(mean=(0.5,0.5,0.5), std=(0.5,0.5,0.5))])}
cifar10_train=torchvision.datasets.CIFAR10(root='./data',train=True,download=True,transform=transform_list['train'])
cifar10_test=torchvision.datasets.CIFAR10(root='./data',train=False,download=True,transform=transform_list['test'])
trainloader = torch.utils.data.DataLoader(cifar10_train, batch_size=128,
shuffle=True)
testloader = torch.utils.data.DataLoader(cifar10_test, batch_size=128,
shuffle=True)
print(cifar10_train)
print(cifar10_train[0])
Error
TypeError Traceback (most recent call last)
<ipython-input-25-03a0afd731d1> in <module>()
15
16 print(cifar10_train)
---> 17 print(cifar10_train[0])
3 frames
/usr/local/lib/python3.7/dist-packages/torchvision/transforms/functional.py in to_tensor(pic)
100 """
101 if not(F_pil._is_pil_image(pic) or _is_numpy(pic)):
--> 102 raise TypeError('pic should be PIL Image or ndarray. Got {}'.format(type(pic)))
103
104 if _is_numpy(pic) and not _is_numpy_image(pic):
TypeError: pic should be PIL Image or ndarray. Got <class 'tuple'>

The reason of this error is using FiveCrop(). Because it gives a tuple of image array.
To solve this problem use Lambda to normalize each element of the tuple. Try this snippet to solve the problem:
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Resize((256, 256)),
transforms.RandomHorizontalFlip(),
transforms.FiveCrop((224, 224)),
transforms.Lambda(lambda crops: torch.stack([transforms.Normalize(mean, std)(crop) for crop in crops]))
])

Related

Predicting a single image with a pretrained load_model in Keras - how to get the label?

I have this code which is meant to take in a single image, convert it to fit in to a CNN model in keras, and then predict if it is a 1 or 0 outcome (for a binomial classification problem).
My model's first input layer has the shape of [(None, 224, 224, 3)].
import os
import numpy as np
from PIL import Image
import tensorflow as tf
from tensorflow.keras.models import load_model
im_path = "..\\Dataset_Thermal_Project\\Camera_videos\\image21.jpg"
def load_image():
im = Image.open(im_path)
im = im.resize((224,224))
im_array = np.array(im)/255 # a normalised 2D array
im_array = im_array.reshape(-1, 224, 224, 3) # to shape as (1, 224, 224, 3)
return im_array
def predict_image():
model_cnn_ltsm = load_model("..\\Camera_videos\\Saved_models\\cnn_ltsm_model.h5")
model_cnn_ltsm_ = tf.keras.models.Model(model_cnn_ltsm.inputs, model_cnn_ltsm.outputs)
image = load_image()
# pred_label = model_cnn_.predict(image)[0]
pred_label = model_cnn_.predict_classes(image)[0]
return pred_label
predict_image()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Input In [49], in <cell line: 1>()
----> 1 predict_image()
Input In [48], in predict_image()
5 image = load_image()
7 # pred_label = model_cnn_.predict(image)[0]
----> 9 pred_label = model_cnn_.predict_classes(image)[0]
10 return pred_label
AttributeError: 'Functional' object has no attribute 'predict_classes'.
So that gives the AttributeError.
If I use pred_label = model_cnn_.predict(image)[0] then I just get
1/1 [==============================] - 0s 13ms/step
array([1.], dtype=float32)
I have also tried
pred_label = model_cnn_.predict(image)[0]
return np.argmax(pred_label)
but this returns 0 for both image20.jpg(no human) and image21.jpg(human) which is not right.
What is the correct way to do it please?
The files, image21.jpg, image20.jpg and cnn_ltsm_model.h5, are loaded here,
https://github.com/bluetail14/Thermal_data_images_project if someone wants to reproduce this problem.

LabelEncoder instance is not fitted yet

I have a code for prediction of unseen data in a sentence classification task.
The code is
from sklearn.preprocessing import LabelEncoder
maxlen = 1152
### PREDICT NEW UNSEEN DATA ###
tokenizer = Tokenizer()
label_enc = LabelEncoder()
X_test = ['this is boring', 'wow i like this you did a great job']
X_test = tokenizer.texts_to_sequences(X_test)
X_test = sequence.pad_sequences(X_test, maxlen=maxlen)
a = (model.predict(X_test)>0.5).astype(int).ravel()
print(a)
reverse_pred = label_enc.inverse_transform(a.ravel())
print(reverse_pred)
But I am getting this error
[1 1]
---------------------------------------------------------------------------
NotFittedError Traceback (most recent call last)
<ipython-input-33-7e12dbe8aec1> in <module>()
39 print(a)
40
---> 41 reverse_pred = label_enc.inverse_transform(a.ravel())
42 print(reverse_pred)
1 frames
/usr/local/lib/python3.6/dist-packages/sklearn/utils/validation.py in check_is_fitted(estimator, attributes, msg, all_or_any)
965
966 if not attrs:
--> 967 raise NotFittedError(msg % {'name': type(estimator).__name__})
968
969
NotFittedError: This LabelEncoder instance is not fitted yet. Call 'fit' with appropriate arguments before using this estimator.
I have used Sequential model and the model.fit is written as history=model.fit() in the training part. Why am I getting this error?
following the sklearn documentation and what reported here, you have simply to fit your encoder before making an inverse transform
y = ['positive','negative','positive','negative','positive','negative']
label_enc = LabelEncoder()
label_enc.fit(y)
model_predictions = np.random.uniform(0,1, 3)
model_predictions = (model_predictions>0.5).astype(int).ravel()
model_predictions = label_enc.inverse_transform(model_predictions)

XLNetForSequenceClassification Pretrained model unable to load

I tried loading the XLNet pretrained but this occurred. I've tried this before and it worked, however, now it doesn't. Any suggestion on how to fix this problem?
model = XLNetForSequenceClassification.from_pretrained("xlnet-large-cased", num_labels = 2)
model.to(device)
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-55-d6f698a3714b> in <module>()
----> 1 model = XLNetForSequenceClassification.from_pretrained("xlnet-large-cased", num_labels = 2)
2 model.to(device)
3 frames
/usr/local/lib/python3.6/dist-packages/torch/nn/modules/sparse.py in __init__(self, num_embeddings, embedding_dim, padding_idx, max_norm, norm_type, scale_grad_by_freq, sparse, _weight)
95 self.scale_grad_by_freq = scale_grad_by_freq
96 if _weight is None:
---> 97 self.weight = Parameter(torch.Tensor(num_embeddings, embedding_dim))
98 self.reset_parameters()
99 else:
RuntimeError: Trying to create tensor with negative dimension -1: [-1, 1024]
You should import XLNetForSequenceClassification from transformers and not from pytorch-transformers. First, make sure transformers is installed:
> pip install transformers
Then, in your code:
from transformers import XLNetForSequenceClassification
model = XLNetForSequenceClassification.from_pretrained("xlnet-large-cased", num_labels = 2)
This should work.
If you've not changed internally anything, most likely a version mismatch. Have you upgraded any relevant modules? Go back to previous version if you have that should solve it.
Pytorch Quantization RuntimeError: Trying to create tensor with negative dimension

ValueError: Object arrays cannot be loaded when allow_pickle=False for IMDB data for Keras

First I am using Tensorflow 1.15 and Keras 2.2.4.
I ran the following code in Jupyter Notebook:
from keras.datasets import imdb
from keras import preprocessing
max_features = 10000
maxlen = 20
(x_train, y_train), (x_test, y_test) = imdb.load_data(
num_words=max_features)
x_train = preprocessing.sequence.pad_sequences(x_train, maxlen=maxlen)
x_test = preprocessing.sequence.pad_sequences(x_test, maxlen=maxlen)
and it gave me this error:
Downloading data from https://s3.amazonaws.com/text-datasets/imdb.npz
17465344/17464789 [==============================] - 8s 0us/step
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-6-609d113f6ed2> in <module>
6
7 (x_train, y_train), (x_test, y_test) = imdb.load_data(
----> 8 num_words=max_features)
9
10 x_train = preprocessing.sequence.pad_sequences(x_train, maxlen=maxlen)
~\.conda\envs\tensorflow_env\lib\site-packages\keras\datasets\imdb.py in load_data(path, num_words, skip_top, maxlen, seed, start_char, oov_char, index_from, **kwargs)
57 file_hash='599dadb1135973df5b59232a0e9a887c')
58 with np.load(path) as f:
---> 59 x_train, labels_train = f['x_train'], f['y_train']
60 x_test, labels_test = f['x_test'], f['y_test']
61
~\.conda\envs\tensorflow_env\lib\site-packages\numpy\lib\npyio.py in __getitem__(self, key)
260 return format.read_array(bytes,
261 allow_pickle=self.allow_pickle,
--> 262 pickle_kwargs=self.pickle_kwargs)
263 else:
264 return self.zip.read(key)
~\.conda\envs\tensorflow_env\lib\site-packages\numpy\lib\format.py in read_array(fp, allow_pickle, pickle_kwargs)
720 # The array contained Python objects. We need to unpickle the data.
721 if not allow_pickle:
--> 722 raise ValueError("Object arrays cannot be loaded when "
723 "allow_pickle=False")
724 if pickle_kwargs is None:
ValueError: Object arrays cannot be loaded when allow_pickle=False
What is wrong with it? I took this code from "Deep Learning with Python" book.
Thanks
When numpy is loading a lot of data, it needs to have allow_pickle set to True. You should change that manually.
np.load("place of bumpy file.npy", allow_pickle=True)
I think imdb has numpy load inside.

Running through a dataloader in Pytorch using Google Colab

I am trying to use Pytorch to run classification on a dataset of images of cats and dogs. In my code I am so far downloading the data and going into the folder train which has two folders in it called "cats" and "dogs." I am then trying to load this data into a dataloader and iterate through batches, but it is giving me some error I don't understand in the iteration step.
Since it is Google Colabs I have code in there for downloading data and installing libraries. Any other advice on my code so far would be appreciated as well.
!pip install torch
!pip install torchvision
from __future__ import print_function, division
import os
import torch
import pandas as pd
import numpy as np
# For showing and formatting images
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
# For importing datasets into pytorch
import torchvision.datasets as dataset
# Used for dataloaders
import torch.utils.data as data
# For pretrained resnet34 model
import torchvision.models as models
# For optimisation function
import torch.nn as nn
import torch.optim as optim
!wget http://files.fast.ai/data/dogscats.zip
!unzip dogscats.zip
batch_size = 256
train_raw = dataset.ImageFolder(PATH+"train", transform=transforms.ToTensor())
train_loader = data.DataLoader(train_raw, batch_size=batch_size, shuffle=True)
for batch_idx, (data, target) in enumerate(train_loader):
print("Data: ", batch_idx)
The error comes up on the last lines and is below:
RuntimeErrorTraceback (most recent call last)
<ipython-input-66-c32dd0c1b880> in <module>()
----> 1 for batch_idx, (data, target) in enumerate(train_loader):
2 print("Data: ", batch_idx)
3
/usr/local/lib/python2.7/dist-packages/torch/utils/data/dataloader.pyc in __next__(self)
257 if self.num_workers == 0: # same-process loading
258 indices = next(self.sample_iter) # may raise StopIteration
--> 259 batch = self.collate_fn([self.dataset[i] for i in indices])
260 if self.pin_memory:
261 batch = pin_memory_batch(batch)
/usr/local/lib/python2.7/dist-packages/torch/utils/data/dataloader.pyc in default_collate(batch)
133 elif isinstance(batch[0], collections.Sequence):
134 transposed = zip(*batch)
--> 135 return [default_collate(samples) for samples in transposed]
136
137 raise TypeError((error_msg.format(type(batch[0]))))
/usr/local/lib/python2.7/dist-packages/torch/utils/data/dataloader.pyc in default_collate(batch)
110 storage = batch[0].storage()._new_shared(numel)
111 out = batch[0].new(storage)
--> 112 return torch.stack(batch, 0, out=out)
113 elif elem_type.__module__ == 'numpy' and elem_type.__name__ != 'str_' \
114 and elem_type.__name__ != 'string_':
/usr/local/lib/python2.7/dist-packages/torch/functional.pyc in stack(sequence, dim, out)
62 inputs = [t.unsqueeze(dim) for t in sequence]
63 if out is None:
---> 64 return torch.cat(inputs, dim)
65 else:
66 return torch.cat(inputs, dim, out=out)
RuntimeError: invalid argument 0: Sizes of tensors must match except in dimension 0. Got 400 and 487 in dimension 2 at /pytorch/torch/lib/TH/generic/THTensorMath.c:2897
Thanks
I think the main problem was images being of different size . I may have understood ImageFolder in other way but, i think you don't need labels for images if the directory structure is as specified in pytorch and pytorch will figure out the labels for you.
I would also add more things to your transform that automatically resizes every images from the folder such as:
normalize = transforms.Normalize(
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]
)
transform = transforms.Compose(
[transforms.ToTensor(),transforms.Resize((224,224)),
normalize])
Also you can use other tricks to make your DataLoader much faster such as adding batch_size and number of cpu workers such as:
testloader = DataLoader(testset, batch_size=16,
shuffle=False, num_workers=4)
I think this will make you pipeline much faster.
I see two problems in your code first you are importing import torch.utils.data as data and again replacing that in the data loader. Please keep the imported module and your variable name in separate namespace. I think this error could be because of different sizes of data returned by dataloder(images) and labels. As you can see there is an error in concatenation because the first dimension ie. the label size and number of images in folder do not match. Hope this helps.
I think I was wrong in my comment to Manoj Acharya, the problem was in the batch_size being put into the dataloader. I read the below source and it seems you can't batch images together with different sizes:
https://medium.com/#yvanscher/pytorch-tip-yielding-image-sizes-6a776eb4115b
So in my code after changing the data variable Manoj points out I changed the batch_size to 1 and the program stopped failing. I want to put it in batches though so I added a further transform CenterCrop() to resize all images to the same size. Below is my new code:
!pip install torch
!pip install torchvision
from __future__ import print_function, division
import os
import torch
import pandas as pd
import numpy as np
# For showing and formatting images
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
# For importing datasets into pytorch
import torchvision.datasets as dataset
# Used for dataloaders
from torch.utils.data import DataLoader
# For pretrained resnet34 model
import torchvision.models as models
# For optimisation function
import torch.nn as nn
import torch.optim as optim
# For turning data into tensors
import torchvision.transforms as transforms
!wget http://files.fast.ai/data/dogscats.zip
!unzip dogscats.zip
batch_size = 256
sz = 224
train_raw = dataset.ImageFolder(PATH+"train", transform=transforms.Compose([transforms.CenterCrop(sz),transforms.ToTensor()]))
train_loader = DataLoader(train_raw,batch_size=batch_size, shuffle=True)
for batch_idx, (data, target) in enumerate(train_loader):
print("Data: ", batch_idx)
Thanks

Resources