{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"#!pip install --upgrade -q wandb","metadata":{"execution":{"iopub.status.busy":"2022-12-09T22:31:53.400968Z","iopub.execute_input":"2022-12-09T22:31:53.401351Z","iopub.status.idle":"2022-12-09T22:31:53.407241Z","shell.execute_reply.started":"2022-12-09T22:31:53.401295Z","shell.execute_reply":"2022-12-09T22:31:53.405934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Intro to MLOps: Experiment Tracking\n","metadata":{}},{"cell_type":"code","source":"from datetime import datetime\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport random\nimport cv2\n\nimport torch\nimport torch.nn as nn\n\nimport torchvision\n\nfrom torch import nn\nfrom torch import optim\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset, DataLoader, ConcatDataset\nfrom torchvision import datasets, transforms, models\nimport torchvision.models as models\n\nimport copy\nimport tqdm\nfrom PIL import Image\n\nimport os\nimport zipfile\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nfrom sklearn import preprocessing\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score, confusion_matrix\n\nfrom kaggle_secrets import UserSecretsClient\n\nimport wandb\n\nSEED = 42\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-12-09T22:31:53.411025Z","iopub.execute_input":"2022-12-09T22:31:53.411319Z","iopub.status.idle":"2022-12-09T22:31:53.421219Z","shell.execute_reply.started":"2022-12-09T22:31:53.411275Z","shell.execute_reply":"2022-12-09T22:31:53.420265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n# Experiment Tracking with W&B\n\nBefore we begin with the modeling, let's setup Weights & Biases (W&B) for experiment tracking.\n\n**Disclaimer:** I am a W&B Ambassador\n\n![Weights & Biases Black Text.png](attachment:0767596b-2518-4be1-9568-866550cfeabe.png)","metadata":{},"attachments":{"0767596b-2518-4be1-9568-866550cfeabe.png":{"image/png":"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"}}},{"cell_type":"code","source":"# Setup user secrets for login\nuser_secrets = UserSecretsClient()\nwandb_api = user_secrets.get_secret(\"WANDB_API_KEY\") \n\n# Login\nwandb.login(key = wandb_api)\n","metadata":{"execution":{"iopub.status.busy":"2022-12-09T22:31:53.432619Z","iopub.execute_input":"2022-12-09T22:31:53.433464Z","iopub.status.idle":"2022-12-09T22:31:53.816321Z","shell.execute_reply.started":"2022-12-09T22:31:53.433428Z","shell.execute_reply":"2022-12-09T22:31:53.815282Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"NUM_CLASSES = 2\n\nIMAGE_CHANNELS = 3\n\nconfig = dict(\n    seed = SEED,\n    model = 'resnet',\n    batch_size = 32,\n    image_size = 224, \n    epochs = 5,\n    learning_rate = 1e-4,\n    augmentation = 'medium'\n)\n\nrun = wandb.init(project = \"Intro-to-MLOps\",\n                 name = f\"Run_{datetime.now().strftime('%d%m%Y%H%M%S')}\", \n                 notes = \"Increase augmentation\",\n                 tags = [],\n                 config = config,\n)","metadata":{"execution":{"iopub.status.busy":"2022-12-09T22:31:53.818396Z","iopub.execute_input":"2022-12-09T22:31:53.819053Z","iopub.status.idle":"2022-12-09T22:31:59.916311Z","shell.execute_reply.started":"2022-12-09T22:31:53.819011Z","shell.execute_reply":"2022-12-09T22:31:59.915478Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load and Prepare Data","metadata":{}},{"cell_type":"code","source":"# Load train data\ntrain_zip = zipfile.ZipFile(\"/kaggle/input/dogs-vs-cats/train.zip\")\ntrain_zip.extractall(\"/kaggle/working/dataset\")\ntrain_zip.close()","metadata":{"execution":{"iopub.status.busy":"2022-12-09T22:31:59.917382Z","iopub.execute_input":"2022-12-09T22:31:59.917740Z","iopub.status.idle":"2022-12-09T22:32:11.209609Z","shell.execute_reply.started":"2022-12-09T22:31:59.917704Z","shell.execute_reply":"2022-12-09T22:32:11.208480Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dir = './dataset/train'\ntrain_files = os.listdir(train_dir)","metadata":{"execution":{"iopub.status.busy":"2022-12-09T22:32:11.215280Z","iopub.execute_input":"2022-12-09T22:32:11.216138Z","iopub.status.idle":"2022-12-09T22:32:11.247433Z","shell.execute_reply.started":"2022-12-09T22:32:11.216086Z","shell.execute_reply":"2022-12-09T22:32:11.246195Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"filenames = os.listdir('./dataset/train')\ncategories = []\nfor filename in filenames:\n    category = filename.split('.')[0]\n    if category == 'dog':\n        categories.append('dog')\n    else:\n        categories.append('cat')\ndf = pd.DataFrame({'filename' : filenames , 'category' : categories})\n\n# Shuffle datapoints\ndf = df.sample(frac = 1, random_state = SEED).reset_index(drop=True)\n\n# Label encode labels\nle = preprocessing.LabelEncoder()\ndf['label'] = le.fit_transform(df['category'])\n\n# Split data into training and testing data\ntrain, test_df = train_test_split(df , test_size = 0.2, random_state = SEED)\ntrain.reset_index(drop = True, inplace = True)\ntest_df.reset_index(drop = True, inplace = True)\n\n# Split training data into training and validation data\ntrain_df, val_df = train_test_split(train, test_size = 0.2, random_state = SEED)\ntrain_df.reset_index(drop = True, inplace = True)\nval_df.reset_index(drop = True, inplace = True)\n\ndisplay(train_df.head())\ndisplay(val_df.head())\ndisplay(test_df.head())","metadata":{"execution":{"iopub.status.busy":"2022-12-09T22:32:11.251474Z","iopub.execute_input":"2022-12-09T22:32:11.252002Z","iopub.status.idle":"2022-12-09T22:32:11.357682Z","shell.execute_reply.started":"2022-12-09T22:32:11.251967Z","shell.execute_reply":"2022-12-09T22:32:11.356811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CatDogDataset(Dataset):\n    def __init__(self, \n                 root_dir, \n                 df, \n                 transform=None):\n        self.root_dir = root_dir\n        self.df = df\n        self.file_names = df['filename'].values\n        self.labels = df['label'].values\n        self.transform = transform\n        \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, idx):\n        img = Image.open(os.path.join(self.root_dir, \n                                      self.file_names[idx]))\n        \n        if self.transform:\n            img = self.transform(img)\n            \n        img = img.numpy()\n        return img.astype('float32'), self.labels[idx]","metadata":{"execution":{"iopub.status.busy":"2022-12-09T22:32:11.361652Z","iopub.execute_input":"2022-12-09T22:32:11.367369Z","iopub.status.idle":"2022-12-09T22:32:11.383238Z","shell.execute_reply.started":"2022-12-09T22:32:11.367331Z","shell.execute_reply":"2022-12-09T22:32:11.382338Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_transform_none = transforms.Compose([\n    transforms.Resize((config['image_size'], config['image_size'])),\n    transforms.ToTensor()\n])\n\ndata_transform_soft = transforms.Compose([\n    transforms.Resize((config['image_size'], config['image_size'])),\n    transforms.RandomHorizontalFlip(),\n    transforms.ToTensor()\n])\n\ndata_transform_medium = transforms.Compose([\n    transforms.Resize((config['image_size'], config['image_size'])),\n    transforms.RandomHorizontalFlip(),\n    transforms.ColorJitter(),\n    transforms.ToTensor()\n])\n\ntrain_dataset = CatDogDataset(train_dir, train_df, transform = data_transform_medium)\nval_dataset = CatDogDataset(train_dir, val_df, transform = data_transform_none)\ntest_dataset = CatDogDataset(train_dir, test_df, transform = data_transform_none)","metadata":{"execution":{"iopub.status.busy":"2022-12-09T22:32:11.387453Z","iopub.execute_input":"2022-12-09T22:32:11.389656Z","iopub.status.idle":"2022-12-09T22:32:11.401161Z","shell.execute_reply.started":"2022-12-09T22:32:11.389598Z","shell.execute_reply":"2022-12-09T22:32:11.400101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# In general seed PyTorch operations\ntorch.manual_seed(config['seed'])\n# If you are using CUDA on 1 GPU, seed it\ntorch.cuda.manual_seed(config['seed'])\n# If you are using CUDA on more than 1 GPU, seed them all\ntorch.cuda.manual_seed_all(config['seed'])\n# Disable the inbuilt cudnn auto-tuner that finds the best algorithm to use for your hardware.\ntorch.backends.cudnn.benchmark = False\n# Certain operations in Cudnn are not deterministic, and this line will force them to behave!\ntorch.backends.cudnn.deterministic = True\n\nrandom.seed(SEED)\nnp.random.seed(SEED)\n\ntrain_dataloader = DataLoader(train_dataset, \n                              batch_size = config['batch_size'], \n                              shuffle=True, \n                              num_workers=0,\n                             )\n\n\nval_dataloader = DataLoader(val_dataset, \n                              batch_size = config['batch_size'], \n                              shuffle=False, \n                              num_workers=0,     \n                           )\n\n\ntest_dataloader = DataLoader(test_dataset, \n                              batch_size = config['batch_size'], \n                              shuffle=False, \n                              num_workers=0,     \n                            )\n","metadata":{"execution":{"iopub.status.busy":"2022-12-09T22:32:11.405165Z","iopub.execute_input":"2022-12-09T22:32:11.407429Z","iopub.status.idle":"2022-12-09T22:32:11.423159Z","shell.execute_reply.started":"2022-12-09T22:32:11.407395Z","shell.execute_reply":"2022-12-09T22:32:11.422096Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"samples, labels = iter(train_dataloader).next()\nplt.figure(figsize=(16,24))\ngrid_imgs = torchvision.utils.make_grid(samples[:24])\nnp_grid_imgs = grid_imgs.numpy()\nplt.imshow(np.transpose(np_grid_imgs, (1,2,0)))","metadata":{"execution":{"iopub.status.busy":"2022-12-09T22:32:11.427939Z","iopub.execute_input":"2022-12-09T22:32:11.430249Z","iopub.status.idle":"2022-12-09T22:32:12.631585Z","shell.execute_reply.started":"2022-12-09T22:32:11.430212Z","shell.execute_reply":"2022-12-09T22:32:12.630375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = 'cuda'\nmodel = models.resnet18(pretrained=True)\n\nnum_ftrs = model.fc.in_features\nmodel.fc = nn.Sequential(\n    nn.Linear(num_ftrs, 2),\n)\n\nmodel = model.to(device)\ncriterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(model.parameters(), lr=config['learning_rate'], amsgrad=True)\nscheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, \n                                                       T_max=(len(train_dataloader.dataset)/config['batch_size'])*config['epochs'], # half period\n                                                       eta_min=1e-5)","metadata":{"execution":{"iopub.status.busy":"2022-12-09T22:32:12.634885Z","iopub.execute_input":"2022-12-09T22:32:12.635890Z","iopub.status.idle":"2022-12-09T22:32:13.182397Z","shell.execute_reply.started":"2022-12-09T22:32:12.635854Z","shell.execute_reply":"2022-12-09T22:32:13.181391Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lrs = []\n\nwandb.watch(model, log_freq=100)\n\nfor epoch in range(config['epochs']):\n    print(f\"Epoch {epoch + 1}/{config['epochs']}\")\n        \n    # Train\n    model.train()\n    y_train_pred = []\n    y_val_pred = []\n    \n    running_loss = 0.0            \n    running_corrects = 0\n            \n    # Iterate over data\n    for samples, labels in (train_dataloader):\n\n        samples, labels = samples.to(device), labels.to(device)\n\n\n        # Zero the parameter gradients\n        optimizer.zero_grad()\n\n        with torch.set_grad_enabled(True):\n            # Forward: Get model outputs and calculate loss\n            output = model(samples)\n            loss_ = criterion(output, labels)\n\n            # Backward: Optimize\n            loss_.backward()\n            optimizer.step()\n            \n            y_train_pred = np.concatenate((y_train_pred, torch.argmax(output, dim=1).to('cpu').numpy()), axis=0)\n        \n        lrs.append(optimizer.param_groups[0][\"lr\"])\n        scheduler.step()\n\n        # statistics\n        running_loss += loss_.item() * samples.size(0)\n        running_corrects += torch.sum(torch.argmax(output, dim=1) == labels.data)\n        \n    loss = running_loss / len(train_dataloader.dataset)\n    acc = running_corrects / len(train_dataloader.dataset)\n    \n    # Validation\n    model.eval()\n    \n    running_loss = 0.0\n    for X_val, y_val in (val_dataloader):\n        X_val, y_val = X_val.to(device), y_val.to(device)\n\n        with torch.no_grad():\n            y_pred = model(X_val)\n            loss = criterion(y_pred, y_val)  \n            y_val_pred = np.concatenate((y_val_pred, torch.argmax(y_pred, dim=1).to('cpu').numpy()), axis=0)\n            \n        # statistics\n        running_loss += loss.item() * X_val.size(0)\n\n    val_loss = running_loss / len(val_dataloader.dataset)\n    val_acc = accuracy_score(val_dataloader.dataset.labels, y_val_pred)\n\n    print(f'Loss: {loss:.4f} Acc: {acc:.4f} Val Loss: {val_loss:.4f} Val Acc: {val_acc:.4f}')\n    wandb.log({\"epoch\" : epoch, \n               \"acc\" : acc, \n               \"loss\" : loss, \n               \"val_acc\" : val_acc, \n               \"val_loss\" : val_loss })  \n\n","metadata":{"execution":{"iopub.status.busy":"2022-12-09T22:32:13.183888Z","iopub.execute_input":"2022-12-09T22:32:13.184641Z","iopub.status.idle":"2022-12-09T22:46:19.366533Z","shell.execute_reply.started":"2022-12-09T22:32:13.184599Z","shell.execute_reply":"2022-12-09T22:46:19.365380Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ax = plt.subplots(1,1, figsize=(12,4))\nax.plot(range(len(lrs)),lrs,  color='black')\n#ax.set_xlim([0, EPOCHS-0.8])\n#ax.set_ylim([0, LEARNING_RATE + 0.0001])\nax.set_xlabel('Steps')\nax.set_ylabel('Learning Rate')\n#ax.set_title(title)\nax.spines['top'].set_visible(False)\nax.spines['right'].set_visible(False)","metadata":{"execution":{"iopub.status.busy":"2022-12-09T22:46:19.367974Z","iopub.execute_input":"2022-12-09T22:46:19.369591Z","iopub.status.idle":"2022-12-09T22:46:19.601259Z","shell.execute_reply.started":"2022-12-09T22:46:19.369534Z","shell.execute_reply":"2022-12-09T22:46:19.600244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Make Predictions","metadata":{}},{"cell_type":"code","source":"# Prediction\nmodel.eval()\ny_test_pred = []\n\nfor X_test, y_test in (test_dataloader):\n    X_test, y_test = X_test.to(device), y_test.to(device)\n\n    with torch.no_grad():\n        y_pred = model(X_test)\n        loss = criterion(y_pred, y_test)  \n        y_test_pred = np.concatenate((y_test_pred, torch.argmax(y_pred, dim=1).to('cpu').numpy()), axis=0)\n        \ntest_df['prediction'] = y_test_pred.astype(int)\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-12-09T22:46:19.602749Z","iopub.execute_input":"2022-12-09T22:46:19.603154Z","iopub.status.idle":"2022-12-09T22:46:52.944991Z","shell.execute_reply.started":"2022-12-09T22:46:19.603116Z","shell.execute_reply":"2022-12-09T22:46:52.944131Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y = test_df['label'].values\ny_pred = test_df['prediction'].values\nprint(accuracy_score(y, y_pred))\n\nwandb.log({\"test_acc\" : accuracy_score(y, y_pred) })  \ncf_matrix = confusion_matrix(y, y_pred)\nsns.heatmap(cf_matrix/np.sum(cf_matrix), annot=True, \n            fmt='.2%', cmap='Blues', vmin=0, vmax=1)\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2022-12-09T22:46:52.949173Z","iopub.execute_input":"2022-12-09T22:46:52.951724Z","iopub.status.idle":"2022-12-09T22:46:53.198398Z","shell.execute_reply.started":"2022-12-09T22:46:52.951687Z","shell.execute_reply":"2022-12-09T22:46:53.197286Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"NUM_SAMPLES = 5\nfig, ax = plt.subplots(1, NUM_SAMPLES, figsize=(20,6))\n\nwrong_predictions = test_df[test_df.label != test_df.prediction].iloc[:NUM_SAMPLES]\n\nfor i, file in enumerate(wrong_predictions.index):\n    image = Image.open('./dataset/train/{}'.format(wrong_predictions.iloc[i].filename))\n    ax[i].imshow(image)\n    ax[i].set_title(f'{wrong_predictions.iloc[i].filename}')\nwandb.log({\"wrong_predictions\": plt})\n\nplt.show()\n\nrun.finish()","metadata":{"execution":{"iopub.status.busy":"2022-12-09T22:46:53.200068Z","iopub.execute_input":"2022-12-09T22:46:53.200418Z","iopub.status.idle":"2022-12-09T22:46:57.117821Z","shell.execute_reply.started":"2022-12-09T22:46:53.200381Z","shell.execute_reply":"2022-12-09T22:46:57.116721Z"},"trusted":true},"execution_count":null,"outputs":[]}]}