{"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":"import torch\nimport torch.nn as nn\nfrom torchvision import datasets ,models,transforms\nfrom torch.utils.data.sampler import SubsetRandomSampler\nfrom torch.optim import lr_scheduler\nfrom pathlib import Path\nfrom matplotlib import pyplot as plt\nimport numpy as np\nfrom io import BytesIO\nfrom zipfile import ZipFile\nimport matplotlib.pyplot as plt\n%matplotlib inline","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-04-15T14:15:14.364725Z","iopub.execute_input":"2023-04-15T14:15:14.365655Z","iopub.status.idle":"2023-04-15T14:15:17.361486Z","shell.execute_reply.started":"2023-04-15T14:15:14.365616Z","shell.execute_reply":"2023-04-15T14:15:17.360322Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_on_gpu = torch.cuda.is_available()\n\nif not train_on_gpu:\n    print('CUDA is not available.  Training on CPU ...')\nelse:\n    print('CUDA is available!  Training on GPU ...')\n    \ndata_transforms = transforms.Compose([transforms.Resize((224,224)), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])  \n\nnum_workers = 0\nbatch_size = 32\n  \nDATA = Path('/kaggle/input/cats-and-dogs/train')\ndata = datasets.ImageFolder(DATA, transform=data_transforms)\nfull_data_size = len(data)\nprint(\"总数据集的长度为：{}\".format(full_data_size))","metadata":{"execution":{"iopub.status.busy":"2023-04-15T14:15:22.54015Z","iopub.execute_input":"2023-04-15T14:15:22.540893Z","iopub.status.idle":"2023-04-15T14:15:42.108903Z","shell.execute_reply.started":"2023-04-15T14:15:22.540845Z","shell.execute_reply":"2023-04-15T14:15:42.107649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_size = int(0.8 * len(data))\nval_size = int(0.2 * len(data))\ntrain_data, val_data = torch.utils.data.random_split(data, [train_size, val_size])\ntrain_data_size = len(train_data)\nval_data_size = len(val_data)\n# 如果train_data_size=10, 训练数据集的长度为：10\nprint(\"训练数据集的长度为：{}\".format(train_data_size))\nprint(\"验证数据集的长度为：{}\".format(val_data_size))","metadata":{"execution":{"iopub.status.busy":"2023-04-15T14:16:27.803191Z","iopub.execute_input":"2023-04-15T14:16:27.803683Z","iopub.status.idle":"2023-04-15T14:16:27.842669Z","shell.execute_reply.started":"2023-04-15T14:16:27.803641Z","shell.execute_reply":"2023-04-15T14:16:27.841586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size, num_workers=num_workers,shuffle=True)\nval_loader = torch.utils.data.DataLoader(val_data, batch_size=batch_size,  num_workers=num_workers,shuffle=True)\nimages, labels = next(iter(train_loader))\nprint(images.shape)\nprint(labels.shape)","metadata":{"execution":{"iopub.status.busy":"2023-04-15T14:16:29.809788Z","iopub.execute_input":"2023-04-15T14:16:29.81016Z","iopub.status.idle":"2023-04-15T14:16:30.35628Z","shell.execute_reply.started":"2023-04-15T14:16:29.810128Z","shell.execute_reply":"2023-04-15T14:16:30.355211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"classes = ['cat','dog']\nmean , std = torch.tensor([0.485, 0.456, 0.406]),torch.tensor([0.229, 0.224, 0.225])","metadata":{"execution":{"iopub.status.busy":"2023-04-15T14:16:32.10061Z","iopub.execute_input":"2023-04-15T14:16:32.100976Z","iopub.status.idle":"2023-04-15T14:16:32.106675Z","shell.execute_reply.started":"2023-04-15T14:16:32.100943Z","shell.execute_reply":"2023-04-15T14:16:32.105518Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def denormalize(image):\n    image = transforms.Normalize(-mean/std,1/std)(image) #denormalize\n    image = image.permute(1,2,0) #Changing from 3x224x224 to 224x224x3\n    image = torch.clamp(image,0,1)\n    return image\n\n# helper function to un-normalize and display an image\ndef imshow(img):\n    img = denormalize(img) \n    plt.imshow(img)\n    \n\ndataiter = iter(train_loader)\nimages, labels = dataiter.__next__()","metadata":{"execution":{"iopub.status.busy":"2023-04-15T14:16:34.033945Z","iopub.execute_input":"2023-04-15T14:16:34.034468Z","iopub.status.idle":"2023-04-15T14:16:34.459303Z","shell.execute_reply.started":"2023-04-15T14:16:34.034424Z","shell.execute_reply":"2023-04-15T14:16:34.458145Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = plt.figure(figsize=(25, 8))\n# display 20 images\nfor idx in np.arange(20):\n    ax = fig.add_subplot(2, 10, idx+1, xticks=[], yticks=[])\n    imshow(images[idx])\n    ax.set_title(\"{} \".format(classes[labels[idx]]))\n\nplt.show()    \nvgg_19=models.vgg19_bn(pretrained=True)\n\nfor param in vgg_19.parameters():\n    param.requires_grad = False\n\nfrom collections import OrderedDict\nclassifier = nn.Sequential(OrderedDict([('fc1', nn.Linear(25088, 1028)), ('relu1', nn.ReLU()),('dropout1',nn.Dropout(0.5)), ('fc2', nn.Linear(1028, 512)), ('relu2', nn.ReLU()), \n ('dropout2',nn.Dropout(0.5)), ('fc3', nn.Linear(512, 2)), ('output', nn.LogSoftmax(dim=1))]))\n    \nvgg_19.classifier = classifier\ncriterion = nn.CrossEntropyLoss()\noptimizer = torch.optim.Adam(vgg_19.parameters(),lr=0.001)","metadata":{"execution":{"iopub.status.busy":"2023-04-15T14:16:36.915289Z","iopub.execute_input":"2023-04-15T14:16:36.915773Z","iopub.status.idle":"2023-04-15T14:16:43.994903Z","shell.execute_reply.started":"2023-04-15T14:16:36.915731Z","shell.execute_reply":"2023-04-15T14:16:43.993857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if train_on_gpu:\n    vgg_19.cuda()\n# number of epochs to train the model\nn_epochs = 10\n\nvalid_loss_min = np.Inf # track change in validation loss\n\n#train_losses,valid_losses=[],[]\n\nfor epoch in range(1, n_epochs+1):\n\n    # keep track of training and validation loss\n    train_loss = 0.0\n    valid_loss = 0.0\n    \n    ###################\n    # train the model #\n    ###################\n    vgg_19.train()\n    for data, target in train_loader:\n        # move tensors to GPU if CUDA is available\n        if train_on_gpu:\n            data, target = data.cuda(), target.cuda()\n        # clear the gradients of all optimized variables\n        optimizer.zero_grad()\n        # forward pass: compute predicted outputs by passing inputs to the model\n        output = vgg_19(data)\n        # calculate the batch loss\n        loss = criterion(output, target)\n        # backward pass: compute gradient of the loss with respect to model parameters\n        loss.backward()\n        # perform a single optimization step (parameter update)\n        optimizer.step()\n        # update training loss\n        train_loss += loss.item()*data.size(0)\n        \n    ######################    \n    # validate the model #\n    ######################\n    vgg_19.eval()\n    for data, target in val_loader:\n        # move tensors to GPU if CUDA is available\n        if train_on_gpu:\n            data, target = data.cuda(), target.cuda()\n        # forward pass: compute predicted outputs by passing inputs to the model\n        output = vgg_19(data)\n        # calculate the batch loss\n        loss = criterion(output, target)\n        # update average validation loss \n        valid_loss += loss.item()*data.size(0)\n    \n    # calculate average losses\n    #train_losses.append(train_loss/len(train_loader.dataset))\n    #valid_losses.append(valid_loss.item()/len(val_loader.dataset)\n    train_loss = train_loss/len(train_loader.dataset)\n    valid_loss = valid_loss/len(val_loader.dataset)\n        \n    # print training/validation statistics \n    print('Epoch: {} \\tTraining Loss: {:.6f} \\tValidation Loss: {:.6f}'.format(\n        epoch, train_loss, valid_loss))\n    \n    # save model if validation loss has decreased\n    if valid_loss <= valid_loss_min:\n        print('Validation loss decreased ({:.6f} --> {:.6f}).  Saving model ...'.format(\n        valid_loss_min,\n        valid_loss))\n        torch.save(vgg_19.state_dict(), 'model_vgg19.pth')\n        valid_loss_min = valid_loss","metadata":{"execution":{"iopub.status.busy":"2023-04-15T14:18:23.387205Z","iopub.execute_input":"2023-04-15T14:18:23.388321Z","iopub.status.idle":"2023-04-15T15:12:17.225124Z","shell.execute_reply.started":"2023-04-15T14:18:23.388269Z","shell.execute_reply":"2023-04-15T15:12:17.224082Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_loader = torch.utils.data.DataLoader(val_data, batch_size=batch_size,  num_workers=num_workers,shuffle=True)\nbatch_size=4\n# track test loss\ntest_loss = 0.0\nclass_correct = list(0. for i in range(2))\nclass_total = list(0. for i in range(2))\n\nvgg_19.eval()\n# iterate over valid data\nfor data, target in val_loader:\n    # move tensors to GPU if CUDA is available\n    if train_on_gpu:\n        data, target = data.cuda(), target.cuda()\n    # forward pass: compute predicted outputs by passing inputs to the model\n    output = vgg_19(data)\n    # calculate the batch loss\n    loss = criterion(output, target)\n    # update test loss \n    test_loss += loss.item()*data.size(0)\n    # convert output probabilities to predicted class\n    _, pred = torch.max(output, 1)    \n    # compare predictions to true label\n    correct_tensor = pred.eq(target.data.view_as(pred))\n    correct = np.squeeze(correct_tensor.numpy()) if not train_on_gpu else np.squeeze(correct_tensor.cpu().numpy())\n    # calculate test accuracy for each object class\n    for i in range(batch_size):\n        label = target.data[i]\n        class_correct[label] += correct[i].item()\n        class_total[label] += 1\n\n# average test loss\ntest_loss = test_loss/len(val_loader.dataset)\nprint('Test Loss: {:.6f}\\n'.format(test_loss))\n\nfor i in range(2):\n    if class_total[i] > 0:\n        print('Test Accuracy of %5s: %.2f%% (%2d/%2d)' % (\n            classes[i], 100 * class_correct[i] / class_total[i],\n            np.sum(class_correct[i]), np.sum(class_total[i])))\n    else:\n        print('Test Accuracy of %5s: N/A (no training examples)' % (classes[i]))\n\nprint('\\nTest Accuracy (Overall): %.2f%% (%2d/%2d)' % (\n    100. * np.sum(class_correct) / np.sum(class_total),\n    np.sum(class_correct), np.sum(class_total)))","metadata":{"execution":{"iopub.status.busy":"2023-04-15T15:21:09.074835Z","iopub.execute_input":"2023-04-15T15:21:09.075533Z","iopub.status.idle":"2023-04-15T15:22:14.322336Z","shell.execute_reply.started":"2023-04-15T15:21:09.075493Z","shell.execute_reply":"2023-04-15T15:22:14.321135Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torchvision\n\nresnet = torchvision.models.resnet18(pretrained=True)\nresnet.fc = nn.Sequential(*[\n    nn.Linear(in_features=512, out_features=2),\n    nn.LogSoftmax(dim=1)\n])\noptimizer = torch.optim.Adam(resnet.parameters(),lr=0.001)","metadata":{"execution":{"iopub.status.busy":"2023-04-15T15:23:05.976013Z","iopub.execute_input":"2023-04-15T15:23:05.976407Z","iopub.status.idle":"2023-04-15T15:23:06.875218Z","shell.execute_reply.started":"2023-04-15T15:23:05.976374Z","shell.execute_reply":"2023-04-15T15:23:06.87424Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if train_on_gpu:\n    resnet.cuda()\n# number of epochs to train the model\nn_epochs = 10\n\nvalid_loss_min = np.Inf # track change in validation loss\n\n#train_losses,valid_losses=[],[]\n\nfor epoch in range(1, n_epochs+1):\n\n    # keep track of training and validation loss\n    train_loss = 0.0\n    valid_loss = 0.0\n    \n    ###################\n    # train the model #\n    ###################\n    resnet.train()\n    for data, target in train_loader:\n        # move tensors to GPU if CUDA is available\n        if train_on_gpu:\n            data, target = data.cuda(), target.cuda()\n        # clear the gradients of all optimized variables\n        optimizer.zero_grad()\n        # forward pass: compute predicted outputs by passing inputs to the model\n        output = resnet(data)\n        # calculate the batch loss\n        loss = criterion(output, target)\n        # backward pass: compute gradient of the loss with respect to model parameters\n        loss.backward()\n        # perform a single optimization step (parameter update)\n        optimizer.step()\n        # update training loss\n        train_loss += loss.item()*data.size(0)\n        \n    ######################    \n    # validate the model #\n    ######################\n    resnet.eval()\n    for data, target in val_loader:\n        # move tensors to GPU if CUDA is available\n        if train_on_gpu:\n            data, target = data.cuda(), target.cuda()\n        # forward pass: compute predicted outputs by passing inputs to the model\n        output = resnet(data)\n        # calculate the batch loss\n        loss = criterion(output, target)\n        # update average validation loss \n        valid_loss += loss.item()*data.size(0)\n    \n    # calculate average losses\n    #train_losses.append(train_loss/len(train_loader.dataset))\n    #valid_losses.append(valid_loss.item()/len(val_loader.dataset)\n    train_loss = train_loss/len(train_loader.dataset)\n    valid_loss = valid_loss/len(val_loader.dataset)\n        \n    # print training/validation statistics \n    print('Epoch: {} \\tTraining Loss: {:.6f} \\tValidation Loss: {:.6f}'.format(\n        epoch, train_loss, valid_loss))\n    \n    # save model if validation loss has decreased\n    if valid_loss <= valid_loss_min:\n        print('Validation loss decreased ({:.6f} --> {:.6f}).  Saving model ...'.format(\n        valid_loss_min,\n        valid_loss))\n        torch.save(resnet.state_dict(), 'model_resnet.pth')\n        valid_loss_min = valid_loss","metadata":{"execution":{"iopub.status.busy":"2023-04-15T15:23:09.165143Z","iopub.execute_input":"2023-04-15T15:23:09.165825Z","iopub.status.idle":"2023-04-15T15:58:45.126458Z","shell.execute_reply.started":"2023-04-15T15:23:09.165789Z","shell.execute_reply":"2023-04-15T15:58:45.125264Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_loader = torch.utils.data.DataLoader(val_data, batch_size=batch_size,  num_workers=num_workers,shuffle=True)\nbatch_size=4\n# track test loss\ntest_loss = 0.0\nclass_correct = list(0. for i in range(2))\nclass_total = list(0. for i in range(2))\n\nresnet.eval()\n# iterate over valid data\nfor data, target in val_loader:\n    # move tensors to GPU if CUDA is available\n    if train_on_gpu:\n        data, target = data.cuda(), target.cuda()\n    # forward pass: compute predicted outputs by passing inputs to the model\n    output = resnet(data)\n    # calculate the batch loss\n    loss = criterion(output, target)\n    # update test loss \n    test_loss += loss.item()*data.size(0)\n    # convert output probabilities to predicted class\n    _, pred = torch.max(output, 1)    \n    # compare predictions to true label\n    correct_tensor = pred.eq(target.data.view_as(pred))\n    correct = np.squeeze(correct_tensor.numpy()) if not train_on_gpu else np.squeeze(correct_tensor.cpu().numpy())\n    # calculate test accuracy for each object class\n    for i in range(batch_size):\n        label = target.data[i]\n        class_correct[label] += correct[i].item()\n        class_total[label] += 1\n\n# average test loss\ntest_loss = test_loss/len(val_loader.dataset)\nprint('Test Loss: {:.6f}\\n'.format(test_loss))\n\nfor i in range(2):\n    if class_total[i] > 0:\n        print('Test Accuracy of %5s: %.2f%% (%2d/%2d)' % (\n            classes[i], 100 * class_correct[i] / class_total[i],\n            np.sum(class_correct[i]), np.sum(class_total[i])))\n    else:\n        print('Test Accuracy of %5s: N/A (no training examples)' % (classes[i]))\n\nprint('\\nTest Accuracy (Overall): %.2f%% (%2d/%2d)' % (\n    100. * np.sum(class_correct) / np.sum(class_total),\n    np.sum(class_correct), np.sum(class_total)))","metadata":{"execution":{"iopub.status.busy":"2023-04-15T15:59:52.488999Z","iopub.execute_input":"2023-04-15T15:59:52.4894Z","iopub.status.idle":"2023-04-15T16:00:31.013994Z","shell.execute_reply.started":"2023-04-15T15:59:52.489366Z","shell.execute_reply":"2023-04-15T16:00:31.012659Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"densenet = torchvision.models.densenet121(pretrained=True)\nclassifier1 = nn.Sequential(OrderedDict([('fc1', nn.Linear(1024, 512)), ('relu1', nn.ReLU()), \n ('dropout1',nn.Dropout(0.5)), ('fc2', nn.Linear(512, 2)), ('output', nn.LogSoftmax(dim=1))]))\ndensenet.classifier = classifier1\noptimizer = torch.optim.Adam(densenet.parameters(),lr=0.001)","metadata":{"execution":{"iopub.status.busy":"2023-04-15T16:19:52.665667Z","iopub.execute_input":"2023-04-15T16:19:52.666287Z","iopub.status.idle":"2023-04-15T16:19:52.954714Z","shell.execute_reply.started":"2023-04-15T16:19:52.666235Z","shell.execute_reply":"2023-04-15T16:19:52.953668Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if train_on_gpu:\n    densenet.cuda()\n# number of epochs to train the model\nn_epochs = 10\n\nvalid_loss_min = np.Inf # track change in validation loss\n\n#train_losses,valid_losses=[],[]\n\nfor epoch in range(1, n_epochs+1):\n\n    # keep track of training and validation loss\n    train_loss = 0.0\n    valid_loss = 0.0\n    \n    ###################\n    # train the model #\n    ###################\n    densenet.train()\n    for data, target in train_loader:\n        # move tensors to GPU if CUDA is available\n        if train_on_gpu:\n            data, target = data.cuda(), target.cuda()\n        # clear the gradients of all optimized variables\n        optimizer.zero_grad()\n        # forward pass: compute predicted outputs by passing inputs to the model\n        output = densenet(data)\n        # calculate the batch loss\n        loss = criterion(output, target)\n        # backward pass: compute gradient of the loss with respect to model parameters\n        loss.backward()\n        # perform a single optimization step (parameter update)\n        optimizer.step()\n        # update training loss\n        train_loss += loss.item()*data.size(0)\n        \n    ######################    \n    # validate the model #\n    ######################\n    densenet.eval()\n    for data, target in val_loader:\n        # move tensors to GPU if CUDA is available\n        if train_on_gpu:\n            data, target = data.cuda(), target.cuda()\n        # forward pass: compute predicted outputs by passing inputs to the model\n        output = densenet(data)\n        # calculate the batch loss\n        loss = criterion(output, target)\n        # update average validation loss \n        valid_loss += loss.item()*data.size(0)\n    \n    # calculate average losses\n    #train_losses.append(train_loss/len(train_loader.dataset))\n    #valid_losses.append(valid_loss.item()/len(val_loader.dataset)\n    train_loss = train_loss/len(train_loader.dataset)\n    valid_loss = valid_loss/len(val_loader.dataset)\n        \n    # print training/validation statistics \n    print('Epoch: {} \\tTraining Loss: {:.6f} \\tValidation Loss: {:.6f}'.format(\n        epoch, train_loss, valid_loss))\n    \n    # save model if validation loss has decreased\n    if valid_loss <= valid_loss_min:\n        print('Validation loss decreased ({:.6f} --> {:.6f}).  Saving model ...'.format(\n        valid_loss_min,\n        valid_loss))\n        torch.save(densenet.state_dict(), 'model_densenet.pth')\n        valid_loss_min = valid_loss","metadata":{"execution":{"iopub.status.busy":"2023-04-15T16:19:56.178938Z","iopub.execute_input":"2023-04-15T16:19:56.179353Z","iopub.status.idle":"2023-04-15T17:28:08.99957Z","shell.execute_reply.started":"2023-04-15T16:19:56.179317Z","shell.execute_reply":"2023-04-15T17:28:08.998413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_loader = torch.utils.data.DataLoader(val_data, batch_size=batch_size,  num_workers=num_workers,shuffle=True)\nbatch_size=4\n# track test loss\ntest_loss = 0.0\nclass_correct = list(0. for i in range(2))\nclass_total = list(0. for i in range(2))\n\ndensenet.eval()\n# iterate over valid data\nfor data, target in val_loader:\n    # move tensors to GPU if CUDA is available\n    if train_on_gpu:\n        data, target = data.cuda(), target.cuda()\n    # forward pass: compute predicted outputs by passing inputs to the model\n    output = densenet(data)\n    # calculate the batch loss\n    loss = criterion(output, target)\n    # update test loss \n    test_loss += loss.item()*data.size(0)\n    # convert output probabilities to predicted class\n    _, pred = torch.max(output, 1)    \n    # compare predictions to true label\n    correct_tensor = pred.eq(target.data.view_as(pred))\n    correct = np.squeeze(correct_tensor.numpy()) if not train_on_gpu else np.squeeze(correct_tensor.cpu().numpy())\n    # calculate test accuracy for each object class\n    for i in range(batch_size):\n        label = target.data[i]\n        class_correct[label] += correct[i].item()\n        class_total[label] += 1\n\n# average test loss\ntest_loss = test_loss/len(val_loader.dataset)\nprint('Test Loss: {:.6f}\\n'.format(test_loss))\n\nfor i in range(2):\n    if class_total[i] > 0:\n        print('Test Accuracy of %5s: %.2f%% (%2d/%2d)' % (\n            classes[i], 100 * class_correct[i] / class_total[i],\n            np.sum(class_correct[i]), np.sum(class_total[i])))\n    else:\n        print('Test Accuracy of %5s: N/A (no training examples)' % (classes[i]))\n\nprint('\\nTest Accuracy (Overall): %.2f%% (%2d/%2d)' % (\n    100. * np.sum(class_correct) / np.sum(class_total),\n    np.sum(class_correct), np.sum(class_total)))","metadata":{"execution":{"iopub.status.busy":"2023-04-15T17:29:50.053743Z","iopub.execute_input":"2023-04-15T17:29:50.054114Z","iopub.status.idle":"2023-04-15T17:30:53.601005Z","shell.execute_reply.started":"2023-04-15T17:29:50.054081Z","shell.execute_reply":"2023-04-15T17:30:53.598856Z"},"trusted":true},"execution_count":null,"outputs":[]}]}