01: Intro

Setup

Import fastbook and patch IPython for VS Code

from fastbook import *
from IPython.display import clear_output, DisplayHandle
def update_patch(self, obj):
    clear_output(wait=True)
    self.display(obj)
DisplayHandle.update = update_patch

Set up a path to store the images

data_path = Path('data')/'01'
data_path.mkdir(parents=True,exist_ok=True)

Preview Images

Set up a function to try out different keywords and see how they look

def preview(keyword: string):
    path = data_path / f"{keyword}.jpg"
    download_url(search_images_ddg(keyword, max_images=1)[0], path)
    return Image.open(path).to_thumb(256, 256)
preview("rugby")
100.75% [98304/97571 00:02<00:00]

png

preview("nfl")
100.88% [245760/243610 00:00<00:00]

png

preview("soccer")
107.98% [81920/75868 00:00<00:00]

png

preview("afl")
100.18% [139264/139007 00:00<00:00]

png

Download Dataset

searches = "rugby","afl","nfl","soccer"
dataset_path = data_path/"datasets"
if not (dataset_path).exists():
    for o in searches:
        dest = (dataset_path/o)
        dest.mkdir(parents=True,exist_ok=True)
        results = search_images_ddg(f"{o} game")
        download_images(dest, urls=results[:200])
        resize_images(dest, max_size=400, dest=dest)

Build Data Block

failed = verify_images(get_image_files(dataset_path))
failed.map(Path.unlink)
(#17) [None,None,None,None,None,None,None,None,None,None...]
dls = DataBlock(
    blocks=(ImageBlock, CategoryBlock),
    get_items=get_image_files,
    splitter=RandomSplitter(valid_pct=0.2, seed=42),
    get_y=parent_label,
    item_tfms=[Resize(192, method='squish')]
).dataloaders(dataset_path)

dls.show_batch(max_n=6)

png

Train Model

learn = vision_learner(dls, resnet18, metrics=error_rate)
learn.fine_tune(30)
epochtrain_lossvalid_losserror_ratetime
01.3312761.2825370.39823000:00
11.0730421.1084790.36283200:00
20.8737940.9987660.37168100:00
30.7181800.9871330.38938100:00
40.5832151.0169070.36283200:00
50.4764261.0675160.34513300:00
60.3834981.1373390.36283200:00
70.3143191.2003280.35398200:00
80.2617721.2086680.33628300:00
90.2189761.1755290.32743400:00
100.1849301.1392890.30088500:00
110.1566221.1091120.29203500:00
120.1335401.1125550.29203500:00
130.1141731.1267500.30088500:00
140.0982291.1369300.30088500:00
150.0849031.1402840.31858400:00
160.0746241.1483020.32743400:00
170.0646031.1673050.31858400:00
180.0559111.1796640.31858400:00
190.0484611.1911160.32743400:00
200.0421651.1781580.33628300:00
210.0369021.1854830.32743400:00
220.0323481.1708210.33628300:00
230.0286131.1686870.33628300:00
240.0253991.1679780.34513300:00
250.0223981.1666660.34513300:00
260.0197211.1733680.34513300:00
270.0175801.1743130.34513300:00
280.0155511.1728760.34513300:00
290.0136631.1716740.34513300:00

Test Model

learn.show_results()

png

sport,_,probs = learn.predict(PILImage.create(data_path/'nfl.jpg'))
print(f"this is {sport}")
print("\n--probabilities--")
for i, o in enumerate(dls.vocab):
    print(f"{o}: {probs[i]:.4f}")
this is nfl

--probabilities--
afl: 0.0008
nfl: 0.9891
rugby: 0.0013
soccer: 0.0089