Fastai import best practice

I’d like to ask the community on what the best practice is for importing various fastai libraries? In most of the courses, I see that we import everything with a wildcard without aliases (ie from fastai.vision.all import *).

I know this is personal preference, but this makes it less obvious where certain methods/classes come from while learning. Is there a specific reason why courses choose this kind of imports instead of doing import fastai.vision.all as fv? Happy to read any further material on this.

2 Likes

In the first chapter of the fastai book, Jeremy states,

A lot of Python coders recommend avoiding importing a whole library like this (using the import * syntax), because in large software projects it can cause problems. However, for interactive work such as in a Jupyter notebook, it works great. The fastai library is specially designed to support this kind of interactive use, and it will only import the necessary pieces into your environment.

Hope that helps.

1 Like

I prefer doing imports such as the ones shown in my course here: Lesson 2 - Image Classification Models from Scratch | walkwithfastai

Such as:

from fastai.vision.all import *

Is replaced with:

from torch import nn

from fastai.callback.hook import summary
from fastai.callback.schedule import fit_one_cycle, lr_find 
from fastai.callback.progress import ProgressCallback

from fastai.data.core import Datasets, DataLoaders, show_at
from fastai.data.external import untar_data, URLs
from fastai.data.transforms import Categorize, GrandparentSplitter, parent_label, ToTensor, IntToFloatTensor, Normalize

from fastai.layers import Flatten
from fastai.learner import Learner

from fastai.metrics import accuracy, CrossEntropyLossFlat

from fastai.vision.augment import CropPad, RandomCrop, PadMode
from fastai.vision.core import PILImageBW
from fastai.vision.utils import get_image_files

Though I usually do this only after I’m all done hacking away and I push my open source code, for readability

1 Like

I have found the practice of import * the single most frustrating thing in the book and course. This is compounded by the fact that many Fastai objects seem to be thin wrappers around other things. For example, in chapter 4 we have ds = L(enumerate(string.ascii_lowercase)). What is L()?, where does it come from? Turns out L is a fancy version of python’s list and it’s specific to Fastai. list(enumerate(string.ascii_lowercase)) works just as well for the above code, why didn’t we just use that? There’s no explanation in the text why they choose this. Later we see L(learn.recorder.values).itemgot(2). What is itemgot()? Am I learning something I will be able to apply in other python frameworks here, or is this specific to fastai? Turns out this is fastai, but there’s no way to know by looking. [item[2] for item in learn.recorder.values] works just as well here and is much more useful thing to know how to do since it applies to all python. I am all for convenience methods and classes, but they add a layer of abstraction that is very confusing when learning basics.

It’s also frustrating when objects in Fastai and PyTorch have the same name. When I see DataLoader I’m not sure if what I am learning applies only to fastai.data.load.DataLoader or if it also applies to the native PyTorch DataLoader. Since the names are not imported using best practices, the only way to figure out is to break out of context and investigate. I’m honestly at the point where I’m just going to find a PyTorch book and forget about Fastai. This saddens me because I really agree with most of the philosophy of this practical approach to learning.

1 Like

This is disappointing. I really like the general philosophy as well, but when the first thing I read is import * and the justification is “we are working interactively in Jupyter” I must admit I’m a bit taken aback. Namespace pollution is something I just intrinsically recoil from (PEP8 etc etc)

It is definitely possible to buy into the philosophy of fastai (deep learning for everyone) without pushing such code smells (sorry I don’t mean to be overly negative it is a great suite of ideas overall). I am currently trying to decide what resources to use to teach deep learning to newcomers, and such stuff does concern me when it comes to student comprehension. One option I’m considering is forking and making imports explicit like @muellerzr has done.

Again, I am not trying to be too negative in here, but I do worry when this is the first thing mature coders see in the book/course it will be a big turn off because of the justifiable concerns with wildcard imports. I suppose if it was written for non-programmers or Matlab converts, or if there is a clear pedagogical benefit, or space is saved in the print version, there could be some benefit that outweighs the cost. But maybe in the digital version do the explicit imports?

Dive into Deep Learning (D2L) does import d2l and then d2l.method(), I think something like that could be nice with namespace handling for fastai. I wonder if the maintainers here would be adamantly opposed. :grimacing: I hate to focus on superficial things but I think this would multiply entrance from more experienced Python users because import * will evoke such a knee-jerk reaction we are trained from birth to see it as a code smell :blush:

Edit: It was discussed as an issue here: Use of import * in the fastai library · Issue #125 · fastai/fastai · GitHub

It’s from 2018. There is some stuff about how wildcards are good for data science or something. It is not compelling. Jeremy Howard replied with some stuff about how computers should be parsing namespaces, not humans. At any rate, heels seem to have been dug in with this code smell at fastai, so I guess rule number 10: don’t fight the system. :grinning: