Only way to use TTA with missy right now is to put her in a test set. I agree predict_array_TTA() would be a nice addition
Interestingly, I retrained the model on resnext50 and now it’s properly classifying Missy as a cat with 99.7% confidence!
Hello @yinterian,
I have a question about passing test_name='test'
AFTER learning the model. It is too late and I must rerun all my jupyter notebook or I can learn my model without this argument and passed it after ? (if yes, how ?). Thank you.
I ran into the same problem in my experiments. @jeremy, since more often that not TTA yields better results, do you think the predict_array
function could be improved to take additional parameters tta=True, n_aug=4
and get away from adding a new func or do you suggest predict_array_TTA
?
Keeping it consistent with predict
seems like a good idea…
Not sure why this error is occuring. Code worked fine before, im stumped!
#0 = capsules
#1 = tablets
trn_tfms, val_tfms = tfms_from_model(arch, sz)
im = val_tfms(PIL.Image.open(test_image))
preds = learn.predict_array(im[None])
np.argmax(preds)
This is the error:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-99-f8c7aacfaae1> in <module>()
2 #1 = tablets
3 trn_tfms, val_tfms = tfms_from_model(arch, sz)
----> 4 im = val_tfms(PIL.Image.open(test_image))
5 preds = learn.predict_array(im[None])
6 np.argmax(preds)
/output/fastai/transforms.py in __call__(self, im, y)
448 if crop_type == CropType.NO: crop_tfm = NoCropXY(sz, tfm_y)
449 self.tfms = tfms + [crop_tfm, normalizer, channel_dim]
--> 450 def __call__(self, im, y=None): return compose(im, y, self.tfms)
451
452
/output/fastai/transforms.py in compose(im, y, fns)
429 def compose(im, y, fns):
430 for fn in fns:
--> 431 im, y =fn(im, y)
432 return im if y is None else (im, y)
433
/output/fastai/transforms.py in __call__(self, x, y)
223 def __call__(self, x, y):
224 self.set_state()
--> 225 x,y = ((self.transform(x),y) if self.tfm_y==TfmType.NO
226 else self.transform(x,y) if self.tfm_y==TfmType.PIXEL
227 else self.transform_coord(x,y))
/output/fastai/transforms.py in transform(self, x, y)
231
232 def transform(self, x, y=None):
--> 233 x = self.do_transform(x)
234 return (x, self.do_transform(y)) if y is not None else x
235
/output/fastai/transforms.py in do_transform(self, x)
312
313 def do_transform(self, x):
--> 314 return scale_min(x, self.sz)
315
316
/output/fastai/transforms.py in scale_min(im, targ)
9 targ (int): target size
10 """
---> 11 r,c,*_ = im.shape
12 ratio = targ/min(r,c)
13 sz = (scale_to(c, ratio, targ), scale_to(r, ratio, targ))
AttributeError: 'JpegImageFile' object has no attribute 'shape'
I believe needs to be im = val_tfms(np.array(PIL.Image.open(test_image)))
, to convert the PIL Image to Numpy array before passing to transforms functiion.
I have the following to get my prediction for a single image. How can I get the reference to the classification for the predictions?
Here are a few of the possible classifications
Are the classifications still available through learn.data.classes in your code?
Yes I do. When I use argmax, I can get the most likely class out of there, but not sure how to get all the non-zero predicted values.
Also, I am now seeing this error. I am using the same values as my successful runs, but about 10x the amount of data. There are about 200k in this dataset so finding an error in the CSV is proving tough. ny thoughts on what the issue might be here?
~/fastai/courses/dl1/fastai/dataset.py in <listcomp>(.0)
64 skip = 1 if skip_header else 0
65 csv_lines = [o.strip().split(',') for o in open(fn)][skip:]
---> 66 fnames = [fname for fname, _ in csv_lines]
67 csv_labels = {a:b.split(' ') for a,b in csv_lines}
68 all_labels = sorted(list(set(p for o in csv_labels.values() for p in o)))
ValueError: too many values to unpack (expected 2)
(fastai) ubuntu@ip-172-31-34-254:~/data/shopstyle$ wc -l prod_train.csv
198869 prod_train.csv
(fastai) ubuntu@ip-172-31-34-254:~/data/shopstyle$ ls train/ | wc -l
198869
This happened to be a single line with a comma in the tags…something to add to my generator.
Still looking for info on how to grab all the classes that have a non-zero prediction for an image.
Also, does anyone have a code example of service prediction results via an endpoint? That is my use case here.
Birch
One more question related to this.
I have all my images in the ‘train’ folder. my CSV has the image id and the tags separated by space, all that is good. What should be in the test directory? In the planet data directory, there are almost as many in test as there are in train, and I am not seeing a test csv. Is the fastai library automatically spitting the training/test set for me? If so, why did it complain that the test dir was empty before I added stuff to it?
Ah. In that case, wouldn’t you just use zip(* to transpose the columns out, or just iterate through the rows and columns? (I guess there’s a more elegant solution …)
I haven’t tried to connect all this to a service, would be interested to hear how you get on with it
I wouldn’t have thought that the test set would be mandatory, what’s the message you’re getting?
Ty @pete.condon. We will be doing the service part as part of an upcoming hackathon next week, I will report back.
I’ll give the zip a try. When I am done with this training run, I will do it again with no test data and share the error.
Birch
I am running the following code, and get an error while trying to pass the data to the predict_array function. Is this the proper code to do this?
from fastai.conv_learner import *
from planet import f2
PATH = 'data/shopstyle/'
metrics=[f2]
f_model = resnet34
def get_data(sz):
tfms = tfms_from_model(f_model, sz, aug_tfms=transforms_side_on, max_zoom=1.05)
return ImageClassifierData.from_csv(PATH, 'train', label_csv, tfms=tfms, suffix='.jpg', val_idxs=val_idxs, test_name='test')
def print_list(list_or_iterator):
return "[" + ", ".join( str(x) for x in list_or_iterator) + "]"
label_csv = f'{PATH}prod_train.csv'
n = len(list(open(label_csv)))-1
val_idxs = get_cv_idxs(n)
sz = 64
data = get_data(sz)
print("Loading model...")
learn = ConvLearner.pretrained(f_model, data, metrics=metrics)
learn.load(f'{sz}')
#learn.load("tmp")
print("Predicting...")
learn.precompute=False
trn_tfms, val_tfrms = tfms_from_model(f_model, sz)
#im = val_tfrms(open_image(f'{PATH}valid/4500132.jpg'))
im = val_tfrms(np.array(PIL.Image.open(f'{PATH}valid/4500132.jpg')))
preds = learn.predict_array(im[None])
p=list(zip(data.classes, preds))
print("predictions = " + print_list(p))
Getting this error
Traceback (most recent call last):
File "predict.py", line 34, in <module>
preds = learn.predict_array(im[None])
File "/home/ubuntu/fastai/courses/dl1/fastai/learner.py", line 266, in predict_array
def predict_array(self, arr): return to_np(self.model(V(T(arr).cuda())))
File "/home/ubuntu/src/anaconda3/envs/fastai/lib/python3.6/site-packages/torch/nn/modules/module.py", line 325, in __call__
result = self.forward(*input, **kwargs)
File "/home/ubuntu/src/anaconda3/envs/fastai/lib/python3.6/site-packages/torch/nn/modules/container.py", line 67, in forward
input = module(input)
File "/home/ubuntu/src/anaconda3/envs/fastai/lib/python3.6/site-packages/torch/nn/modules/module.py", line 325, in __call__
result = self.forward(*input, **kwargs)
File "/home/ubuntu/src/anaconda3/envs/fastai/lib/python3.6/site-packages/torch/nn/modules/batchnorm.py", line 37, in forward
self.training, self.momentum, self.eps)
File "/home/ubuntu/src/anaconda3/envs/fastai/lib/python3.6/site-packages/torch/nn/functional.py", line 1011, in batch_norm
raise ValueError('Expected more than 1 value per channel when training, got input size {}'.format(size))
ValueError: Expected more than 1 value per channel when training, got input size [1, 1024]
Why are you passing None?
I don’t know this , looks great…
Can you explain?
I have been cobbling instructions from various posts. Not convinced it is right. Although I thought I had it working like this yesterday.
Without the None, I get this:
ValueError: Expected 4D tensor as input, got 3D tensor instead.