JimmyChin1998/Pytorch-Learning-File
0
1{2 "cells": [3 {4 "cell_type": "code",5 "execution_count": 1,6 "id": "97572a01-d0d1-4b8e-b7ba-8d09f1d3bd89",7 "metadata": {},8 "outputs": [9 {10 "name": "stdout",11 "output_type": "stream",12 "text": [13 "[INFO] torch/torchvision versions not as required, installing nightly versions.\n",14 "Looking in indexes: https://pypi.org/simple, https://download.pytorch.org/whl/cu113\n",15 "Requirement already satisfied: torch in c:\\users\\jimmychin\\desktop\\pytorch\\lib\\site-packages (2.5.1)\n",16 "Requirement already satisfied: torchvision in c:\\users\\jimmychin\\desktop\\pytorch\\lib\\site-packages (0.20.1)\n",17 "Requirement already satisfied: torchaudio in c:\\users\\jimmychin\\desktop\\pytorch\\lib\\site-packages (2.5.1)\n",18 "Requirement already satisfied: filelock in c:\\users\\jimmychin\\desktop\\pytorch\\lib\\site-packages (from torch) (3.13.1)\n",19 "Requirement already satisfied: typing-extensions>=4.8.0 in c:\\users\\jimmychin\\desktop\\pytorch\\lib\\site-packages (from torch) (4.11.0)\n",20 "Requirement already satisfied: sympy==1.13.1 in c:\\users\\jimmychin\\desktop\\pytorch\\lib\\site-packages (from torch) (1.13.1)\n",21 "Requirement already satisfied: networkx in c:\\users\\jimmychin\\desktop\\pytorch\\lib\\site-packages (from torch) (3.2.1)\n",22 "Requirement already satisfied: jinja2 in c:\\users\\jimmychin\\desktop\\pytorch\\lib\\site-packages (from torch) (3.1.4)\n",23 "Requirement already satisfied: fsspec in c:\\users\\jimmychin\\desktop\\pytorch\\lib\\site-packages (from torch) (2024.10.0)\n",24 "Requirement already satisfied: mpmath<1.4,>=1.1.0 in c:\\users\\jimmychin\\desktop\\pytorch\\lib\\site-packages (from sympy==1.13.1->torch) (1.3.0)\n",25 "Requirement already satisfied: numpy in c:\\users\\jimmychin\\desktop\\pytorch\\lib\\site-packages (from torchvision) (1.26.4)\n",26 "Requirement already satisfied: pillow!=8.3.*,>=5.3.0 in c:\\users\\jimmychin\\desktop\\pytorch\\lib\\site-packages (from torchvision) (10.4.0)\n",27 "Requirement already satisfied: MarkupSafe>=2.0 in c:\\users\\jimmychin\\desktop\\pytorch\\lib\\site-packages (from jinja2->torch) (2.1.3)\n",28 "torch version: 2.5.1\n",29 "torchvision version: 0.20.1\n"30 ]31 }32 ],33 "source": [34 "# For this notebook to run with updated APIs, we need torch 1.12+ and torchvision 0.13+\n",35 "try:\n",36 " import torch\n",37 " import torchvision\n",38 " assert int(torch.__version__.split(\".\")[1]) >= 12, \"torch version should be 1.12+\"\n",39 " assert int(torchvision.__version__.split(\".\")[1]) >= 13, \"torchvision version should be 0.13+\"\n",40 " print(f\"torch version: {torch.__version__}\")\n",41 " print(f\"torchvision version: {torchvision.__version__}\")\n",42 "except:\n",43 " print(f\"[INFO] torch/torchvision versions not as required, installing nightly versions.\")\n",44 " !pip3 install -U torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/cu113\n",45 " import torch\n",46 " import torchvision\n",47 " print(f\"torch version: {torch.__version__}\")\n",48 " print(f\"torchvision version: {torchvision.__version__}\")"49 ]50 },51 {52 "cell_type": "code",53 "execution_count": 2,54 "id": "59c21c79-3d26-414f-9c17-93650422d011",55 "metadata": {},56 "outputs": [],57 "source": [58 "# Continue with regular imports\n",59 "import matplotlib.pyplot as plt\n",60 "import torch\n",61 "import torchvision\n",62 "\n",63 "from torch import nn\n",64 "from torchvision import transforms\n",65 "\n",66 "# Try to get torchinfo, install it if it doesn't work\n",67 "try:\n",68 " from torchinfo import summary\n",69 "except:\n",70 " print(\"[INFO] Couldn't find torchinfo... installing it.\")\n",71 " !pip install -q torchinfo\n",72 " from torchinfo import summary"73 ]74 },75 {76 "cell_type": "code",77 "execution_count": 3,78 "id": "8bb2b77a-69f8-4f8a-91e2-d9b034bced28",79 "metadata": {},80 "outputs": [],81 "source": [82 "# Try to import the going_modular directory, download it from GitHub if it doesn't work\n",83 "try:\n",84 " from going_modular import data_setup, engine\n",85 "except:\n",86 " # Get the going_modular scripts\n",87 " print(\"[INFO] Couldn't find going_modular scripts... downloading them from GitHub.\")\n",88 " !git clone https://github.com/mrdbourke/pytorch-deep-learning\n",89 " !mv pytorch-deep-learning/going_modular .\n",90 " !rm -rf pytorch-deep-learning\n",91 " from going_modular.going_modular import data_setup, engine"92 ]93 },94 {95 "cell_type": "code",96 "execution_count": 4,97 "id": "88d4521a-9715-43fc-9066-0174420032e1",98 "metadata": {},99 "outputs": [100 {101 "data": {102 "text/plain": [103 "'cuda'"104 ]105 },106 "execution_count": 4,107 "metadata": {},108 "output_type": "execute_result"109 }110 ],111 "source": [112 "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n",113 "device"114 ]115 },116 {117 "cell_type": "code",118 "execution_count": 5,119 "id": "dec21911-e89c-4a11-a6fb-3ad6cac5b24f",120 "metadata": {},121 "outputs": [],122 "source": [123 "# Set seeds\n",124 "def set_seeds(seed: int=42):\n",125 " \"\"\"Sets random sets for torch operations.\n",126 "\n",127 " Args:\n",128 " seed (int, optional): Random seed to set. Defaults to 42.\n",129 " \"\"\"\n",130 " # Set the seed for general torch operations\n",131 " torch.manual_seed(seed)\n",132 " # Set the seed for CUDA torch operations (ones that happen on the GPU)\n",133 " torch.cuda.manual_seed(seed)"134 ]135 },136 {137 "cell_type": "code",138 "execution_count": 6,139 "id": "063f7a39-92b2-431c-84f3-daecfad6244b",140 "metadata": {},141 "outputs": [142 {143 "name": "stdout",144 "output_type": "stream",145 "text": [146 "[INFO] data\\pizza_steak_sushi directory exists, skipping download.\n"147 ]148 },149 {150 "data": {151 "text/plain": [152 "WindowsPath('data/pizza_steak_sushi')"153 ]154 },155 "execution_count": 6,156 "metadata": {},157 "output_type": "execute_result"158 }159 ],160 "source": [161 "import os\n",162 "import zipfile\n",163 "\n",164 "from pathlib import Path\n",165 "\n",166 "import requests\n",167 "\n",168 "def download_data(source: str, \n",169 " destination: str,\n",170 " remove_source: bool = True) -> Path:\n",171 " \"\"\"Downloads a zipped dataset from source and unzips to destination.\n",172 "\n",173 " Args:\n",174 " source (str): A link to a zipped file containing data.\n",175 " destination (str): A target directory to unzip data to.\n",176 " remove_source (bool): Whether to remove the source after downloading and extracting.\n",177 " \n",178 " Returns:\n",179 " pathlib.Path to downloaded data.\n",180 " \n",181 " Example usage:\n",182 " download_data(source=\"https://github.com/mrdbourke/pytorch-deep-learning/raw/main/data/pizza_steak_sushi.zip\",\n",183 " destination=\"pizza_steak_sushi\")\n",184 " \"\"\"\n",185 " # Setup path to data folder\n",186 " data_path = Path(\"data/\")\n",187 " image_path = data_path / destination\n",188 "\n",189 " # If the image folder doesn't exist, download it and prepare it... \n",190 " if image_path.is_dir():\n",191 " print(f\"[INFO] {image_path} directory exists, skipping download.\")\n",192 " else:\n",193 " print(f\"[INFO] Did not find {image_path} directory, creating one...\")\n",194 " image_path.mkdir(parents=True, exist_ok=True)\n",195 " \n",196 " # Download pizza, steak, sushi data\n",197 " target_file = Path(source).name\n",198 " with open(data_path / target_file, \"wb\") as f:\n",199 " request = requests.get(source)\n",200 " print(f\"[INFO] Downloading {target_file} from {source}...\")\n",201 " f.write(request.content)\n",202 "\n",203 " # Unzip pizza, steak, sushi data\n",204 " with zipfile.ZipFile(data_path / target_file, \"r\") as zip_ref:\n",205 " print(f\"[INFO] Unzipping {target_file} data...\") \n",206 " zip_ref.extractall(image_path)\n",207 "\n",208 " # Remove .zip file\n",209 " if remove_source:\n",210 " os.remove(data_path / target_file)\n",211 " \n",212 " return image_path\n",213 "\n",214 "image_path = download_data(source=\"https://github.com/mrdbourke/pytorch-deep-learning/raw/main/data/pizza_steak_sushi.zip\",\n",215 " destination=\"pizza_steak_sushi\")\n",216 "image_path"217 ]218 },219 {220 "cell_type": "code",221 "execution_count": 7,222 "id": "e81276d8-398f-4bc5-acc4-55d0e210107c",223 "metadata": {},224 "outputs": [],225 "source": [226 "# pretrained on ImageNet\n",227 "normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],\n",228 " std=[0.229, 0.224, 0.225])"229 ]230 },231 {232 "cell_type": "code",233 "execution_count": 8,234 "id": "48a6b69a-32fd-4d5d-b0fe-56e3b8920d54",235 "metadata": {},236 "outputs": [237 {238 "name": "stdout",239 "output_type": "stream",240 "text": [241 "Manually created transforms: Compose(\n",242 " Resize(size=(224, 224), interpolation=bilinear, max_size=None, antialias=True)\n",243 " ToTensor()\n",244 " Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\n",245 ")\n"246 ]247 },248 {249 "data": {250 "text/plain": [251 "(<torch.utils.data.dataloader.DataLoader at 0x1533266cbd0>,\n",252 " <torch.utils.data.dataloader.DataLoader at 0x1531c712f10>,\n",253 " ['pizza', 'steak', 'sushi'])"254 ]255 },256 "execution_count": 8,257 "metadata": {},258 "output_type": "execute_result"259 }260 ],261 "source": [262 "# Setup directories\n",263 "train_dir = image_path / \"train\"\n",264 "test_dir = image_path / \"test\"\n",265 "\n",266 "# Setup ImageNet normalization levels (turns all images into similar distribution as ImageNet)\n",267 "normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],\n",268 " std=[0.229, 0.224, 0.225])\n",269 "\n",270 "# Create transform pipeline manually\n",271 "manual_transforms = transforms.Compose([\n",272 " transforms.Resize((224, 224)),\n",273 " transforms.ToTensor(),\n",274 " normalize\n",275 "]) \n",276 "print(f\"Manually created transforms: {manual_transforms}\")\n",277 "\n",278 "# Create data loaders\n",279 "train_dataloader, test_dataloader, class_names = data_setup.create_dataloaders(\n",280 " train_dir=train_dir,\n",281 " test_dir=test_dir,\n",282 " transform=manual_transforms, # use manually created transforms\n",283 " batch_size=32\n",284 ")\n",285 "\n",286 "train_dataloader, test_dataloader, class_names"287 ]288 },289 {290 "cell_type": "code",291 "execution_count": 10,292 "id": "ddbcbcfd-2d16-492e-b74b-a1edc35b8fdc",293 "metadata": {294 "scrolled": true295 },296 "outputs": [297 {298 "name": "stdout",299 "output_type": "stream",300 "text": [301 "<enum 'EfficientNet_B0_Weights'>\n",302 "{'categories': ['tench', 'goldfish', 'great white shark', 'tiger shark', 'hammerhead', 'electric ray', 'stingray', 'cock', 'hen', 'ostrich', 'brambling', 'goldfinch', 'house finch', 'junco', 'indigo bunting', 'robin', 'bulbul', 'jay', 'magpie', 'chickadee', 'water ouzel', 'kite', 'bald eagle', 'vulture', 'great grey owl', 'European fire salamander', 'common newt', 'eft', 'spotted salamander', 'axolotl', 'bullfrog', 'tree frog', 'tailed frog', 'loggerhead', 'leatherback turtle', 'mud turtle', 'terrapin', 'box turtle', 'banded gecko', 'common iguana', 'American chameleon', 'whiptail', 'agama', 'frilled lizard', 'alligator lizard', 'Gila monster', 'green lizard', 'African chameleon', 'Komodo dragon', 'African crocodile', 'American alligator', 'triceratops', 'thunder snake', 'ringneck snake', 'hognose snake', 'green snake', 'king snake', 'garter snake', 'water snake', 'vine snake', 'night snake', 'boa constrictor', 'rock python', 'Indian cobra', 'green mamba', 'sea snake', 'horned viper', 'diamondback', 'sidewinder', 'trilobite', 'harvestman', 'scorpion', 'black and gold garden spider', 'barn spider', 'garden spider', 'black widow', 'tarantula', 'wolf spider', 'tick', 'centipede', 'black grouse', 'ptarmigan', 'ruffed grouse', 'prairie chicken', 'peacock', 'quail', 'partridge', 'African grey', 'macaw', 'sulphur-crested cockatoo', 'lorikeet', 'coucal', 'bee eater', 'hornbill', 'hummingbird', 'jacamar', 'toucan', 'drake', 'red-breasted merganser', 'goose', 'black swan', 'tusker', 'echidna', 'platypus', 'wallaby', 'koala', 'wombat', 'jellyfish', 'sea anemone', 'brain coral', 'flatworm', 'nematode', 'conch', 'snail', 'slug', 'sea slug', 'chiton', 'chambered nautilus', 'Dungeness crab', 'rock crab', 'fiddler crab', 'king crab', 'American lobster', 'spiny lobster', 'crayfish', 'hermit crab', 'isopod', 'white stork', 'black stork', 'spoonbill', 'flamingo', 'little blue heron', 'American egret', 'bittern', 'crane bird', 'limpkin', 'European gallinule', 'American coot', 'bustard', 'ruddy turnstone', 'red-backed sandpiper', 'redshank', 'dowitcher', 'oystercatcher', 'pelican', 'king penguin', 'albatross', 'grey whale', 'killer whale', 'dugong', 'sea lion', 'Chihuahua', 'Japanese spaniel', 'Maltese dog', 'Pekinese', 'Shih-Tzu', 'Blenheim spaniel', 'papillon', 'toy terrier', 'Rhodesian ridgeback', 'Afghan hound', 'basset', 'beagle', 'bloodhound', 'bluetick', 'black-and-tan coonhound', 'Walker hound', 'English foxhound', 'redbone', 'borzoi', 'Irish wolfhound', 'Italian greyhound', 'whippet', 'Ibizan hound', 'Norwegian elkhound', 'otterhound', 'Saluki', 'Scottish deerhound', 'Weimaraner', 'Staffordshire bullterrier', 'American Staffordshire terrier', 'Bedlington terrier', 'Border terrier', 'Kerry blue terrier', 'Irish terrier', 'Norfolk terrier', 'Norwich terrier', 'Yorkshire terrier', 'wire-haired fox terrier', 'Lakeland terrier', 'Sealyham terrier', 'Airedale', 'cairn', 'Australian terrier', 'Dandie Dinmont', 'Boston bull', 'miniature schnauzer', 'giant schnauzer', 'standard schnauzer', 'Scotch terrier', 'Tibetan terrier', 'silky terrier', 'soft-coated wheaten terrier', 'West Highland white terrier', 'Lhasa', 'flat-coated retriever', 'curly-coated retriever', 'golden retriever', 'Labrador retriever', 'Chesapeake Bay retriever', 'German short-haired pointer', 'vizsla', 'English setter', 'Irish setter', 'Gordon setter', 'Brittany spaniel', 'clumber', 'English springer', 'Welsh springer spaniel', 'cocker spaniel', 'Sussex spaniel', 'Irish water spaniel', 'kuvasz', 'schipperke', 'groenendael', 'malinois', 'briard', 'kelpie', 'komondor', 'Old English sheepdog', 'Shetland sheepdog', 'collie', 'Border collie', 'Bouvier des Flandres', 'Rottweiler', 'German shepherd', 'Doberman', 'miniature pinscher', 'Greater Swiss Mountain dog', 'Bernese mountain dog', 'Appenzeller', 'EntleBucher', 'boxer', 'bull mastiff', 'Tibetan mastiff', 'French bulldog', 'Great Dane', 'Saint Bernard', 'Eskimo dog', 'malamute', 'Siberian husky', 'dalmatian', 'affenpinscher', 'basenji', 'pug', 'Leonberg', 'Newfoundland', 'Great Pyrenees', 'Samoyed', 'Pomeranian', 'chow', 'keeshond', 'Brabancon griffon', 'Pembroke', 'Cardigan', 'toy poodle', 'miniature poodle', 'standard poodle', 'Mexican hairless', 'timber wolf', 'white wolf', 'red wolf', 'coyote', 'dingo', 'dhole', 'African hunting dog', 'hyena', 'red fox', 'kit fox', 'Arctic fox', 'grey fox', 'tabby', 'tiger cat', 'Persian cat', 'Siamese cat', 'Egyptian cat', 'cougar', 'lynx', 'leopard', 'snow leopard', 'jaguar', 'lion', 'tiger', 'cheetah', 'brown bear', 'American black bear', 'ice bear', 'sloth bear', 'mongoose', 'meerkat', 'tiger beetle', 'ladybug', 'ground beetle', 'long-horned beetle', 'leaf beetle', 'dung beetle', 'rhinoceros beetle', 'weevil', 'fly', 'bee', 'ant', 'grasshopper', 'cricket', 'walking stick', 'cockroach', 'mantis', 'cicada', 'leafhopper', 'lacewing', 'dragonfly', 'damselfly', 'admiral', 'ringlet', 'monarch', 'cabbage butterfly', 'sulphur butterfly', 'lycaenid', 'starfish', 'sea urchin', 'sea cucumber', 'wood rabbit', 'hare', 'Angora', 'hamster', 'porcupine', 'fox squirrel', 'marmot', 'beaver', 'guinea pig', 'sorrel', 'zebra', 'hog', 'wild boar', 'warthog', 'hippopotamus', 'ox', 'water buffalo', 'bison', 'ram', 'bighorn', 'ibex', 'hartebeest', 'impala', 'gazelle', 'Arabian camel', 'llama', 'weasel', 'mink', 'polecat', 'black-footed ferret', 'otter', 'skunk', 'badger', 'armadillo', 'three-toed sloth', 'orangutan', 'gorilla', 'chimpanzee', 'gibbon', 'siamang', 'guenon', 'patas', 'baboon', 'macaque', 'langur', 'colobus', 'proboscis monkey', 'marmoset', 'capuchin', 'howler monkey', 'titi', 'spider monkey', 'squirrel monkey', 'Madagascar cat', 'indri', 'Indian elephant', 'African elephant', 'lesser panda', 'giant panda', 'barracouta', 'eel', 'coho', 'rock beauty', 'anemone fish', 'sturgeon', 'gar', 'lionfish', 'puffer', 'abacus', 'abaya', 'academic gown', 'accordion', 'acoustic guitar', 'aircraft carrier', 'airliner', 'airship', 'altar', 'ambulance', 'amphibian', 'analog clock', 'apiary', 'apron', 'ashcan', 'assault rifle', 'backpack', 'bakery', 'balance beam', 'balloon', 'ballpoint', 'Band Aid', 'banjo', 'bannister', 'barbell', 'barber chair', 'barbershop', 'barn', 'barometer', 'barrel', 'barrow', 'baseball', 'basketball', 'bassinet', 'bassoon', 'bathing cap', 'bath towel', 'bathtub', 'beach wagon', 'beacon', 'beaker', 'bearskin', 'beer bottle', 'beer glass', 'bell cote', 'bib', 'bicycle-built-for-two', 'bikini', 'binder', 'binoculars', 'birdhouse', 'boathouse', 'bobsled', 'bolo tie', 'bonnet', 'bookcase', 'bookshop', 'bottlecap', 'bow', 'bow tie', 'brass', 'brassiere', 'breakwater', 'breastplate', 'broom', 'bucket', 'buckle', 'bulletproof vest', 'bullet train', 'butcher shop', 'cab', 'caldron', 'candle', 'cannon', 'canoe', 'can opener', 'cardigan', 'car mirror', 'carousel', \"carpenter's kit\", 'carton', 'car wheel', 'cash machine', 'cassette', 'cassette player', 'castle', 'catamaran', 'CD player', 'cello', 'cellular telephone', 'chain', 'chainlink fence', 'chain mail', 'chain saw', 'chest', 'chiffonier', 'chime', 'china cabinet', 'Christmas stocking', 'church', 'cinema', 'cleaver', 'cliff dwelling', 'cloak', 'clog', 'cocktail shaker', 'coffee mug', 'coffeepot', 'coil', 'combination lock', 'computer keyboard', 'confectionery', 'container ship', 'convertible', 'corkscrew', 'cornet', 'cowboy boot', 'cowboy hat', 'cradle', 'crane', 'crash helmet', 'crate', 'crib', 'Crock Pot', 'croquet ball', 'crutch', 'cuirass', 'dam', 'desk', 'desktop computer', 'dial telephone', 'diaper', 'digital clock', 'digital watch', 'dining table', 'dishrag', 'dishwasher', 'disk brake', 'dock', 'dogsled', 'dome', 'doormat', 'drilling platform', 'drum', 'drumstick', 'dumbbell', 'Dutch oven', 'electric fan', 'electric guitar', 'electric locomotive', 'entertainment center', 'envelope', 'espresso maker', 'face powder', 'feather boa', 'file', 'fireboat', 'fire engine', 'fire screen', 'flagpole', 'flute', 'folding chair', 'football helmet', 'forklift', 'fountain', 'fountain pen', 'four-poster', 'freight car', 'French horn', 'frying pan', 'fur coat', 'garbage truck', 'gasmask', 'gas pump', 'goblet', 'go-kart', 'golf ball', 'golfcart', 'gondola', 'gong', 'gown', 'grand piano', 'greenhouse', 'grille', 'grocery store', 'guillotine', 'hair slide', 'hair spray', 'half track', 'hammer', 'hamper', 'hand blower', 'hand-held computer', 'handkerchief', 'hard disc', 'harmonica', 'harp', 'harvester', 'hatchet', 'holster', 'home theater', 'honeycomb', 'hook', 'hoopskirt', 'horizontal bar', 'horse cart', 'hourglass', 'iPod', 'iron', \"jack-o'-lantern\", 'jean', 'jeep', 'jersey', 'jigsaw puzzle', 'jinrikisha', 'joystick', 'kimono', 'knee pad', 'knot', 'lab coat', 'ladle', 'lampshade', 'laptop', 'lawn mower', 'lens cap', 'letter opener', 'library', 'lifeboat', 'lighter', 'limousine', 'liner', 'lipstick', 'Loafer', 'lotion', 'loudspeaker', 'loupe', 'lumbermill', 'magnetic compass', 'mailbag', 'mailbox', 'maillot', 'maillot tank suit', 'manhole cover', 'maraca', 'marimba', 'mask', 'matchstick', 'maypole', 'maze', 'measuring cup', 'medicine chest', 'megalith', 'microphone', 'microwave', 'military uniform', 'milk can', 'minibus', 'miniskirt', 'minivan', 'missile', 'mitten', 'mixing bowl', 'mobile home', 'Model T', 'modem', 'monastery', 'monitor', 'moped', 'mortar', 'mortarboard', 'mosque', 'mosquito net', 'motor scooter', 'mountain bike', 'mountain tent', 'mouse', 'mousetrap', 'moving van', 'muzzle', 'nail', 'neck brace', 'necklace', 'nipple', 'notebook', 'obelisk', 'oboe', 'ocarina', 'odometer', 'oil filter', 'organ', 'oscilloscope', 'overskirt', 'oxcart', 'oxygen mask', 'packet', 'paddle', 'paddlewheel', 'padlock', 'paintbrush', 'pajama', 'palace', 'panpipe', 'paper towel', 'parachute', 'parallel bars', 'park bench', 'parking meter', 'passenger car', 'patio', 'pay-phone', 'pedestal', 'pencil box', 'pencil sharpener', 'perfume', 'Petri dish', 'photocopier', 'pick', 'pickelhaube', 'picket fence', 'pickup', 'pier', 'piggy bank', 'pill bottle', 'pillow', 'ping-pong ball', 'pinwheel', 'pirate', 'pitcher', 'plane', 'planetarium', 'plastic bag', 'plate rack', 'plow', 'plunger', 'Polaroid camera', 'pole', 'police van', 'poncho', 'pool table', 'pop bottle', 'pot', \"potter's wheel\", 'power drill', 'prayer rug', 'printer', 'prison', 'projectile', 'projector', 'puck', 'punching bag', 'purse', 'quill', 'quilt', 'racer', 'racket', 'radiator', 'radio', 'radio telescope', 'rain barrel', 'recreational vehicle', 'reel', 'reflex camera', 'refrigerator', 'remote control', 'restaurant', 'revolver', 'rifle', 'rocking chair', 'rotisserie', 'rubber eraser', 'rugby ball', 'rule', 'running shoe', 'safe', 'safety pin', 'saltshaker', 'sandal', 'sarong', 'sax', 'scabbard', 'scale', 'school bus', 'schooner', 'scoreboard', 'screen', 'screw', 'screwdriver', 'seat belt', 'sewing machine', 'shield', 'shoe shop', 'shoji', 'shopping basket', 'shopping cart', 'shovel', 'shower cap', 'shower curtain', 'ski', 'ski mask', 'sleeping bag', 'slide rule', 'sliding door', 'slot', 'snorkel', 'snowmobile', 'snowplow', 'soap dispenser', 'soccer ball', 'sock', 'solar dish', 'sombrero', 'soup bowl', 'space bar', 'space heater', 'space shuttle', 'spatula', 'speedboat', 'spider web', 'spindle', 'sports car', 'spotlight', 'stage', 'steam locomotive', 'steel arch bridge', 'steel drum', 'stethoscope', 'stole', 'stone wall', 'stopwatch', 'stove', 'strainer', 'streetcar', 'stretcher', 'studio couch', 'stupa', 'submarine', 'suit', 'sundial', 'sunglass', 'sunglasses', 'sunscreen', 'suspension bridge', 'swab', 'sweatshirt', 'swimming trunks', 'swing', 'switch', 'syringe', 'table lamp', 'tank', 'tape player', 'teapot', 'teddy', 'television', 'tennis ball', 'thatch', 'theater curtain', 'thimble', 'thresher', 'throne', 'tile roof', 'toaster', 'tobacco shop', 'toilet seat', 'torch', 'totem pole', 'tow truck', 'toyshop', 'tractor', 'trailer truck', 'tray', 'trench coat', 'tricycle', 'trimaran', 'tripod', 'triumphal arch', 'trolleybus', 'trombone', 'tub', 'turnstile', 'typewriter keyboard', 'umbrella', 'unicycle', 'upright', 'vacuum', 'vase', 'vault', 'velvet', 'vending machine', 'vestment', 'viaduct', 'violin', 'volleyball', 'waffle iron', 'wall clock', 'wallet', 'wardrobe', 'warplane', 'washbasin', 'washer', 'water bottle', 'water jug', 'water tower', 'whiskey jug', 'whistle', 'wig', 'window screen', 'window shade', 'Windsor tie', 'wine bottle', 'wing', 'wok', 'wooden spoon', 'wool', 'worm fence', 'wreck', 'yawl', 'yurt', 'web site', 'comic book', 'crossword puzzle', 'street sign', 'traffic light', 'book jacket', 'menu', 'plate', 'guacamole', 'consomme', 'hot pot', 'trifle', 'ice cream', 'ice lolly', 'French loaf', 'bagel', 'pretzel', 'cheeseburger', 'hotdog', 'mashed potato', 'head cabbage', 'broccoli', 'cauliflower', 'zucchini', 'spaghetti squash', 'acorn squash', 'butternut squash', 'cucumber', 'artichoke', 'bell pepper', 'cardoon', 'mushroom', 'Granny Smith', 'strawberry', 'orange', 'lemon', 'fig', 'pineapple', 'banana', 'jackfruit', 'custard apple', 'pomegranate', 'hay', 'carbonara', 'chocolate sauce', 'dough', 'meat loaf', 'pizza', 'potpie', 'burrito', 'red wine', 'espresso', 'cup', 'eggnog', 'alp', 'bubble', 'cliff', 'coral reef', 'geyser', 'lakeside', 'promontory', 'sandbar', 'seashore', 'valley', 'volcano', 'ballplayer', 'groom', 'scuba diver', 'rapeseed', 'daisy', \"yellow lady's slipper\", 'corn', 'acorn', 'hip', 'buckeye', 'coral fungus', 'agaric', 'gyromitra', 'stinkhorn', 'earthstar', 'hen-of-the-woods', 'bolete', 'ear', 'toilet tissue'], 'min_size': (1, 1), 'recipe': 'https://github.com/pytorch/vision/tree/main/references/classification#efficientnet-v1', 'num_params': 5288548, '_metrics': {'ImageNet-1K': {'acc@1': 77.692, 'acc@5': 93.532}}, '_ops': 0.386, '_file_size': 20.451, '_docs': 'These weights are ported from the original paper.'}\n"303 ]304 }305 ],306 "source": [307 "# 可以提供data預處理的transform compose\n",308 "# 可以直接給予model各項已經過訓練調整的參數數值\n",309 "# torchvision.models.efficientnet_b0只是取得model本身但並包括訓練參數,需要再額外賦值\n",310 "weights = torchvision.models.EfficientNet_B0_Weights.DEFAULT\n",311 "print(type(weights))\n",312 "print(weights.meta)"313 ]314 },315 {316 "cell_type": "code",317 "execution_count": 11,318 "id": "c75ffa71-127a-492b-9fd9-fc8c33586a04",319 "metadata": {},320 "outputs": [321 {322 "name": "stdout",323 "output_type": "stream",324 "text": [325 "Automatically created transforms: ImageClassification(\n",326 " crop_size=[224]\n",327 " resize_size=[256]\n",328 " mean=[0.485, 0.456, 0.406]\n",329 " std=[0.229, 0.224, 0.225]\n",330 " interpolation=InterpolationMode.BICUBIC\n",331 ")\n"332 ]333 },334 {335 "data": {336 "text/plain": [337 "(<torch.utils.data.dataloader.DataLoader at 0x15332823f10>,\n",338 " <torch.utils.data.dataloader.DataLoader at 0x1533266f190>,\n",339 " ['pizza', 'steak', 'sushi'])"340 ]341 },342 "execution_count": 11,343 "metadata": {},344 "output_type": "execute_result"345 }346 ],347 "source": [348 "# Setup dirs\n",349 "train_dir = image_path / \"train\"\n",350 "test_dir = image_path / \"test\"\n",351 "\n",352 "# Setup pretrained weights (plenty of these available in torchvision.models)\n",353 "weights = torchvision.models.EfficientNet_B0_Weights.DEFAULT\n",354 "\n",355 "# Get transforms from weights (these are the transforms that were used to obtain the weights)\n",356 "automatic_transforms = weights.transforms() \n",357 "print(f\"Automatically created transforms: {automatic_transforms}\")\n",358 "\n",359 "# Create data loaders\n",360 "train_dataloader, test_dataloader, class_names = data_setup.create_dataloaders(\n",361 " train_dir=train_dir,\n",362 " test_dir=test_dir,\n",363 " transform=automatic_transforms, # use automatic created transforms\n",364 " batch_size=32\n",365 ")\n",366 "\n",367 "train_dataloader, test_dataloader, class_names"368 ]369 },370 {371 "cell_type": "code",372 "execution_count": 13,373 "id": "25411e29-b308-474d-a3b4-bd55933084ae",374 "metadata": {},375 "outputs": [],376 "source": [377 "# Note: This is how a pretrained model would be created in torchvision > 0.13, it will be deprecated in future versions.\n",378 "# model = torchvision.models.efficientnet_b0(pretrained=True).to(device) # OLD \n",379 "\n",380 "# Download the pretrained weights for EfficientNet_B0\n",381 "weights = torchvision.models.EfficientNet_B0_Weights.DEFAULT # NEW in torchvision 0.13, \"DEFAULT\" means \"best weights available\"\n",382 "\n",383 "# Setup the model with the pretrained weights and send it to the target device\n",384 "model = torchvision.models.efficientnet_b0(weights=weights).to(device)\n",385 "\n",386 "# View the output of the model\n",387 "# model"388 ]389 },390 {391 "cell_type": "code",392 "execution_count": 16,393 "id": "01d558ad-b3ff-4b9e-b74c-4ebd5f3a430b",394 "metadata": {},395 "outputs": [],396 "source": [397 "# Freeze all base layers by setting requires_grad attribute to False\n",398 "for param in model.features.parameters():\n",399 " param.requires_grad = False # 除了classifier\n",400 " \n",401 "# Since we're creating a new layer with random weights (torch.nn.Linear), \n",402 "# let's set the seeds\n",403 "set_seeds() \n",404 "\n",405 "# Update the classifier head to suit our problem\n",406 "model.classifier = torch.nn.Sequential(\n",407 " nn.Dropout(p=0.2, inplace=True),\n",408 " nn.Linear(in_features=1280, \n",409 " out_features=len(class_names),\n",410 " bias=True).to(device))"411 ]412 },413 {414 "cell_type": "code",415 "execution_count": 17,416 "id": "8bbb9a52-e3f1-4c93-a63c-07a01e3e5ddc",417 "metadata": {418 "scrolled": true419 },420 "outputs": [421 {422 "data": {423 "text/plain": [424 "============================================================================================================================================\n",425 "Layer (type (var_name)) Input Shape Output Shape Param # Trainable\n",426 "============================================================================================================================================\n",427 "EfficientNet (EfficientNet) [32, 3, 224, 224] [32, 3] -- Partial\n",428 "├─Sequential (features) [32, 3, 224, 224] [32, 1280, 7, 7] -- False\n",429 "│ └─Conv2dNormActivation (0) [32, 3, 224, 224] [32, 32, 112, 112] -- False\n",430 "│ │ └─Conv2d (0) [32, 3, 224, 224] [32, 32, 112, 112] (864) False\n",431 "│ │ └─BatchNorm2d (1) [32, 32, 112, 112] [32, 32, 112, 112] (64) False\n",432 "│ │ └─SiLU (2) [32, 32, 112, 112] [32, 32, 112, 112] -- --\n",433 "│ └─Sequential (1) [32, 32, 112, 112] [32, 16, 112, 112] -- False\n",434 "│ │ └─MBConv (0) [32, 32, 112, 112] [32, 16, 112, 112] (1,448) False\n",435 "│ └─Sequential (2) [32, 16, 112, 112] [32, 24, 56, 56] -- False\n",436 "│ │ └─MBConv (0) [32, 16, 112, 112] [32, 24, 56, 56] (6,004) False\n",437 "│ │ └─MBConv (1) [32, 24, 56, 56] [32, 24, 56, 56] (10,710) False\n",438 "│ └─Sequential (3) [32, 24, 56, 56] [32, 40, 28, 28] -- False\n",439 "│ │ └─MBConv (0) [32, 24, 56, 56] [32, 40, 28, 28] (15,350) False\n",440 "│ │ └─MBConv (1) [32, 40, 28, 28] [32, 40, 28, 28] (31,290) False\n",441 "│ └─Sequential (4) [32, 40, 28, 28] [32, 80, 14, 14] -- False\n",442 "│ │ └─MBConv (0) [32, 40, 28, 28] [32, 80, 14, 14] (37,130) False\n",443 "│ │ └─MBConv (1) [32, 80, 14, 14] [32, 80, 14, 14] (102,900) False\n",444 "│ │ └─MBConv (2) [32, 80, 14, 14] [32, 80, 14, 14] (102,900) False\n",445 "│ └─Sequential (5) [32, 80, 14, 14] [32, 112, 14, 14] -- False\n",446 "│ │ └─MBConv (0) [32, 80, 14, 14] [32, 112, 14, 14] (126,004) False\n",447 "│ │ └─MBConv (1) [32, 112, 14, 14] [32, 112, 14, 14] (208,572) False\n",448 "│ │ └─MBConv (2) [32, 112, 14, 14] [32, 112, 14, 14] (208,572) False\n",449 "│ └─Sequential (6) [32, 112, 14, 14] [32, 192, 7, 7] -- False\n",450 "│ │ └─MBConv (0) [32, 112, 14, 14] [32, 192, 7, 7] (262,492) False\n",451 "│ │ └─MBConv (1) [32, 192, 7, 7] [32, 192, 7, 7] (587,952) False\n",452 "│ │ └─MBConv (2) [32, 192, 7, 7] [32, 192, 7, 7] (587,952) False\n",453 "│ │ └─MBConv (3) [32, 192, 7, 7] [32, 192, 7, 7] (587,952) False\n",454 "│ └─Sequential (7) [32, 192, 7, 7] [32, 320, 7, 7] -- False\n",455 "│ │ └─MBConv (0) [32, 192, 7, 7] [32, 320, 7, 7] (717,232) False\n",456 "│ └─Conv2dNormActivation (8) [32, 320, 7, 7] [32, 1280, 7, 7] -- False\n",457 "│ │ └─Conv2d (0) [32, 320, 7, 7] [32, 1280, 7, 7] (409,600) False\n",458 "│ │ └─BatchNorm2d (1) [32, 1280, 7, 7] [32, 1280, 7, 7] (2,560) False\n",459 "│ │ └─SiLU (2) [32, 1280, 7, 7] [32, 1280, 7, 7] -- --\n",460 "├─AdaptiveAvgPool2d (avgpool) [32, 1280, 7, 7] [32, 1280, 1, 1] -- --\n",461 "├─Sequential (classifier) [32, 1280] [32, 3] -- True\n",462 "│ └─Dropout (0) [32, 1280] [32, 1280] -- --\n",463 "│ └─Linear (1) [32, 1280] [32, 3] 3,843 True\n",464 "============================================================================================================================================\n",465 "Total params: 4,011,391\n",466 "Trainable params: 3,843\n",467 "Non-trainable params: 4,007,548\n",468 "Total mult-adds (Units.GIGABYTES): 12.31\n",469 "============================================================================================================================================\n",470 "Input size (MB): 19.27\n",471 "Forward/backward pass size (MB): 3452.09\n",472 "Params size (MB): 16.05\n",473 "Estimated Total Size (MB): 3487.41\n",474 "============================================================================================================================================"475 ]476 },477 "execution_count": 17,478 "metadata": {},479 "output_type": "execute_result"480 }481 ],482 "source": [483 "from torchinfo import summary\n",484 "\n",485 "# # Get a summary of the model (uncomment for full output)\n",486 "summary(model, \n",487 " input_size=(32, 3, 224, 224), # make sure this is \"input_size\", not \"input_shape\" (batch_size, color_channels, height, width)\n",488 " verbose=0,\n",489 " col_names=[\"input_size\", \"output_size\", \"num_params\", \"trainable\"],\n",490 " col_width=20,\n",491 " row_settings=[\"var_names\"]\n",492 ")"493 ]494 },495 {496 "cell_type": "code",497 "execution_count": 19,498 "id": "4eff8664-1235-448a-99b0-60d8d3daebe9",499 "metadata": {},500 "outputs": [],501 "source": [502 "# Define loss and optimizer\n",503 "loss_fn = nn.CrossEntropyLoss()\n",504 "optimizer = torch.optim.Adam(model.parameters(), lr=0.001)"505 ]506 },507 {508 "cell_type": "code",509 "execution_count": 23,510 "id": "d034a075-6c8d-46d2-9b5c-02b6505b2f15",511 "metadata": {},512 "outputs": [],513 "source": [514 "try:\n",515 " from torch.utils.tensorboard import SummaryWriter\n",516 "except:\n",517 " print(\"[INFO] Couldn't find tensorboard... installing it.\")\n",518 " !pip install -q tensorboard\n",519 " from torch.utils.tensorboard import SummaryWriter\n",520 "\n",521 "\n",522 "# Create a writer with all default settings\n",523 "writer = SummaryWriter()"524 ]525 },526 {527 "cell_type": "code",528 "execution_count": 24,529 "id": "ef0c9201-78ae-4963-b7ce-e14d5e6cbb3b",530 "metadata": {},531 "outputs": [],532 "source": [533 "from typing import Dict, List\n",534 "from tqdm.auto import tqdm\n",535 "\n",536 "from going_modular.engine import train_step, test_step\n",537 "\n",538 "# Import train() function from: \n",539 "# https://github.com/mrdbourke/pytorch-deep-learning/blob/main/going_modular/going_modular/engine.py\n",540 "def train(model: torch.nn.Module, \n",541 " train_dataloader: torch.utils.data.DataLoader, \n",542 " test_dataloader: torch.utils.data.DataLoader, \n",543 " optimizer: torch.optim.Optimizer,\n",544 " loss_fn: torch.nn.Module,\n",545 " epochs: int,\n",546 " device: torch.device) -> Dict[str, List]:\n",547 " \"\"\"Trains and tests a PyTorch model.\n",548 "\n",549 " Passes a target PyTorch models through train_step() and test_step()\n",550 " functions for a number of epochs, training and testing the model\n",551 " in the same epoch loop.\n",552 "\n",553 " Calculates, prints and stores evaluation metrics throughout.\n",554 "\n",555 " Args:\n",556 " model: A PyTorch model to be trained and tested.\n",557 " train_dataloader: A DataLoader instance for the model to be trained on.\n",558 " test_dataloader: A DataLoader instance for the model to be tested on.\n",559 " optimizer: A PyTorch optimizer to help minimize the loss function.\n",560 " loss_fn: A PyTorch loss function to calculate loss on both datasets.\n",561 " epochs: An integer indicating how many epochs to train for.\n",562 " device: A target device to compute on (e.g. \"cuda\" or \"cpu\").\n",563 " \n",564 " Returns:\n",565 " A dictionary of training and testing loss as well as training and\n",566 " testing accuracy metrics. Each metric has a value in a list for \n",567 " each epoch.\n",568 " In the form: {train_loss: [...],\n",569 " train_acc: [...],\n",570 " test_loss: [...],\n",571 " test_acc: [...]} \n",572 " For example if training for epochs=2: \n",573 " {train_loss: [2.0616, 1.0537],\n",574 " train_acc: [0.3945, 0.3945],\n",575 " test_loss: [1.2641, 1.5706],\n",576 " test_acc: [0.3400, 0.2973]} \n",577 " \"\"\"\n",578 " # Create empty results dictionary\n",579 " results = {\"train_loss\": [],\n",580 " \"train_acc\": [],\n",581 " \"test_loss\": [],\n",582 " \"test_acc\": []\n",583 " }\n",584 "\n",585 " # Loop through training and testing steps for a number of epochs\n",586 " for epoch in tqdm(range(epochs)):\n",587 " train_loss, train_acc = train_step(model=model,\n",588 " dataloader=train_dataloader,\n",589 " loss_fn=loss_fn,\n",590 " optimizer=optimizer,\n",591 " device=device)\n",592 " test_loss, test_acc = test_step(model=model,\n",593 " dataloader=test_dataloader,\n",594 " loss_fn=loss_fn,\n",595 " device=device)\n",596 "\n",597 " # Print out what's happening\n",598 " print(\n",599 " f\"Epoch: {epoch+1} | \"\n",600 " f\"train_loss: {train_loss:.4f} | \"\n",601 " f\"train_acc: {train_acc:.4f} | \"\n",602 " f\"test_loss: {test_loss:.4f} | \"\n",603 " f\"test_acc: {test_acc:.4f}\"\n",604 " )\n",605 "\n",606 " # Update results dictionary\n",607 " results[\"train_loss\"].append(train_loss)\n",608 " results[\"train_acc\"].append(train_acc)\n",609 " results[\"test_loss\"].append(test_loss)\n",610 " results[\"test_acc\"].append(test_acc)\n",611 "\n",612 " ### New: Experiment tracking ###\n",613 " # Add loss results to SummaryWriter\n",614 " # tag_scalar_dict => Y軸, global_step => X軸\n",615 " writer.add_scalars(main_tag=\"Loss\", \n",616 " tag_scalar_dict={\"train_loss\": train_loss,\n",617 " \"test_loss\": test_loss},\n",618 " global_step=epoch)\n",619 "\n",620 " # Add accuracy results to SummaryWriter\n",621 " writer.add_scalars(main_tag=\"Accuracy\", \n",622 " tag_scalar_dict={\"train_acc\": train_acc,\n",623 " \"test_acc\": test_acc}, \n",624 " global_step=epoch)\n",625 " \n",626 " # Track the PyTorch model architecture\n",627 " writer.add_graph(model=model, \n",628 " # Pass in an example input\n",629 " input_to_model=torch.randn(32, 3, 224, 224).to(device))\n",630 " \n",631 " # Close the writer\n",632 " writer.close()\n",633 " \n",634 " ### End new ###\n",635 "\n",636 " # Return the filled results at the end of the epochs\n",637 " return results"638 ]639 },640 {641 "cell_type": "code",642 "execution_count": 25,643 "id": "293be727-1361-425f-92e5-4c28f5fd37aa",644 "metadata": {},645 "outputs": [646 {647 "data": {648 "application/vnd.jupyter.widget-view+json": {649 "model_id": "a4e0a2e7286d4245b7d9ee5820ef2be5",650 "version_major": 2,651 "version_minor": 0652 },653 "text/plain": [654 " 0%| | 0/5 [00:00<?, ?it/s]"655 ]656 },657 "metadata": {},658 "output_type": "display_data"659 },660 {661 "name": "stdout",662 "output_type": "stream",663 "text": [664 "Epoch: 1 | train_loss: 1.0978 | train_acc: 0.3750 | test_loss: 0.9135 | test_acc: 0.5502\n",665 "Epoch: 2 | train_loss: 0.9017 | train_acc: 0.6484 | test_loss: 0.7943 | test_acc: 0.8258\n",666 "Epoch: 3 | train_loss: 0.8139 | train_acc: 0.7266 | test_loss: 0.6804 | test_acc: 0.8759\n",667 "Epoch: 4 | train_loss: 0.6793 | train_acc: 0.7188 | test_loss: 0.6745 | test_acc: 0.8352\n",668 "Epoch: 5 | train_loss: 0.7114 | train_acc: 0.7266 | test_loss: 0.6813 | test_acc: 0.7737\n"669 ]670 }671 ],672 "source": [673 "# Train model\n",674 "# Note: Not using engine.train() since the original script isn't updated to use writer\n",675 "set_seeds()\n",676 "results = train(model=model,\n",677 " train_dataloader=train_dataloader,\n",678 " test_dataloader=test_dataloader,\n",679 " optimizer=optimizer,\n",680 " loss_fn=loss_fn,\n",681 " epochs=5,\n",682 " device=device)"683 ]684 },685 {686 "cell_type": "code",687 "execution_count": 26,688 "id": "a8d0dbf4-8119-407d-8495-0a4ed015de6d",689 "metadata": {},690 "outputs": [691 {692 "data": {693 "text/plain": [694 "{'train_loss': [1.0977561250329018,\n",695 " 0.9016556069254875,\n",696 " 0.8138723447918892,\n",697 " 0.6793194711208344,\n",698 " 0.7113911136984825],\n",699 " 'train_acc': [0.375, 0.6484375, 0.7265625, 0.71875, 0.7265625],\n",700 " 'test_loss': [0.9135278065999349,\n",701 " 0.7943447828292847,\n",702 " 0.6804185907046,\n",703 " 0.6744822263717651,\n",704 " 0.6812926332155863],\n",705 " 'test_acc': [0.5501893939393939,\n",706 " 0.8257575757575758,\n",707 " 0.8759469696969697,\n",708 " 0.8352272727272728,\n",709 " 0.7736742424242425]}"710 ]711 },712 "execution_count": 26,713 "metadata": {},714 "output_type": "execute_result"715 }716 ],717 "source": [718 "# Check out the model results\n",719 "results"720 ]721 },722 {723 "cell_type": "code",724 "execution_count": 30,725 "id": "fb7617ca-25dc-4105-9352-de013b7dd871",726 "metadata": {},727 "outputs": [728 {729 "name": "stdout",730 "output_type": "stream",731 "text": [732 "The tensorboard extension is already loaded. To reload it, use:\n",733 " %reload_ext tensorboard\n"734 ]735 },736 {737 "data": {738 "text/html": [739 "\n",740 " <iframe id=\"tensorboard-frame-51d2c4e785846834\" width=\"100%\" height=\"800\" frameborder=\"0\">\n",741 " </iframe>\n",742 " <script>\n",743 " (function() {\n",744 " const frame = document.getElementById(\"tensorboard-frame-51d2c4e785846834\");\n",745 " const url = new URL(\"/\", window.location);\n",746 " const port = 6006;\n",747 " if (port) {\n",748 " url.port = port;\n",749 " }\n",750 " frame.src = url;\n",751 " })();\n",752 " </script>\n",753 " "754 ],755 "text/plain": [756 "<IPython.core.display.HTML object>"757 ]758 },759 "metadata": {},760 "output_type": "display_data"761 }762 ],763 "source": [764 "# Example code to run in Jupyter or Google Colab Notebook (uncomment to try it out)\n",765 "%load_ext tensorboard\n",766 "%tensorboard --logdir \"C:\\Users\\jimmychin\\Desktop\\Pytorch\\Practice\\runs\"\n",767 "# %tensorboard --logdir runs"768 ]769 },770 {771 "cell_type": "code",772 "execution_count": 31,773 "id": "f1cd53f1-dff6-4d6f-b3c8-5ff994436693",774 "metadata": {},775 "outputs": [],776 "source": [777 "def create_writer(experiment_name: str, \n",778 " model_name: str, \n",779 " extra: str=None) -> torch.utils.tensorboard.writer.SummaryWriter():\n",780 " \"\"\"Creates a torch.utils.tensorboard.writer.SummaryWriter() instance saving to a specific log_dir.\n",781 "\n",782 " log_dir is a combination of runs/timestamp/experiment_name/model_name/extra.\n",783 "\n",784 " Where timestamp is the current date in YYYY-MM-DD format.\n",785 "\n",786 " Args:\n",787 " experiment_name (str): Name of experiment.\n",788 " model_name (str): Name of model.\n",789 " extra (str, optional): Anything extra to add to the directory. Defaults to None.\n",790 "\n",791 " Returns:\n",792 " torch.utils.tensorboard.writer.SummaryWriter(): Instance of a writer saving to log_dir.\n",793 "\n",794 " Example usage:\n",795 " # Create a writer saving to \"runs/2022-06-04/data_10_percent/effnetb2/5_epochs/\"\n",796 " writer = create_writer(experiment_name=\"data_10_percent\",\n",797 " model_name=\"effnetb2\",\n",798 " extra=\"5_epochs\")\n",799 " # The above is the same as:\n",800 " writer = SummaryWriter(log_dir=\"runs/2022-06-04/data_10_percent/effnetb2/5_epochs/\")\n",801 " \"\"\"\n",802 " from datetime import datetime\n",803 " import os\n",804 "\n",805 " # Get timestamp of current date (all experiments on certain day live in same folder)\n",806 " timestamp = datetime.now().strftime(\"%Y-%m-%d\") # returns current date in YYYY-MM-DD format\n",807 "\n",808 " if extra:\n",809 " # Create log directory path\n",810 " log_dir = os.path.join(\"runs\", timestamp, experiment_name, model_name, extra)\n",811 " else:\n",812 " log_dir = os.path.join(\"runs\", timestamp, experiment_name, model_name)\n",813 " \n",814 " print(f\"[INFO] Created SummaryWriter, saving to: {log_dir}...\")\n",815 " return SummaryWriter(log_dir=log_dir)"816 ]817 },818 {819 "cell_type": "code",820 "execution_count": 32,821 "id": "8263c336-9aed-4d0c-933f-aca301d47346",822 "metadata": {},823 "outputs": [824 {825 "name": "stdout",826 "output_type": "stream",827 "text": [828 "[INFO] Created SummaryWriter, saving to: runs\\2024-11-29\\data_10_percent\\effnetb0\\5_epochs...\n"829 ]830 }831 ],832 "source": [833 "# Create an example writer\n",834 "example_writer = create_writer(experiment_name=\"data_10_percent\",\n",835 " model_name=\"effnetb0\",\n",836 " extra=\"5_epochs\")"837 ]838 },839 {840 "cell_type": "code",841 "execution_count": 33,842 "id": "04e75050-b17e-4903-bea7-ce19f3eb8a66",843 "metadata": {},844 "outputs": [],845 "source": [846 "from typing import Dict, List\n",847 "from tqdm.auto import tqdm\n",848 "\n",849 "# Add writer parameter to train()\n",850 "def train(model: torch.nn.Module, \n",851 " train_dataloader: torch.utils.data.DataLoader, \n",852 " test_dataloader: torch.utils.data.DataLoader, \n",853 " optimizer: torch.optim.Optimizer,\n",854 " loss_fn: torch.nn.Module,\n",855 " epochs: int,\n",856 " device: torch.device, \n",857 " writer: torch.utils.tensorboard.writer.SummaryWriter # new parameter to take in a writer\n",858 " ) -> Dict[str, List]:\n",859 " \"\"\"Trains and tests a PyTorch model.\n",860 "\n",861 " Passes a target PyTorch models through train_step() and test_step()\n",862 " functions for a number of epochs, training and testing the model\n",863 " in the same epoch loop.\n",864 "\n",865 " Calculates, prints and stores evaluation metrics throughout.\n",866 "\n",867 " Stores metrics to specified writer log_dir if present.\n",868 "\n",869 " Args:\n",870 " model: A PyTorch model to be trained and tested.\n",871 " train_dataloader: A DataLoader instance for the model to be trained on.\n",872 " test_dataloader: A DataLoader instance for the model to be tested on.\n",873 " optimizer: A PyTorch optimizer to help minimize the loss function.\n",874 " loss_fn: A PyTorch loss function to calculate loss on both datasets.\n",875 " epochs: An integer indicating how many epochs to train for.\n",876 " device: A target device to compute on (e.g. \"cuda\" or \"cpu\").\n",877 " writer: A SummaryWriter() instance to log model results to.\n",878 "\n",879 " Returns:\n",880 " A dictionary of training and testing loss as well as training and\n",881 " testing accuracy metrics. Each metric has a value in a list for \n",882 " each epoch.\n",883 " In the form: {train_loss: [...],\n",884 " train_acc: [...],\n",885 " test_loss: [...],\n",886 " test_acc: [...]} \n",887 " For example if training for epochs=2: \n",888 " {train_loss: [2.0616, 1.0537],\n",889 " train_acc: [0.3945, 0.3945],\n",890 " test_loss: [1.2641, 1.5706],\n",891 " test_acc: [0.3400, 0.2973]} \n",892 " \"\"\"\n",893 " # Create empty results dictionary\n",894 " results = {\"train_loss\": [],\n",895 " \"train_acc\": [],\n",896 " \"test_loss\": [],\n",897 " \"test_acc\": []\n",898 " }\n",899 "\n",900 " # Loop through training and testing steps for a number of epochs\n",901 " for epoch in tqdm(range(epochs)):\n",902 " train_loss, train_acc = train_step(model=model,\n",903 " dataloader=train_dataloader,\n",904 " loss_fn=loss_fn,\n",905 " optimizer=optimizer,\n",906 " device=device)\n",907 " test_loss, test_acc = test_step(model=model,\n",908 " dataloader=test_dataloader,\n",909 " loss_fn=loss_fn,\n",910 " device=device)\n",911 "\n",912 " # Print out what's happening\n",913 " print(\n",914 " f\"Epoch: {epoch+1} | \"\n",915 " f\"train_loss: {train_loss:.4f} | \"\n",916 " f\"train_acc: {train_acc:.4f} | \"\n",917 " f\"test_loss: {test_loss:.4f} | \"\n",918 " f\"test_acc: {test_acc:.4f}\"\n",919 " )\n",920 "\n",921 " # Update results dictionary\n",922 " results[\"train_loss\"].append(train_loss)\n",923 " results[\"train_acc\"].append(train_acc)\n",924 " results[\"test_loss\"].append(test_loss)\n",925 " results[\"test_acc\"].append(test_acc)\n",926 "\n",927 "\n",928 " ### New: Use the writer parameter to track experiments ###\n",929 " # See if there's a writer, if so, log to it\n",930 " if writer:\n",931 " # Add results to SummaryWriter\n",932 " writer.add_scalars(main_tag=\"Loss\", \n",933 " tag_scalar_dict={\"train_loss\": train_loss,\n",934 " \"test_loss\": test_loss},\n",935 " global_step=epoch)\n",936 " writer.add_scalars(main_tag=\"Accuracy\", \n",937 " tag_scalar_dict={\"train_acc\": train_acc,\n",938 " \"test_acc\": test_acc}, \n",939 " global_step=epoch)\n",940 "\n",941 " # Close the writer\n",942 " writer.close()\n",943 " else:\n",944 " pass\n",945 " ### End new ###\n",946 "\n",947 " # Return the filled results at the end of the epochs\n",948 " return results"949 ]950 },951 {952 "cell_type": "code",953 "execution_count": 34,954 "id": "07428f09-f8c5-48f7-a1e2-2c1145ea104b",955 "metadata": {},956 "outputs": [957 {958 "name": "stdout",959 "output_type": "stream",960 "text": [961 "[INFO] data\\pizza_steak_sushi directory exists, skipping download.\n",962 "[INFO] data\\pizza_steak_sushi_20_percent directory exists, skipping download.\n"963 ]964 }965 ],966 "source": [967 "# Download 10 percent and 20 percent training data (if necessary)\n",968 "data_10_percent_path = download_data(source=\"https://github.com/mrdbourke/pytorch-deep-learning/raw/main/data/pizza_steak_sushi.zip\",\n",969 " destination=\"pizza_steak_sushi\")\n",970 "\n",971 "data_20_percent_path = download_data(source=\"https://github.com/mrdbourke/pytorch-deep-learning/raw/main/data/pizza_steak_sushi_20_percent.zip\",\n",972 " destination=\"pizza_steak_sushi_20_percent\")"973 ]974 },975 {976 "cell_type": "code",977 "execution_count": 35,978 "id": "c7473efb-cfab-4e52-830d-62d6005086e0",979 "metadata": {},980 "outputs": [981 {982 "name": "stdout",983 "output_type": "stream",984 "text": [985 "Training directory 10%: data\\pizza_steak_sushi\\train\n",986 "Training directory 20%: data\\pizza_steak_sushi_20_percent\\train\n",987 "Testing directory: data\\pizza_steak_sushi\\test\n"988 ]989 }990 ],991 "source": [992 "# Setup training directory paths\n",993 "train_dir_10_percent = data_10_percent_path / \"train\"\n",994 "train_dir_20_percent = data_20_percent_path / \"train\"\n",995 "\n",996 "# Setup testing directory paths (note: use the same test dataset for both to compare the results)\n",997 "test_dir = data_10_percent_path / \"test\"\n",998 "\n",999 "# Check the directories\n",1000 "print(f\"Training directory 10%: {train_dir_10_percent}\")\n",1001 "print(f\"Training directory 20%: {train_dir_20_percent}\")\n",1002 "print(f\"Testing directory: {test_dir}\")"1003 ]1004 },1005 {1006 "cell_type": "code",1007 "execution_count": 36,1008 "id": "1c2ddd67-1b9b-45dc-9237-bf850c69e142",1009 "metadata": {},1010 "outputs": [],1011 "source": [1012 "from torchvision import transforms\n",1013 "\n",1014 "# Create a transform to normalize data distribution to be inline with ImageNet\n",1015 "normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], # values per colour channel [red, green, blue]\n",1016 " std=[0.229, 0.224, 0.225]) # values per colour channel [red, green, blue]\n",1017 "\n",1018 "# Compose transforms into a pipeline\n",1019 "simple_transform = transforms.Compose([\n",1020 " transforms.Resize((224, 224)), # 1. Resize the images\n",1021 " transforms.ToTensor(), # 2. Turn the images into tensors with values between 0 & 1\n",1022 " normalize # 3. Normalize the images so their distributions match the ImageNet dataset \n",1023 "])"1024 ]1025 },1026 {1027 "cell_type": "code",1028 "execution_count": 37,1029 "id": "963c0b15-e042-4d98-9b25-9c9fd2640626",1030 "metadata": {},1031 "outputs": [1032 {1033 "name": "stdout",1034 "output_type": "stream",1035 "text": [1036 "Number of batches of size 32 in 10 percent training data: 8\n",1037 "Number of batches of size 32 in 20 percent training data: 15\n",1038 "Number of batches of size 32 in testing data: 3 (all experiments will use the same test set)\n",1039 "Number of classes: 3, class names: ['pizza', 'steak', 'sushi']\n"1040 ]1041 }1042 ],1043 "source": [1044 "BATCH_SIZE = 32\n",1045 "\n",1046 "# Create 10% training and test DataLoaders\n",1047 "train_dataloader_10_percent, test_dataloader, class_names = data_setup.create_dataloaders(train_dir=train_dir_10_percent,\n",1048 " test_dir=test_dir, \n",1049 " transform=simple_transform,\n",1050 " batch_size=BATCH_SIZE\n",1051 ")\n",1052 "\n",1053 "# Create 20% training and test data DataLoders\n",1054 "train_dataloader_20_percent, test_dataloader, class_names = data_setup.create_dataloaders(train_dir=train_dir_20_percent,\n",1055 " test_dir=test_dir,\n",1056 " transform=simple_transform,\n",1057 " batch_size=BATCH_SIZE\n",1058 ")\n",1059 "\n",1060 "# Find the number of samples/batches per dataloader (using the same test_dataloader for both experiments)\n",1061 "print(f\"Number of batches of size {BATCH_SIZE} in 10 percent training data: {len(train_dataloader_10_percent)}\")\n",1062 "print(f\"Number of batches of size {BATCH_SIZE} in 20 percent training data: {len(train_dataloader_20_percent)}\")\n",1063 "print(f\"Number of batches of size {BATCH_SIZE} in testing data: {len(test_dataloader)} (all experiments will use the same test set)\")\n",1064 "print(f\"Number of classes: {len(class_names)}, class names: {class_names}\")"1065 ]1066 },1067 {1068 "cell_type": "code",1069 "execution_count": 40,1070 "id": "1474969f-5fde-4025-9d30-2588e962616b",1071 "metadata": {1072 "scrolled": true1073 },1074 "outputs": [1075 {1076 "data": {1077 "text/plain": [1078 "============================================================================================================================================\n",1079 "Layer (type (var_name)) Input Shape Output Shape Param # Trainable\n",1080 "============================================================================================================================================\n",1081 "EfficientNet (EfficientNet) [32, 3, 224, 224] [32, 1000] -- True\n",1082 "├─Sequential (features) [32, 3, 224, 224] [32, 1408, 7, 7] -- True\n",1083 "│ └─Conv2dNormActivation (0) [32, 3, 224, 224] [32, 32, 112, 112] -- True\n",1084 "│ │ └─Conv2d (0) [32, 3, 224, 224] [32, 32, 112, 112] 864 True\n",1085 "│ │ └─BatchNorm2d (1) [32, 32, 112, 112] [32, 32, 112, 112] 64 True\n",1086 "│ │ └─SiLU (2) [32, 32, 112, 112] [32, 32, 112, 112] -- --\n",1087 "│ └─Sequential (1) [32, 32, 112, 112] [32, 16, 112, 112] -- True\n",1088 "│ │ └─MBConv (0) [32, 32, 112, 112] [32, 16, 112, 112] 1,448 True\n",1089 "│ │ └─MBConv (1) [32, 16, 112, 112] [32, 16, 112, 112] 612 True\n",1090 "│ └─Sequential (2) [32, 16, 112, 112] [32, 24, 56, 56] -- True\n",1091 "│ │ └─MBConv (0) [32, 16, 112, 112] [32, 24, 56, 56] 6,004 True\n",1092 "│ │ └─MBConv (1) [32, 24, 56, 56] [32, 24, 56, 56] 10,710 True\n",1093 "│ │ └─MBConv (2) [32, 24, 56, 56] [32, 24, 56, 56] 10,710 True\n",1094 "│ └─Sequential (3) [32, 24, 56, 56] [32, 48, 28, 28] -- True\n",1095 "│ │ └─MBConv (0) [32, 24, 56, 56] [32, 48, 28, 28] 16,518 True\n",1096 "│ │ └─MBConv (1) [32, 48, 28, 28] [32, 48, 28, 28] 43,308 True\n",1097 "│ │ └─MBConv (2) [32, 48, 28, 28] [32, 48, 28, 28] 43,308 True\n",1098 "│ └─Sequential (4) [32, 48, 28, 28] [32, 88, 14, 14] -- True\n",1099 "│ │ └─MBConv (0) [32, 48, 28, 28] [32, 88, 14, 14] 50,300 True\n",1100 "│ │ └─MBConv (1) [32, 88, 14, 14] [32, 88, 14, 14] 123,750 True\n",1101 "│ │ └─MBConv (2) [32, 88, 14, 14] [32, 88, 14, 14] 123,750 True\n",1102 "│ │ └─MBConv (3) [32, 88, 14, 14] [32, 88, 14, 14] 123,750 True\n",1103 "│ └─Sequential (5) [32, 88, 14, 14] [32, 120, 14, 14] -- True\n",1104 "│ │ └─MBConv (0) [32, 88, 14, 14] [32, 120, 14, 14] 149,158 True\n",1105 "│ │ └─MBConv (1) [32, 120, 14, 14] [32, 120, 14, 14] 237,870 True\n",1106 "│ │ └─MBConv (2) [32, 120, 14, 14] [32, 120, 14, 14] 237,870 True\n",1107 "│ │ └─MBConv (3) [32, 120, 14, 14] [32, 120, 14, 14] 237,870 True\n",1108 "│ └─Sequential (6) [32, 120, 14, 14] [32, 208, 7, 7] -- True\n",1109 "│ │ └─MBConv (0) [32, 120, 14, 14] [32, 208, 7, 7] 301,406 True\n",1110 "│ │ └─MBConv (1) [32, 208, 7, 7] [32, 208, 7, 7] 686,868 True\n",1111 "│ │ └─MBConv (2) [32, 208, 7, 7] [32, 208, 7, 7] 686,868 True\n",1112 "│ │ └─MBConv (3) [32, 208, 7, 7] [32, 208, 7, 7] 686,868 True\n",1113 "│ │ └─MBConv (4) [32, 208, 7, 7] [32, 208, 7, 7] 686,868 True\n",1114 "│ └─Sequential (7) [32, 208, 7, 7] [32, 352, 7, 7] -- True\n",1115 "│ │ └─MBConv (0) [32, 208, 7, 7] [32, 352, 7, 7] 846,900 True\n",1116 "│ │ └─MBConv (1) [32, 352, 7, 7] [32, 352, 7, 7] 1,888,920 True\n",1117 "│ └─Conv2dNormActivation (8) [32, 352, 7, 7] [32, 1408, 7, 7] -- True\n",1118 "│ │ └─Conv2d (0) [32, 352, 7, 7] [32, 1408, 7, 7] 495,616 True\n",1119 "│ │ └─BatchNorm2d (1) [32, 1408, 7, 7] [32, 1408, 7, 7] 2,816 True\n",1120 "│ │ └─SiLU (2) [32, 1408, 7, 7] [32, 1408, 7, 7] -- --\n",1121 "├─AdaptiveAvgPool2d (avgpool) [32, 1408, 7, 7] [32, 1408, 1, 1] -- --\n",1122 "├─Sequential (classifier) [32, 1408] [32, 1000] -- True\n",1123 "│ └─Dropout (0) [32, 1408] [32, 1408] -- --\n",1124 "│ └─Linear (1) [32, 1408] [32, 1000] 1,409,000 True\n",1125 "============================================================================================================================================\n",1126 "Total params: 9,109,994\n",1127 "Trainable params: 9,109,994\n",1128 "Non-trainable params: 0\n",1129 "Total mult-adds (Units.GIGABYTES): 21.09\n",1130 "============================================================================================================================================\n",1131 "Input size (MB): 19.27\n",1132 "Forward/backward pass size (MB): 5017.79\n",1133 "Params size (MB): 36.44\n",1134 "Estimated Total Size (MB): 5073.49\n",1135 "============================================================================================================================================"1136 ]1137 },1138 "execution_count": 40,1139 "metadata": {},1140 "output_type": "execute_result"1141 }1142 ],1143 "source": [1144 "import torchvision\n",1145 "from torchinfo import summary\n",1146 "\n",1147 "# 1. Create an instance of EffNetB2 with pretrained weights\n",1148 "effnetb2_weights = torchvision.models.EfficientNet_B2_Weights.DEFAULT # \"DEFAULT\" means best available weights\n",1149 "effnetb2 = torchvision.models.efficientnet_b2(weights=effnetb2_weights)\n",1150 "\n",1151 "# # 2. Get a summary of standard EffNetB2 from torchvision.models (uncomment for full output)\n",1152 "summary(model=effnetb2, \n",1153 " input_size=(32, 3, 224, 224), # make sure this is \"input_size\", not \"input_shape\"\n",1154 " # col_names=[\"input_size\"], # uncomment for smaller output\n",1155 " col_names=[\"input_size\", \"output_size\", \"num_params\", \"trainable\"],\n",1156 " col_width=20,\n",1157 " row_settings=[\"var_names\"]\n",1158 ") \n",1159 "\n",1160 "# 3. Get the number of in_features of the EfficientNetB2 classifier layer\n",1161 "# print(f\"Number of in_features to final layer of EfficientNetB2: {len(effnetb2.classifier.state_dict()['1.weight'][0])}\")"1162 ]1163 },1164 {1165 "cell_type": "code",1166 "execution_count": 41,1167 "id": "90edeb3d-b50d-4046-b447-f87b208669cf",1168 "metadata": {},1169 "outputs": [1170 {1171 "name": "stdout",1172 "output_type": "stream",1173 "text": [1174 "Number of in_features to final layer of EfficientNetB2: 1408\n"1175 ]1176 }1177 ],1178 "source": [1179 "print(f\"Number of in_features to final layer of EfficientNetB2: {len(effnetb2.classifier.state_dict()['1.weight'][0])}\")"1180 ]1181 },1182 {1183 "cell_type": "code",1184 "execution_count": 42,1185 "id": "285f89f0-8bfe-48e4-b21a-39c1be56a7ac",1186 "metadata": {},1187 "outputs": [],1188 "source": [1189 "import torchvision\n",1190 "from torch import nn\n",1191 "\n",1192 "# Get num out features (one for each class pizza, steak, sushi)\n",1193 "OUT_FEATURES = len(class_names)\n",1194 "\n",1195 "# Create an EffNetB0 feature extractor\n",1196 "def create_effnetb0():\n",1197 " # 1. Get the base model with pretrained weights and send to target device\n",1198 " weights = torchvision.models.EfficientNet_B0_Weights.DEFAULT\n",1199 " model = torchvision.models.efficientnet_b0(weights=weights).to(device)\n",1200 "\n",