A walk with fastai2 - Vision - Study Group and Online Lectures Megathread

Understood, Thank you :slight_smile:

Hiii, I got this error for the first time. What’s missing?

Edit: When I tried without using fp_16() it’s working but takes a lottt of time.
How to use fp_16() without getting this error?
@muellerzr

If you read the first error you’re not training with a GPU.

“Mixed Precision requires a GPU. Remove call to to_fp16”

1 Like

Yeah… I changed the runtime to GPU and it works fine.
Thanks

Hi, I tried to create the dataloaders using Datablock API for the MNIST dataset and i faced this error.

Also I’m not able to do a .show_batch() because of this error.
What’s wrong here?

Thanks,

You’re using the DataBlock API. You shouldn’t add in anything related to type transforms into the item transforms as you’re doing here. Instead of PILImageBW.create you should have it in your block like so:

ImageBlock(cls=PILImageBW)

1 Like

Yeahh works perfect now!
Also instead of converting them to black and white(2 channels) can we have with as they are and classify them like we do a pets classification? Will there be any deterioration ?

I think a good way to visualize the differences is examining the pipeline:

Type Transforms

Type Transforms are there to first grab any inputs or output we’re wanting. IE take a file on my system and turn it into a Pillow image (ImageBlock) or dictate what our y’s will roughly be (such as CategoryBlock for classification, RegressionBlock for regression).

Item Transforms

Take your newly made inputs from the type transforms and make them ready for being collated into batches. This includes making them all the same size and adjusting any y values initially (such as with points), such as Resize

Batch Transforms

Any general augmentation we can run efficiently on the GPU after they’re in batches, including augmentation, such as Normalize and aug_transforms Does this help @AjayStark?

1 Like

Well they are two channel images, so that’s already done. We can make them three channel by normalizing from imagenet or adding in a third channel of some form, but generally you should use 2 channel for BW images (as you’re not converting, you’re keeping it the same), but others may have thoughts on this too it’s fairly controversial :slight_smile:

Hi @muellerzr!

I’ve been getting some errors when playing around with show_results() for a custom type transform. I see some code in your 06_Scalar_Regression.ipynb notebook related to the same issue I’ve had:

AttributeError: 'Tensor' object has no attribute 'show' 

Did you cover this notebook in your videos? In my case I’m encountering an issue trying to display a titled image while regressing multiple floats.

Yeahh that was great.
Thanks for detailed explanation. :slight_smile:

Hi @jwuphysics! If you look a bit further you can see just how I went about doing this :wink: I wound up making my own transform that has an encodes and decodes function. The decodes is what’s being shown and so any time we show our transforms will go backwards in our pipeline until we see this decodes function. In our case we built a TitledNumberShort which inherits ShowTitle (a fastai2 function for showing an image with a title`)

From there we adapted the show function to display our title as the number (self is our label here). And then we siply add this to our get_y :slight_smile:

Code I’m talking about:

class TitledNumberShort(Int, ShowTitle):
    _show_args = {'label': 'text'}
    def show(self, ctx=None, **kwargs):
        "Show self"
        return show_title(f'{self:.2f}', ctx=ctx, **merge(self._show_args, kwargs))

class ToIntTensor(Transform):
    "Transform to int tensor"
    order = 10 #Need to run after PIL transforms on the GPU
    _show_args = {'label': 'text'}
    def __init__(self, split_idx=None, as_item=True):
        super().__init__(split_idx=split_idx,as_item=as_item)

    def encodes(self, o): return o.int()
    def decodes(self, o): return TitledFloatShort(o)


block = DataBlock(blocks=(ImageBlock, RegressionBlock()),
                  get_items=get_image_files,
                  splitter=RandomSplitter(),
                  get_y=[parent_label, to_num, ToIntTensor], <- Here
                  item_tfms=Resize(460, method='squish'),
                  batch_tfms=[Flip(), Rotate(), Zoom(), Warp()])

Does this help? :slight_smile:

I didn’t cover this notebook much in the videos IIRC because it was made by someone on the forums :slight_smile:

1 Like

Thanks, yep that was the section I was investigating! It has been helpful, though I’m still a bit unsure how to generalize everything. In my case I’m using ImageDataLoaders.from_df() as such:

dls = ImageDataLoaders.from_df(
    df,
    path=PATH,
    folder=image_folder,
    suff='.jpg',
    fn_col=fn_col,
    label_col=label_cols,
    y_block=RegressionBlock,
    bs=16,
    item_tfms=item_tfms,
    batch_tfms=batch_tfms,
)

and I can’t figure out where the ToIntTensor should go.

Well, first you may have better luck using the DataBlock rather than the ImageDataLoaders :wink: because here we’re getting away from what can be preloaded in. We’re adjusting the get_y and from_df preloads them in. You can see this in this line:

dblock = DataBlock(blocks=(ImageBlock, y_block),
                           get_x=ColReader(fn_col, pref=pref, suff=suff),
                           get_y=ColReader(label_col, label_delim=label_delim),
                           splitter=splitter,
                           item_tfms=item_tfms,
                           batch_tfms=batch_tfms)

We can’t modify the get_y (which we need to do), so you should use the DataBlock instead

(for context this is from this line, which you can see any XDataLoaders uses the DataBlock API:)

1 Like

Yeah, after writing out my comment I came to the same conclusion! Thanks :slight_smile:

As a nice update, I wanted to mention that I was able to display 7 floats across two rows using the following:


class TitledTensor(Tensor, ShowTitle):
    _show_args = {'label': 'text'}
    def show(title, ctx=None, **kwargs):
        "Show self"
        return show_title(
            ' '.join(f'{s:.2f}' for s in title[:4]) + '\n' + ' '.join(f'{s:.2f}' for s in title[4:]), 
            ctx=ctx, 
            **merge(title._show_args, kwargs)
        )
    
class ToFloatTensor(Transform):
    "Transform to float tensor"
    order = 10 #Need to run after PIL transforms on the GPU
    _show_args = {'label': 'text'}
    def __init__(self, split_idx=None):
        super().__init__(split_idx=split_idx)

    def encodes(self, o): return o.float()
    def decodes(self, o): return TitledTensor(o)

and then constructed the DataBlock using:

dblock = DataBlock(
    blocks=(ImageBlock, RegressionBlock),
    get_x=ColReader(fn_col, pref=path_prefix, suff='.jpg'),
    get_y=Pipeline([ColReader(label_cols, label_delim=None), ToFloatTensor]), # don't forget the `Pipeline` constructor!
    splitter=RandomSplitter(0.2),
    item_tfms=item_tfms,
    batch_tfms=batch_tfms,
)
2 Likes

@muellerzr
How to open a tar.gz(uploaded in github) file in colab?
I tried with untar_data(URL) but it says:It’s not a gzip file
I read that untar_data() by default adds an extension so I tried removing the extension, this is the error i get:

After I cloned the repo and untar again, it says: not a gzip file

@AjayStark You need to copy the link of the github download button!

Here you have the correct link:

https://github.com/spinaki/sports-shot-classifier/raw/master/data/tennis/tennis.tar.gz

1 Like

Wow! That surprisingly did the job!
Thanks @WaterKnight

1 Like

If you don’t press the download button, you get downloaded the website.

So, you need to copy the link of the download button!

You are welcome @AjayStark

1 Like

Also, when I run this line for the first time i get the same error, again if I copy the link from the download button it works fine,weird.