{ "cells": [ { "cell_type": "markdown", "metadata": { "colab_type": "text", "id": "view-in-github" }, "source": [ "\"Open" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "mZ6kD4-AtQOw" }, "outputs": [], "source": [ "%%capture\n", "!mkdir ../content/input/computer-vision-for-the-humanities-ph/ads_data/ads_data/ -p\n", "!wget https://zenodo.org/record/5838410/files/ads_upsampled.csv?download=1 -O ../content/input/computer-vision-for-the-humanities-ph/ads_data/ads_data/ads_upsampled.csv\n", "!mkdir ../content/input/computer-vision-for-the-humanities-ph/ads_data/ads_data/images/ -p\n", "!wget -O images.zip https://zenodo.org/record/5838410/files/images.zip?download=1\n", "!unzip images.zip -d ../content/input/computer-vision-for-the-humanities-ph/ads_data/ads_data/images/\n", "!mkdir ../content/input/computer-vision-for-the-humanities-ph/photos_multi/photos_multi/ -p\n", "!wget https://zenodo.org/record/4487141/files/multi_label.csv?download=1 -O ../content/input/computer-vision-for-the-humanities-ph/photos_multi/photos_multi/multi_label.csv\n", "!wget -O photo_images.zip https://zenodo.org/record/4487141/files/images.zip?download=1\n", "!mkdir ../content/input/computer-vision-for-the-humanities-ph/photos_multi/photos_multi/photo_images -p\n", "!unzip photo_images -d ../content/input/computer-vision-for-the-humanities-ph/photos_multi/photos_multi/photo_images" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "DBpY2b6dutRK" }, "outputs": [], "source": [ "!pip install fastai==2.7.9\n", "!pip install fastprogress==1.0.3" ] }, { "cell_type": "markdown", "metadata": { "id": "L9UuXbPZtGlW" }, "source": [ "# Computer Vision for the Humanities: an Introduction to Deep Learning for Image Classification\n", "\n", "This notebook contains the code you'll need to run in both Part 1 and Part 2 of this lesson." ] }, { "cell_type": "markdown", "metadata": { "id": "3AwPRMvttGlY" }, "source": [ "# Part 1" ] }, { "cell_type": "markdown", "metadata": { "id": "UbyxOsmVtGlb" }, "source": [ "## Creating an Image Classifier in fastai" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T11:59:49.084274Z", "iopub.status.busy": "2022-04-11T11:59:49.083953Z", "iopub.status.idle": "2022-04-11T11:59:52.004748Z", "shell.execute_reply": "2022-04-11T11:59:52.004023Z", "shell.execute_reply.started": "2022-04-11T11:59:49.084227Z" }, "id": "JHjSMawrtGlc", "trusted": true }, "outputs": [], "source": [ "from fastai.vision.all import *" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T11:59:52.720702Z", "iopub.status.busy": "2022-04-11T11:59:52.720242Z", "iopub.status.idle": "2022-04-11T11:59:52.729297Z", "shell.execute_reply": "2022-04-11T11:59:52.727987Z", "shell.execute_reply.started": "2022-04-11T11:59:52.720663Z" }, "id": "sDYg4CDJtGle", "trusted": true }, "outputs": [], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "plt.style.use('seaborn-v0_8')" ] }, { "cell_type": "markdown", "metadata": { "id": "3JVVHm2ZtGlf" }, "source": [ "### Loading the Data\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T11:59:55.195772Z", "iopub.status.busy": "2022-04-11T11:59:55.195514Z", "iopub.status.idle": "2022-04-11T11:59:58.285119Z", "shell.execute_reply": "2022-04-11T11:59:58.284354Z", "shell.execute_reply.started": "2022-04-11T11:59:55.195743Z" }, "id": "lZ6UzCLItGlg", "trusted": true }, "outputs": [], "source": [ "ad_data = ImageDataLoaders.from_csv(\n", " path=\"../content/input/computer-vision-for-the-humanities-ph/ads_data/ads_data/\", # root path to csv file and image directory\n", " csv_fname=\"ads_upsampled.csv\", # the name of our csv file\n", " folder=\"images/\", # the folder where our images are stored\n", " fn_col=\"file\", # the file column in our csv\n", " label_col=\"label\", # the label column in our csv\n", " item_tfms=Resize(224, ResizeMethod.Squish), # resize imagesby squishing so they are 224x224 pixels\n", " seed=42, # set a fixed seed to make results more reproducible\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-05T14:06:03.336903Z", "iopub.status.busy": "2022-04-05T14:06:03.336292Z", "iopub.status.idle": "2022-04-05T14:06:04.846184Z", "shell.execute_reply": "2022-04-05T14:06:04.845404Z", "shell.execute_reply.started": "2022-04-05T14:06:03.33686Z" }, "id": "Goj63ha-tGli", "trusted": true }, "outputs": [], "source": [ "ad_data.show_batch()" ] }, { "cell_type": "markdown", "metadata": { "id": "4ddde34WtGlj" }, "source": [ "### Creating the Model\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-05T14:06:07.790766Z", "iopub.status.busy": "2022-04-05T14:06:07.790508Z", "iopub.status.idle": "2022-04-05T14:06:08.226152Z", "shell.execute_reply": "2022-04-05T14:06:08.225364Z", "shell.execute_reply.started": "2022-04-05T14:06:07.790738Z" }, "id": "FuJpCuabtGlk", "trusted": true }, "outputs": [], "source": [ "learn = vision_learner(\n", " ad_data, # the data the model will be trained on\n", " resnet18, # the type of model we want to use\n", " metrics=accuracy, # the metrics to track\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "vZXVOKlwtGll" }, "source": [ "### Training the Model" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-05T14:06:11.885687Z", "iopub.status.busy": "2022-04-05T14:06:11.884992Z", "iopub.status.idle": "2022-04-05T14:07:00.069511Z", "shell.execute_reply": "2022-04-05T14:07:00.06871Z", "shell.execute_reply.started": "2022-04-05T14:06:11.885649Z" }, "id": "kAQ9LeUwtGll", "trusted": true }, "outputs": [], "source": [ "learn.fine_tune(5)" ] }, { "cell_type": "markdown", "metadata": { "id": "oz4Vf88PtGln" }, "source": [ "## Appendix: A Non-Scientific Experiment Assessing Transfer Learning" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-05T14:07:00.07182Z", "iopub.status.busy": "2022-04-05T14:07:00.071567Z", "iopub.status.idle": "2022-04-05T14:07:00.280735Z", "shell.execute_reply": "2022-04-05T14:07:00.280003Z", "shell.execute_reply.started": "2022-04-05T14:07:00.071784Z" }, "id": "sB24zj-QtGln", "trusted": true }, "outputs": [], "source": [ "learn_random_start = vision_learner(ad_data, resnet18, metrics=accuracy, pretrained=False)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-05T14:07:00.282596Z", "iopub.status.busy": "2022-04-05T14:07:00.282289Z", "iopub.status.idle": "2022-04-05T14:07:42.701202Z", "shell.execute_reply": "2022-04-05T14:07:42.700238Z", "shell.execute_reply.started": "2022-04-05T14:07:00.28256Z" }, "id": "Os18su93tGlp", "trusted": true }, "outputs": [], "source": [ "learn_random_start.fine_tune(5)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-05T14:07:42.706639Z", "iopub.status.busy": "2022-04-05T14:07:42.706367Z", "iopub.status.idle": "2022-04-05T14:07:44.422563Z", "shell.execute_reply": "2022-04-05T14:07:44.421748Z", "shell.execute_reply.started": "2022-04-05T14:07:42.706602Z" }, "id": "_kQejerNtGlp", "trusted": true }, "outputs": [], "source": [ "learn.validate()" ] }, { "cell_type": "markdown", "metadata": { "id": "juNRu6KHtGlp" }, "source": [ "# Part 2\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "46-BOYAdtGls" }, "source": [ "## Looking More Closely at the Data" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T11:42:02.363426Z", "iopub.status.busy": "2022-04-11T11:42:02.363139Z", "iopub.status.idle": "2022-04-11T11:42:02.367617Z", "shell.execute_reply": "2022-04-11T11:42:02.366599Z", "shell.execute_reply.started": "2022-04-11T11:42:02.363394Z" }, "id": "C_4zpaFmtGls", "trusted": true }, "outputs": [], "source": [ "import pandas as pd" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T11:42:05.786948Z", "iopub.status.busy": "2022-04-11T11:42:05.786625Z", "iopub.status.idle": "2022-04-11T11:42:05.798159Z", "shell.execute_reply": "2022-04-11T11:42:05.797459Z", "shell.execute_reply.started": "2022-04-11T11:42:05.786911Z" }, "id": "2mTQOjLmtGlt", "trusted": true }, "outputs": [], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "plt.style.use('seaborn-v0_8')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T11:42:05.933052Z", "iopub.status.busy": "2022-04-11T11:42:05.932808Z", "iopub.status.idle": "2022-04-11T11:42:05.974127Z", "shell.execute_reply": "2022-04-11T11:42:05.973460Z", "shell.execute_reply.started": "2022-04-11T11:42:05.933024Z" }, "id": "4b3H22KBtGlt", "trusted": true }, "outputs": [], "source": [ "df = pd.read_csv('../content/input/computer-vision-for-the-humanities-ph/photos_multi/photos_multi/multi_label.csv', na_filter=False)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T11:42:15.588133Z", "iopub.status.busy": "2022-04-11T11:42:15.587703Z", "iopub.status.idle": "2022-04-11T11:42:15.607841Z", "shell.execute_reply": "2022-04-11T11:42:15.607190Z", "shell.execute_reply.started": "2022-04-11T11:42:15.588094Z" }, "id": "H1gm4_F9tGlt", "trusted": true }, "outputs": [], "source": [ "df" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T11:44:00.933710Z", "iopub.status.busy": "2022-04-11T11:44:00.933419Z", "iopub.status.idle": "2022-04-11T11:44:00.945885Z", "shell.execute_reply": "2022-04-11T11:44:00.945254Z", "shell.execute_reply.started": "2022-04-11T11:44:00.933681Z" }, "id": "t1s132SNtGlv", "trusted": true }, "outputs": [], "source": [ "df['label'].value_counts()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T11:44:27.829749Z", "iopub.status.busy": "2022-04-11T11:44:27.829466Z", "iopub.status.idle": "2022-04-11T11:44:27.837343Z", "shell.execute_reply": "2022-04-11T11:44:27.836475Z", "shell.execute_reply.started": "2022-04-11T11:44:27.829717Z" }, "id": "lEW4ECDxtGlw", "trusted": true }, "outputs": [], "source": [ "# create a variable lables to store the list\n", "labels = df['label'].to_list()\n", "# take a slice of this list to display\n", "labels[:6]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T11:45:15.974114Z", "iopub.status.busy": "2022-04-11T11:45:15.973822Z", "iopub.status.idle": "2022-04-11T11:45:15.979020Z", "shell.execute_reply": "2022-04-11T11:45:15.978258Z", "shell.execute_reply.started": "2022-04-11T11:45:15.974082Z" }, "id": "friAb3vetGlw", "trusted": true }, "outputs": [], "source": [ "# for each label in the list split on \"|\"\n", "split_labels = [label.split(\"|\") for label in labels]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T11:45:34.901684Z", "iopub.status.busy": "2022-04-11T11:45:34.901094Z", "iopub.status.idle": "2022-04-11T11:45:34.907259Z", "shell.execute_reply": "2022-04-11T11:45:34.906089Z", "shell.execute_reply.started": "2022-04-11T11:45:34.901641Z" }, "id": "QJ5au4ZRtGlx", "trusted": true }, "outputs": [], "source": [ "split_labels[:4]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T11:46:06.263591Z", "iopub.status.busy": "2022-04-11T11:46:06.263127Z", "iopub.status.idle": "2022-04-11T11:46:06.269926Z", "shell.execute_reply": "2022-04-11T11:46:06.269212Z", "shell.execute_reply.started": "2022-04-11T11:46:06.263555Z" }, "id": "J-OH52DPtGlx", "trusted": true }, "outputs": [], "source": [ "labels = [label for sublist in split_labels for label in sublist]\n", "labels[:4]" ] }, { "cell_type": "markdown", "metadata": { "id": "FGYCm8b0tGly" }, "source": [ "### Counting the Labels\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T11:53:48.446200Z", "iopub.status.busy": "2022-04-11T11:53:48.445922Z", "iopub.status.idle": "2022-04-11T11:53:48.450742Z", "shell.execute_reply": "2022-04-11T11:53:48.449421Z", "shell.execute_reply.started": "2022-04-11T11:53:48.446165Z" }, "id": "uojeAb0FtGly", "trusted": true }, "outputs": [], "source": [ "from collections import Counter\n", "label_freqs = Counter(labels)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T11:54:02.776756Z", "iopub.status.busy": "2022-04-11T11:54:02.776300Z", "iopub.status.idle": "2022-04-11T11:54:02.782036Z", "shell.execute_reply": "2022-04-11T11:54:02.781023Z", "shell.execute_reply.started": "2022-04-11T11:54:02.776716Z" }, "id": "BFBngQzUtGlz", "trusted": true }, "outputs": [], "source": [ "label_freqs" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T11:57:02.701059Z", "iopub.status.busy": "2022-04-11T11:57:02.700782Z", "iopub.status.idle": "2022-04-11T11:57:02.707094Z", "shell.execute_reply": "2022-04-11T11:57:02.706336Z", "shell.execute_reply.started": "2022-04-11T11:57:02.701028Z" }, "id": "bGrWN0JntGl1", "trusted": true }, "outputs": [], "source": [ "sum(label_freqs.values())" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T11:57:14.992807Z", "iopub.status.busy": "2022-04-11T11:57:14.992108Z", "iopub.status.idle": "2022-04-11T11:57:15.292728Z", "shell.execute_reply": "2022-04-11T11:57:15.292079Z", "shell.execute_reply.started": "2022-04-11T11:57:14.992770Z" }, "id": "kOkXw2MktGl3", "trusted": true }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "\n", "plt.bar(\n", " label_freqs.keys(), #pass in our labels\n", " list(map(lambda x: x / sum(label_freqs.values()), label_freqs.values())), # normalized values\n", ")\n", "# add a title to the plot\n", "plt.title(\"Label frequencies\")\n", "# add a y axis label\n", "plt.ylabel(\"Percentage of total labels\")\n", "plt.show() # show the plot" ] }, { "cell_type": "markdown", "metadata": { "id": "xLjQQL8MtGl4" }, "source": [ "## Loading Data\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "ZUK8pVmHAD76" }, "outputs": [], "source": [ "from fastai.vision.all import *" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T11:58:47.125103Z", "iopub.status.busy": "2022-04-11T11:58:47.124354Z", "iopub.status.idle": "2022-04-11T11:58:47.130423Z", "shell.execute_reply": "2022-04-11T11:58:47.129576Z", "shell.execute_reply.started": "2022-04-11T11:58:47.125064Z" }, "id": "71GoU8z5tGl6", "trusted": true }, "outputs": [], "source": [ "df.columns" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:00:00.802979Z", "iopub.status.busy": "2022-04-11T12:00:00.802712Z", "iopub.status.idle": "2022-04-11T12:00:01.004391Z", "shell.execute_reply": "2022-04-11T12:00:01.003636Z", "shell.execute_reply.started": "2022-04-11T12:00:00.802950Z" }, "id": "qYPZtgTZtGl7", "trusted": true }, "outputs": [], "source": [ "photo_data = ImageDataLoaders.from_df(\n", " df, # the dataframe where our labels and image file paths are stored\n", " folder=\"../content/input/computer-vision-for-the-humanities-ph/photos_multi/photos_multi/photo_images\", # the path to the directory holding the images\n", " bs=32, # the batch size (number of images + labels)\n", " label_delim=\"|\", # the deliminator between each label in our label column\n", " item_tfms=Resize(224), # resize each image to 224x224\n", " valid_pct=0.3, # use 30% of the data as validation data\n", " seed=42 # set a seed to make results more reproducible\n", ")" ] }, { "cell_type": "markdown", "metadata": { "id": "ruXSFtB0tGl9" }, "source": [ "### fastai DataLoaders\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:00:47.990276Z", "iopub.status.busy": "2022-04-11T12:00:47.989803Z", "iopub.status.idle": "2022-04-11T12:00:47.995285Z", "shell.execute_reply": "2022-04-11T12:00:47.994547Z", "shell.execute_reply.started": "2022-04-11T12:00:47.990236Z" }, "id": "TtvoDoO2tGl-", "trusted": true }, "outputs": [], "source": [ "photo_data" ] }, { "cell_type": "markdown", "metadata": { "id": "87_lX7ILtGl-" }, "source": [ "## Viewing our Loaded Data" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:01:00.398876Z", "iopub.status.busy": "2022-04-11T12:01:00.398599Z", "iopub.status.idle": "2022-04-11T12:01:04.071641Z", "shell.execute_reply": "2022-04-11T12:01:04.070969Z", "shell.execute_reply.started": "2022-04-11T12:01:00.398842Z" }, "id": "7jSQzG-ktGl-", "trusted": true }, "outputs": [], "source": [ "photo_data.show_batch(figsize=(15,15))" ] }, { "cell_type": "markdown", "metadata": { "id": "9tKMazuytGl_" }, "source": [ "### Inspecting Model Inputs" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:01:52.465845Z", "iopub.status.busy": "2022-04-11T12:01:52.465592Z", "iopub.status.idle": "2022-04-11T12:01:52.471575Z", "shell.execute_reply": "2022-04-11T12:01:52.470667Z", "shell.execute_reply.started": "2022-04-11T12:01:52.465816Z" }, "id": "J88c3UaItGl_", "trusted": true }, "outputs": [], "source": [ "photo_data.vocab" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:01:57.590860Z", "iopub.status.busy": "2022-04-11T12:01:57.590605Z", "iopub.status.idle": "2022-04-11T12:01:59.461254Z", "shell.execute_reply": "2022-04-11T12:01:59.460510Z", "shell.execute_reply.started": "2022-04-11T12:01:57.590831Z" }, "id": "5K91-0lFtGmA", "trusted": true }, "outputs": [], "source": [ "x, y = photo_data.one_batch()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:06:13.348826Z", "iopub.status.busy": "2022-04-11T12:06:13.348351Z", "iopub.status.idle": "2022-04-11T12:06:13.354377Z", "shell.execute_reply": "2022-04-11T12:06:13.353715Z", "shell.execute_reply.started": "2022-04-11T12:06:13.348790Z" }, "id": "aVOxeLBitGmB", "trusted": true }, "outputs": [], "source": [ "type(x), type(y)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:06:29.572186Z", "iopub.status.busy": "2022-04-11T12:06:29.571807Z", "iopub.status.idle": "2022-04-11T12:06:29.578981Z", "shell.execute_reply": "2022-04-11T12:06:29.578301Z", "shell.execute_reply.started": "2022-04-11T12:06:29.572132Z" }, "id": "S1pCSw2rtGmB", "trusted": true }, "outputs": [], "source": [ "len(x), len(y)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:06:52.215392Z", "iopub.status.busy": "2022-04-11T12:06:52.214975Z", "iopub.status.idle": "2022-04-11T12:06:52.267205Z", "shell.execute_reply": "2022-04-11T12:06:52.266180Z", "shell.execute_reply.started": "2022-04-11T12:06:52.215349Z" }, "id": "Cr2dbQLJtGmC", "trusted": true }, "outputs": [], "source": [ "x[0]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:07:09.075970Z", "iopub.status.busy": "2022-04-11T12:07:09.075707Z", "iopub.status.idle": "2022-04-11T12:07:09.082593Z", "shell.execute_reply": "2022-04-11T12:07:09.081808Z", "shell.execute_reply.started": "2022-04-11T12:07:09.075941Z" }, "id": "UbOR8P5wtGmD", "trusted": true }, "outputs": [], "source": [ "x[0].shape" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:09:35.438778Z", "iopub.status.busy": "2022-04-11T12:09:35.438368Z", "iopub.status.idle": "2022-04-11T12:09:35.449728Z", "shell.execute_reply": "2022-04-11T12:09:35.448895Z", "shell.execute_reply.started": "2022-04-11T12:09:35.438735Z" }, "id": "CiYqAtlhtGmE", "trusted": true }, "outputs": [], "source": [ "y[0]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:09:49.521028Z", "iopub.status.busy": "2022-04-11T12:09:49.520776Z", "iopub.status.idle": "2022-04-11T12:09:49.526973Z", "shell.execute_reply": "2022-04-11T12:09:49.526287Z", "shell.execute_reply.started": "2022-04-11T12:09:49.520999Z" }, "id": "X8deHsHJtGmF", "trusted": true }, "outputs": [], "source": [ "y[0].shape" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:11:32.645908Z", "iopub.status.busy": "2022-04-11T12:11:32.645653Z", "iopub.status.idle": "2022-04-11T12:11:32.651573Z", "shell.execute_reply": "2022-04-11T12:11:32.650890Z", "shell.execute_reply.started": "2022-04-11T12:11:32.645879Z" }, "id": "o_CpW27ktGmF", "trusted": true }, "outputs": [], "source": [ "x.shape, y.shape" ] }, { "cell_type": "markdown", "metadata": { "id": "8QQY9ku4tGmG" }, "source": [ "### Image Augmentations" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:12:55.253941Z", "iopub.status.busy": "2022-04-11T12:12:55.253325Z", "iopub.status.idle": "2022-04-11T12:12:55.258419Z", "shell.execute_reply": "2022-04-11T12:12:55.257743Z", "shell.execute_reply.started": "2022-04-11T12:12:55.253888Z" }, "id": "Qt_1_mKttGmG", "trusted": true }, "outputs": [], "source": [ "tfms = setup_aug_tfms([Rotate(max_deg=90, p=0.75), Zoom(), Flip()])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:12:58.416431Z", "iopub.status.busy": "2022-04-11T12:12:58.415840Z", "iopub.status.idle": "2022-04-11T12:12:58.609823Z", "shell.execute_reply": "2022-04-11T12:12:58.609052Z", "shell.execute_reply.started": "2022-04-11T12:12:58.416389Z" }, "id": "2vdXBU-RtGmG", "trusted": true }, "outputs": [], "source": [ "photo_data = ImageDataLoaders.from_df(\n", " df, # dataframe containing paths to images and labels\n", " folder=\"../content/input/computer-vision-for-the-humanities-ph/photos_multi/photos_multi/photo_images\", # folder where images are stored\n", " bs=32, # batch size\n", " label_delim=\"|\", # the deliminator for multiple labels\n", " item_tfms=Resize(224), # resize images to a standard size\n", " batch_tfms=tfms, # pass in our transforms\n", " valid_pct=0.3, # 30% of data used for validation\n", " seed=42, # set a seed,\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:13:03.482407Z", "iopub.status.busy": "2022-04-11T12:13:03.481839Z", "iopub.status.idle": "2022-04-11T12:13:05.452713Z", "shell.execute_reply": "2022-04-11T12:13:05.452024Z", "shell.execute_reply.started": "2022-04-11T12:13:03.482364Z" }, "id": "a2tLmt3BtGmJ", "trusted": true }, "outputs": [], "source": [ "photo_data.show_batch(unique=True, figsize=(10,10))" ] }, { "cell_type": "markdown", "metadata": { "id": "CHFHESS9tGmK" }, "source": [ "## Creating a Model" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:20:37.356984Z", "iopub.status.busy": "2022-04-11T12:20:37.356704Z", "iopub.status.idle": "2022-04-11T12:20:37.835902Z", "shell.execute_reply": "2022-04-11T12:20:37.835121Z", "shell.execute_reply.started": "2022-04-11T12:20:37.356953Z" }, "id": "qgV9XF6utGmK", "trusted": true }, "outputs": [], "source": [ "learn = vision_learner(photo_data, densenet121, metrics=[F1ScoreMulti(), accuracy_multi])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:20:49.845940Z", "iopub.status.busy": "2022-04-11T12:20:49.845683Z", "iopub.status.idle": "2022-04-11T12:20:49.901842Z", "shell.execute_reply": "2022-04-11T12:20:49.901168Z", "shell.execute_reply.started": "2022-04-11T12:20:49.845912Z" }, "id": "Yb_QI1y8tGmV", "trusted": true }, "outputs": [], "source": [ "?learn" ] }, { "cell_type": "markdown", "metadata": { "id": "Fr4BmVMhtGmW" }, "source": [ "## Training the Model" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:28:11.288195Z", "iopub.status.busy": "2022-04-11T12:28:11.287902Z", "iopub.status.idle": "2022-04-11T12:31:10.320737Z", "shell.execute_reply": "2022-04-11T12:31:10.319989Z", "shell.execute_reply.started": "2022-04-11T12:28:11.288141Z" }, "id": "YPbZhSGatGmW", "trusted": true }, "outputs": [], "source": [ "learn.lr_find()" ] }, { "cell_type": "markdown", "metadata": { "id": "axk7o2xBtGma" }, "source": [ "## Fitting the Model\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:31:10.323226Z", "iopub.status.busy": "2022-04-11T12:31:10.322637Z", "iopub.status.idle": "2022-04-11T12:40:50.774841Z", "shell.execute_reply": "2022-04-11T12:40:50.774038Z", "shell.execute_reply.started": "2022-04-11T12:31:10.323187Z" }, "id": "vUV9kIibtGmc", "trusted": true }, "outputs": [], "source": [ "learn.fit_one_cycle(5, lr_max=2e-2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:40:50.776881Z", "iopub.status.busy": "2022-04-11T12:40:50.776600Z", "iopub.status.idle": "2022-04-11T12:40:50.998786Z", "shell.execute_reply": "2022-04-11T12:40:50.998021Z", "shell.execute_reply.started": "2022-04-11T12:40:50.776840Z" }, "id": "YSMpWs6mtGmf", "trusted": true }, "outputs": [], "source": [ "learn.recorder.plot_loss()" ] }, { "cell_type": "markdown", "metadata": { "id": "FXQKrGSytGmf" }, "source": [ "### Saving Progress\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:40:51.000919Z", "iopub.status.busy": "2022-04-11T12:40:51.000510Z", "iopub.status.idle": "2022-04-11T12:40:51.163166Z", "shell.execute_reply": "2022-04-11T12:40:51.162188Z", "shell.execute_reply.started": "2022-04-11T12:40:51.000880Z" }, "id": "ky0T-6h5tGmg", "trusted": true }, "outputs": [], "source": [ "learn.save('stage_1')" ] }, { "cell_type": "markdown", "metadata": { "id": "F3dFIN3ntGmg" }, "source": [ "## Unfreezing the Model\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:40:51.165190Z", "iopub.status.busy": "2022-04-11T12:40:51.164881Z", "iopub.status.idle": "2022-04-11T12:40:51.171877Z", "shell.execute_reply": "2022-04-11T12:40:51.170845Z", "shell.execute_reply.started": "2022-04-11T12:40:51.165136Z" }, "id": "6Z1XFYKNtGmg", "trusted": true }, "outputs": [], "source": [ "learn.unfreeze()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:40:51.174334Z", "iopub.status.busy": "2022-04-11T12:40:51.173994Z", "iopub.status.idle": "2022-04-11T12:43:50.743768Z", "shell.execute_reply": "2022-04-11T12:43:50.742996Z", "shell.execute_reply.started": "2022-04-11T12:40:51.174295Z" }, "id": "cLURB5wktGmg", "trusted": true }, "outputs": [], "source": [ "learn.lr_find()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "TK4e49Yy0Nkx" }, "outputs": [], "source": [ "learn.fit_one_cycle(4, lr_max=slice(6e-6, 4e-4), cbs=[SaveModelCallback(monitor='f1_score')])" ] }, { "cell_type": "markdown", "metadata": { "id": "JI-k_BwktGmh" }, "source": [ "## Investigating the Results of our Model\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:43:50.746604Z", "iopub.status.busy": "2022-04-11T12:43:50.746098Z", "iopub.status.idle": "2022-04-11T12:44:24.624914Z", "shell.execute_reply": "2022-04-11T12:44:24.624193Z", "shell.execute_reply.started": "2022-04-11T12:43:50.746563Z" }, "id": "srg-ueRVtGmh", "trusted": true }, "outputs": [], "source": [ "y_pred, y_true = learn.get_preds()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:45:34.706013Z", "iopub.status.busy": "2022-04-11T12:45:34.705358Z", "iopub.status.idle": "2022-04-11T12:45:34.711665Z", "shell.execute_reply": "2022-04-11T12:45:34.710692Z", "shell.execute_reply.started": "2022-04-11T12:45:34.705970Z" }, "id": "aEa2-Zl2tGmh", "trusted": true }, "outputs": [], "source": [ "len(y_pred), len(y_true)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:46:02.496487Z", "iopub.status.busy": "2022-04-11T12:46:02.496215Z", "iopub.status.idle": "2022-04-11T12:46:02.509305Z", "shell.execute_reply": "2022-04-11T12:46:02.508467Z", "shell.execute_reply.started": "2022-04-11T12:46:02.496458Z" }, "id": "mbbRj3XutGmi", "trusted": true }, "outputs": [], "source": [ "y_pred[0]" ] }, { "cell_type": "markdown", "metadata": { "id": "XoSo8ncFtGmj" }, "source": [ "## Exploring our Predictions Using scikit-learn\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:48:19.183907Z", "iopub.status.busy": "2022-04-11T12:48:19.183271Z", "iopub.status.idle": "2022-04-11T12:48:19.187798Z", "shell.execute_reply": "2022-04-11T12:48:19.187111Z", "shell.execute_reply.started": "2022-04-11T12:48:19.183869Z" }, "id": "BDjDkB9stGmj", "trusted": true }, "outputs": [], "source": [ "from sklearn.metrics import precision_score, recall_score, accuracy_score, f1_score" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:48:55.264690Z", "iopub.status.busy": "2022-04-11T12:48:55.264028Z", "iopub.status.idle": "2022-04-11T12:48:55.276923Z", "shell.execute_reply": "2022-04-11T12:48:55.276033Z", "shell.execute_reply.started": "2022-04-11T12:48:55.264646Z" }, "id": "lPqnknRQtGmk", "trusted": true }, "outputs": [], "source": [ "f1_score(y_true, y_pred>0.50, average='macro')" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:49:16.867950Z", "iopub.status.busy": "2022-04-11T12:49:16.867682Z", "iopub.status.idle": "2022-04-11T12:49:16.872276Z", "shell.execute_reply": "2022-04-11T12:49:16.871446Z", "shell.execute_reply.started": "2022-04-11T12:49:16.867920Z" }, "id": "8Tu-kCyKtGml", "trusted": true }, "outputs": [], "source": [ "from sklearn.metrics import classification_report" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "execution": { "iopub.execute_input": "2022-04-11T12:49:21.209678Z", "iopub.status.busy": "2022-04-11T12:49:21.208954Z", "iopub.status.idle": "2022-04-11T12:49:21.229606Z", "shell.execute_reply": "2022-04-11T12:49:21.228792Z", "shell.execute_reply.started": "2022-04-11T12:49:21.209638Z" }, "id": "-T29o-1ctGml", "trusted": true }, "outputs": [], "source": [ "print(classification_report(y_true, y_pred>0.50, target_names=photo_data.vocab, zero_division=1))" ] } ], "metadata": { "accelerator": "GPU", "colab": { "provenance": [] }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.4" } }, "nbformat": 4, "nbformat_minor": 0 }