one code segment error that might be related to python 2.7 vs python 3.x - python-2.7

I am trying to re-use the following code segment. The specific line of code gt_bg = gt_bg.reshape(*gt_bg.shape, 1) gives me the error messages such as
gt_bg = gt_bg.reshape(*gt_bg.shape, 1)
SyntaxError: only named arguments may follow *expression
I am using Python 2.7, is this the problem? If that's the case, how to modify it to make it fit to Python2.7? Thanks.
for image_file in image_paths[batch_i:batch_i+batch_size]:
gt_image_file = label_paths[os.path.basename(image_file)]
image = scipy.misc.imresize(scipy.misc.imread(image_file), image_shape)
gt_image = scipy.misc.imresize(scipy.misc.imread(gt_image_file), image_shape)
gt_bg = np.all(gt_image == background_color, axis=2)
gt_bg = gt_bg.reshape(*gt_bg.shape, 1)
gt_image = np.concatenate((gt_bg, np.invert(gt_bg)), axis=2)
images.append(image)
gt_images.append(gt_image)

This is not really related to the Python 2 / Python 3 difference, that's a red herring.
numpy array's reshape method expects to receive the new shape directly, as a tuple, not unpacked into dimensions. So, instead of this:
gt_bg = gt_bg.reshape(*gt_bg.shape, 1)
It's expecting this:
gt_bg = gt_bg.reshape(gt_bg.shape + (1,))
Or, if you want to be cool, you can just set the shape directly:
gt_bg.shape += (1,)
Or, if you want to be weird, you can use an Ellipsis in a slice:
gt_bg = gt_bg[...,None]

Related

I want to deploy a pytorch segmentation model in a C++ application .. C++ equivalent preprocessing

I want to deploy a pytorch segmentation model in a C++ application. I knew that I have to convert the model to a Torch Script and use libtorch.
However, what is C++ equivalent to the following pre-preprocessing (It's Ok to convert opencv, but I don't know how to convert the others)?
import torch.nn.functional as F
train_tfms = transforms.Compose([transforms.ToTensor(), transforms.Normalize(channel_means, channel_stds)])
input_width, input_height = input_size[0], input_size[1]
img_1 = cv.resize(img, (input_width, input_height), cv.INTER_AREA)
X = train_tfms(Image.fromarray(img_1))
X = Variable(X.unsqueeze(0)).cuda() # [N, 1, H, W]
mask = model(X)
mask = F.sigmoid(mask[0, 0]).data.cpu().numpy()
mask = cv.resize(mask, (img_width, img_height), cv.INTER_AREA)
To create the transformed dataset, you will need to call MapDataset<DatasetType, TransformType> map(DatasetType dataset,TransformType transform) (see doc).
You will likely have to implement your 2 transforms yourself, just look at how they implemented theirs and imitate that.
The libtorch tutorial will guide you through datasets and dataloaders
You can call the sigmoid function with torch::nn::functionql::sigmoid I believe

AttributeError: 'NoneType' object has no attribute 'shape' using OpenCV

I am reading images from google drive mounted to google colab. I have two folders, one with positive covid-19 chest x-rays and another with normal chest x-rays. I am trying to show these images side-by-side for comparison. Here are images of the code and error:
First Lines Of Code
Error Image
Here is also the written code:
Cimages = ('/content/drive/My Drive/Data/Covid')
Nimages = ('/content/drive/My Drive/Data/Normal')
import skimage
from skimage.transform import resize
def plot(i):
normal = cv2.imread(dataset +'Normal//' + Nimages[i])
normal = skimage.transform.resize(normal, (150,150,3))
covid = cv2.imread(dataset +'Covid//' + Cimages[i])
covid = skimage.transform.resize(normal, (150,150,3), mode = reflect)
pair = np.concatenate((normal, covid), axis = 1)
print('Normal vs. Covid')
plt.figure(figsize=(10,5))
plt.imshow(pair)
plt.show()
for i in range(0,3):
plot(i)
This gives me an error:
AttributeError Traceback (most recent call last)
<ipython-input-52-237aff042641> in <module>()
1 for i in range(0,3):
----> 2 plot(i)
<ipython-input-50-85bb2e03725c> in plot(i)
3 def plot(i):
4 normal = cv2.imread(dataset +'Normal//' + Nimages[i])
----> 5 normal = skimage.transform.resize(normal, (150,150,3))
6 covid = cv2.imread(dataset +'Covid//' + Cimages[i])
7 covid = skimage.transform.resize(normal, (150,150,3), mode = reflect)
/usr/local/lib/python3.6/dist-packages/skimage/transform/_warps.py in resize(image, output_shape, order, mode, cval, clip, preserve_range, anti_aliasing, anti_aliasing_sigma)
89 output_shape = tuple(output_shape)
90 output_ndim = len(output_shape)
---> 91 input_shape = image.shape
92 if output_ndim > image.ndim:
93 # append dimensions to input_shape
AttributeError: 'NoneType' object has no attribute 'shape'
So it seems to be occurring in the skimage.tranform.resize line of code. Please help.
The issue is not with the function
skimage.tranform.resize
but with the reading of the image
normal = cv2.imread(dataset +'Normal//' + Nimages[i])
not sure what are you trying to do there but Nimages[i] won't give you first file in a folder but it will yield first character of a string, in your case /. Then you will send dataset variable + Normal// + / which is basically in your case Normal/// and then you will try to read image on that path, but without doubt the is no image there in which case opencv will return to you None (which is basically nothing). and then you try to resize None with skimage which will fail.
better option would be to read the image directly or in a loop that could look somehow like this:
from os import listdir
from os.path import isfile, join
onlyfiles = [f for f in listdir(Nimages) if isfile(join(Nimages , f))]
for image_path in onlyfiles:
normal = cv2.imread(join(Nimages , image_path))
normal = skimage.transform.resize(normal, (150,150,3))
assuming that there are only images in your mentioned directory.

How to fix 'NoneType' object is not subscriptable' error in while loop

Windows 10
Python 3.7
Anaconda 1.9.7
Spyder 3.3.3
PsychoPy for Python 2.7
I am coding an experiment that needs to present images in a random order for the participant to respond to. I am able to get the images in an array, but to present them one at a time I am using a while loop with a variable that increases by 1 every time it goes through the loop. It is not recognizing the variable as a number and therefore the array cannot call anything.
I've tried not randomizing the variable to see if that is the issue, but it just seems to be that my variable i is not being read as a number
#import packages
import random, os
from psychopy import core, visual, event
from PIL import Image
#setup screen with specs and draw
win = visual.Window([400, 300], monitor="testMonitor")
message = visual.TextStim(win, text="")
message.draw()
win.flip()
core.wait(3.0)
#set image size and populate array with images
stim_size = (0.8, 0.8)
image = [i for i in os.listdir('C:/Users/*/psychopy-tests')
if i.endswith('.bmp')]
#randomize image order
images = random.shuffle(image)
this is where my issue seems to be
i = 0
while i != 29: #there are only 28 images
new = images[i] #this is where the issue is
image_stim = Image.open(new)
stim = visual.ImageStim(win, image_stim, size = (stim_size))
stim.draw()
win.update()
output = []
if event.getKeys(keyList=['space']):
output[i] = 1
if event.getKeys(['escape']):
win.close()
core.quit()
if event.getKeys(keyList=None):
output[i] = 0
core.wait(5.0)
i = i + 1
The random.shuffle shuffles in place and doesn’t return anything i.e., It returns None.
Therefor images is None and not subscriptable.
source

Scikit-learn 0.15.2 - OneVsRestClassifier not works due to predict_proba not available

I am trying to do onevsrest classification like below:
classifier = Pipeline([('vectorizer', CountVectorizer()),('tfidf', TfidfTransformer()),('clf', OneVsRestClassifier(SVC(kernel='rbf')))])
classifier.fit(X_train, Y)
predicted = classifier.predict(X_test)
And I get the error 'predict_proba is not available when probability = false'. I saw that there was a bug reported, the one below:
https://github.com/scikit-learn/scikit-learn/issues/1946
And it was closed as fixed, so I killed scikit-learn from my Windows PC and completely re-downloaded scikit-learn to have version 0.15.2. But I still get this error. Any suggestions? Or I understood this wrong, and I still can't use SVC with OneVSRestClassifier unless I specify probability=true?
UPDATE: just to clarify, I am trying to actually achieve multi-label classification, here is data source:
df = pd.read_csv(fileIn, header = 0, encoding='utf-8-sig')
rows = random.sample(df.index, int(len(df) * 0.9))
work = df.ix[rows]
work_test = df.drop(rows)
X_train = []
y_train = []
X_test = []
y_test = []
for i in work[[i for i in list(work.columns.values) if i.startswith('Change')]].values:
X_train.append(','.join(i.T.tolist()))
X_train = np.array(X_train)
for i in work[[i for i in list(work.columns.values) if i.startswith('Corax')]].values:
y_train.append(list(i))
for i in work_test[[i for i in list(work_test.columns.values) if i.startswith('Change')]].values:
X_test.append(','.join(i.T.tolist()))
X_test = np.array(X_test)
for i in work_test[[i for i in list(work_test.columns.values) if i.startswith('Corax')]].values:
y_test.append(list(i))
lb = preprocessing.MultiLabelBinarizer()
Y = lb.fit_transform(y_train)
And after that I send it to pipeline mentioned earlier
Ok, I did some investigation in code. OneVsRestClassifier tries to call decision_function first and if it fails - it goes for predict_proba function of base classifier (svm.svc in our case).
As far as I see, my X_test is numpy.array of lists of strings. After it undergoes a sequence of transformations specified in pipeline CountVectorizer -> TfidfTransformer it becomes a sparse matrix (by design of these things). As I see currently decision_function is not available for sparse matrices, and there is even an open suggestion on github: https://github.com/scikit-learn/scikit-learn/issues/73
So, to summarize, looks like you can't make a multilabel classification using svm.svc unless you specify probability=True. If you do this you introduce some overhead to the classifier.fit process but it will work.

Fitting The Theoretical Equation To My Data

I am very, very new to python, so please bear with me, and pardon my naivety. I am using Spyder Python 2.7 on my Windows laptop. As the title suggests, I have some data, a theoretical equation, and I am attempting to fit my data, with what I believe is the Chi-squared fit. The theoretical equation I am using is
import math
import numpy as np
import scipy.optimize as optimize
import matplotlib.pylab as plt
import csv
#with open('1.csv', 'r') as datafile:
# datareader = csv.reader(datafile)
# for row in datareader:
# print ', '.join(row)
t_y_data = np.loadtxt('exerciseball.csv', dtype=float, delimiter=',', usecols=(1,4), skiprows = 1)
print(t_y_data)
t = t_y_data[:,0]
y = t_y_data[:,1]
gamma0 = [.1]
sigma = [(0.345366)/2]*(len(t))
#len(sigma)
#print(sigma)
#print(len(sigma))
#sigma is the error in our measurements, which is the radius of the object
# Dragfunction is the theoretical equation of the position as a function of time when the thing falling experiences a drag force
# This is the function we are trying to fit to our data
# t is the independent variable time, m is the mass, and D is the Diameter
#Gamma is the value of which python will vary, until chi-squared is a minimum
def Dragfunction(x, gamma):
print x
g = 9.8
D = 0.345366
m = 0.715
# num = math.sqrt(gamma)*D*g*x
# den = math.sqrt(m*g)
# frac = num/den
# print "frac", frac
return ((m)/(gamma*D**2))*math.log(math.cosh(math.sqrt(gamma/m*g)*D*g*t))
optimize.curve_fit(Dragfunction, t, y, gamma0, sigma)
This is the error message I am getting:
return ((m)/(gamma*D**2))*math.log(math.cosh(math.sqrt(gamma/m*g)*D*g*t))
TypeError: only length-1 arrays can be converted to Python scalars
My professor and I have spent about three or four hours trying to fix this. He helped me work out a lot of the problems, but this we can't seem to resolve.
Could someone please help? If there is any other information you need, please let me know.
Your error message comes from the fact that those math functions only accept a scalar, so to call functions on an array, use the numpy versions:
In [82]: a = np.array([1,2,3])
In [83]: np.sqrt(a)
Out[83]: array([ 1. , 1.41421356, 1.73205081])
In [84]: math.sqrt(a)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
----> 1 math.sqrt(a)
TypeError: only length-1 arrays can be converted to Python scalars
In the process, I happened to spot a mathematical error in your code. Your equation at top says that g is in the bottom of the square root inside the log(cosh()), but you've got it on the top because a/b*c == a*c/b in python, not a/(b*c)
log(cosh(sqrt(gamma/m*g)*D*g*t))
should instead be any one of these:
log(cosh(sqrt(gamma/m/g)*D*g*t))
log(cosh(sqrt(gamma/(m*g))*D*g*t))
log(cosh(sqrt(gamma*g/m)*D*t)) # the simplest, by canceling with the g from outside sqrt
A second error is that in your function definition, you have the parameter named x which you never use, but instead you're using t which at this point is a global variable (from your data), so you won't see an error. You won't see an effect using curve_fit since it will pass your t data to the function anyway, but if you tried to call the Dragfunction on a different data set, it would still give you the results from the t values. Probably you meant this:
def Dragfunction(t, gamma):
print t
...
return ... D*g*t ...
A couple other notes as unsolicited advice, since you said you were new to python:
You can load and "unpack" the t and y variables at once with:
t, y = np.loadtxt('exerciseball.csv', dtype=float, delimiter=',', usecols=(1,4), skiprows = 1, unpack=True)
If your error is constant, then sigma has no effect on curve_fit, as it only affects the relative weighting for the fit, so you really don't need it at all.
Below is my version of your code, with all of the above changes in place.
import numpy as np
from scipy import optimize # simplified syntax
import matplotlib.pyplot as plt # pylab != pyplot
# `unpack` lets you split the columns immediately:
t, y = np.loadtxt('exerciseball.csv', dtype=float, delimiter=',',
usecols=(1, 4), skiprows=1, unpack=True)
gamma0 = .1 # does not need to be a list
def Dragfunction(x, gamma):
g = 9.8
D = 0.345366
m = 0.715
gammaD_m = gamma*D*D/m # combination is used twice, only calculate once for (small) speedup
return np.log(np.cosh(np.sqrt(gammaD_m*g)*t)) / gammaD_m
gamma_best, gamma_var = optimize.curve_fit(Dragfunction, t, y, gamma0)