The bears DataBlock example, explained

The bears DataBlock example, explained

These are some quick notes on the DataBlock API which I found a bit confusing at first.

Here is the example taken from the end Lesson 2 (Part I v4 2020):

bears = DataBlock(
   blocks = (ImageBlock, CategoryBlock),
   get_items = get_image_files,
   splitter = RandomSplitter(valid_pct=0.3, seed=42),
   get_y = parent_label,
   item_tfms = Resize(128))

So, let’s take this apart bit by bit.

  • The blocks argument is used to specify the types of input and output of your data. In this example we are trying to classify images into three categories of bears (grizzly, black, teddy), so the input is ImageBlock and the output is CategoryBlock.

  • The get_items argument is used to specify a function which will return the datapoints. Here we use get_image_files, which recurses through directories and returns all files with an image extension (at the time of writing, the list of extensions considered as an image is quite large: ‘.png’, ‘.ppm’, ‘.ico’, ‘.tif’, ‘.rgb’, ‘.xwd’, ‘.jpg’, ‘.pnm’, ‘.ras’, ‘.xbm’, ‘.svg’, ‘.tiff’, ‘.pbm’, ‘.xpm’, ‘.ief’, ‘.gif’, ‘.pgm’, ‘.bmp’, ‘.jpe’, ‘.jpeg’).

  • The get_y argument is also a function, indicating how to extract y (in our case the category of bear) from an item obtained by get_item. In this case, we tell it to use the function parent_label, which gets the name of the parent folder of the item. So for a file bears/grizzly/file1.jpg if will identify the folder grizzly as the parent and hence return 'grizzly'.

  • The splitter argument is used to specify how to split the data into training and validation sets. Here we use a RandomSplitter which just assigns entries randomly. Its parameter valid_pct=0.3 instructs DataBlock to put 30% of the items in the validation set (the seed argument allows us to control the randomness, so that we get the same sets every time we run the function).

  • The item_tfms argument is used to specify which transforms need to be applied to each item. Here we use Resize(128), which resizes each image to 128x128 pixels by the cropping method (another method can be specified with the method argument).


  1. We could also have specified a get_x argument, a function to extract the x from each item. However in this case the x is the image itself, so we don’t need to extract anything.
  2. The most confusing to me was the line
    blocks = (ImageBlock, CategoryBlock)
    because in my intuition these are not really “blocks” but “types”. My brain would be much happier if this was written as
    types = (ImageType, CategoryType)
    but I will have to get used to it :slight_smile:
  3. The constructed DataBlock can be used to produce DataLoaders, as follows:
    dls = bears.dataloaders(path)
    Note that here we are passing a path, whereas we didn’t specify a path when creating the bears object. For example, the get_image_files function takes a path argument, but we simply specified the function without that argument.

Please let me know if something is unclear (or incorrect), and if you found this useful!



IMO, this suffers from what most API guides suffer from, it assumes that the reader understands much more than he or she does. For example in 02_production.ipynb, I don’t know what ImageBlock is, so I read Jeremy’s description in the notebook that describes it as the independent variable and will be the images that predictions will be made from, but it isn’t defined in the notebook.

So I add print(ImageBlock), run it and <function ImageBlock at 0x00000217F7383488> is returned. Therefore, I assume that ImageBlock IS defined somewhere. So, I search for it and and find some information at Data block:

You can create a [`DataBlock`]( by passing functions:
mnist = DataBlock(blocks = (ImageBlock(cls=PILImageBW)...

So, I search for ImageBlocks on and get Vision data, where the following information is provided:

A [`TransformBlock`]( for images of `cls`

So, on the Data blocks page, ImageBlock is shown as a function that has parameters passed to it, but this information is not expanded on the Vision data page and the link returns you back to the Data blocks page for TransformsBlocks for vision.

I would like API guides to provide enough information for me to figure this out on my own. I’m a self-taught programmer who was educated as an electrical engineer, so maybe it’s just me, I don’t look at this information in the right way. Right now, I’m forced to just use the notebook’s code because I can’t write it on my own!

Hi @msp

How can I use my existing (Train/Test/Val) folders instead of random spilt?
like (FASTAI-V1) ImageDataBunch.from_folder(path, train='train',valid='test')


Hi, you need to change RandomSplitter() to GrandparentSplitter(train_name = 'train', valid_name = 'val')

1 Like

Thanks :slight_smile:
It works for me