{
  "source_file": "0930",
  "source_platform": "研究机构",
  "author": "PyTorch Tutorials",
  "title_listed": "Transfer Learning for Computer Vision Tutorial",
  "keywords": "迁移学习,图像分类,CV",
  "domain": "图像处理",
  "content_type": "教程",
  "is_paid_flag": "否",
  "url": "https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html",
  "publish_date": "持续更新",
  "corpus_stage": "图像处理",
  "notes": "CV 迁移学习",
  "id": "61289ce42707",
  "collected_at": "2026-10-02T16:26:18",
  "title": "Transfer Learning for Computer Vision Tutorial — PyTorch Tutorials 2.14.0+cu130 documentation",
  "body_markdown": "Note\nGo to the end\nto download the full example code.\nTransfer Learning for Computer Vision Tutorial\n#\nCreated On: Mar 24, 2017 | Last Updated: Jan 27, 2025 | Last Verified: Nov 05, 2024\nAuthor\n:\nSasank Chilamkurthy\nIn this tutorial, you will learn how to train a convolutional neural network for\nimage classification using transfer learning. You can read more about the transfer\nlearning at\ncs231n notes\nQuoting these notes,\nIn practice, very few people train an entire Convolutional Network\nfrom scratch (with random initialization), because it is relatively\nrare to have a dataset of sufficient size. Instead, it is common to\npretrain a ConvNet on a very large dataset (e.g. ImageNet, which\ncontains 1.2 million images with 1000 categories), and then use the\nConvNet either as an initialization or a fixed feature extractor for\nthe task of interest.\nThese two major transfer learning scenarios look as follows:\nFinetuning the ConvNet\n: Instead of random initialization, we\ninitialize the network with a pretrained network, like the one that is\ntrained on imagenet 1000 dataset. Rest of the training looks as\nusual.\nConvNet as fixed feature extractor\n: Here, we will freeze the weights\nfor all of the network except that of the final fully connected\nlayer. This last fully connected layer is replaced with a new one\nwith random weights and only this layer is trained.\n# License: BSD\n# Author: Sasank Chilamkurthy\nimport\ntorch\nimport\ntorch.nn\nas\nnn\nimport\ntorch.optim\nas\noptim\nfrom\ntorch.optim\nimport\nlr_scheduler\nimport\ntorch.backends.cudnn\nas\ncudnn\nimport\nnumpy\nas\nnp\nimport\ntorchvision\nfrom\ntorchvision\nimport\ndatasets\n,\nmodels\n,\ntransforms\nimport\nmatplotlib.pyplot\nas\nplt\nimport\ntime\nimport\nos\nfrom\nPIL\nimport\nImage\nfrom\ntempfile\nimport\nTemporaryDirectory\ncudnn\n.\nbenchmark\n=\nTrue\nplt\n.\nion\n()\n# interactive mode\n<contextlib.ExitStack object at 0x7f0a75b86530>\nLoad Data\n#\nWe will use torchvision and torch.utils.data packages for loading the\ndata.\nThe problem we’re going to solve today is to train a model to classify\nants\nand\nbees\n. We have about 120 training images each for ants and bees.\nThere are 75 validation images for each class. Usually, this is a very\nsmall dataset to generalize upon, if trained from scratch. Since we\nare using transfer learning, we should be able to generalize reasonably\nwell.\nThis dataset is a very small subset of imagenet.\nNote\nDownload the data from\nhere\nand extract it to the current directory.\n# Data augmentation and normalization for training\n# Just normalization for validation\ndata_transforms\n=\n{\n'train'\n:\ntransforms\n.\nCompose\n([\ntransforms\n.\nRandomResizedCrop\n(\n224\n),\ntransforms\n.\nRandomHorizontalFlip\n(),\ntransforms\n.\nToTensor\n(),\ntransforms\n.\nNormalize\n([\n0.485\n,\n0.456\n,\n0.406\n],\n[\n0.229\n,\n0.224\n,\n0.225\n])\n]),\n'val'\n:\ntransforms\n.\nCompose\n([\ntransforms\n.\nResize\n(\n256\n),\ntransforms\n.\nCenterCrop\n(\n224\n),\ntransforms\n.\nToTensor\n(),\ntransforms\n.\nNormalize\n([\n0.485\n,\n0.456\n,\n0.406\n],\n[\n0.229\n,\n0.224\n,\n0.225\n])\n]),\n}\ndata_dir\n=\n'data/hymenoptera_data'\nimage_datasets\n=\n{\nx\n:\ndatasets\n.\nImageFolder\n(\nos\n.\npath\n.\njoin\n(\ndata_dir\n,\nx\n),\ndata_transforms\n[\nx\n])\nfor\nx\nin\n[\n'train'\n,\n'val'\n]}\ndataloaders\n=\n{\nx\n:\ntorch\n.\nutils\n.\ndata\n.\nDataLoader\n(\nimage_datasets\n[\nx\n],\nbatch_size\n=\n4\n,\nshuffle\n=\nTrue\n,\nnum_workers\n=\n4\n)\nfor\nx\nin\n[\n'train'\n,\n'val'\n]}\ndataset_sizes\n=\n{\nx\n:\nlen\n(\nimage_datasets\n[\nx\n])\nfor\nx\nin\n[\n'train'\n,\n'val'\n]}\nclass_names\n=\nimage_datasets\n[\n'train'\n]\n.\nclasses\n# We want to be able to train our model on an `accelerator <https://pytorch.org/docs/stable/torch.html#accelerators>`__\n# such as CUDA, MPS, MTIA, or XPU. If the current accelerator is available, we will use it. Otherwise, we use the CPU.\ndevice\n=\ntorch\n.\naccelerator\n.\ncurrent_accelerator\n()\n.\ntype\nif\ntorch\n.\naccelerator\n.\nis_available\n()\nelse\n\"cpu\"\nprint\n(\nf\n\"Using\n{\ndevice\n}\ndevice\"\n)\nUsing cuda device\nVisualize a few images\n#\nLet’s visualize a few training images so as to understand the data\naugmentations.\ndef\nimshow\n(\ninp\n,\ntitle\n=\nNone\n):\n\"\"\"Display image for Tensor.\"\"\"\ninp\n=\ninp\n.\nnumpy\n()\n.\ntranspose\n((\n1\n,\n2\n,\n0\n))\nmean\n=\nnp\n.\narray\n([\n0.485\n,\n0.456\n,\n0.406\n])\nstd\n=\nnp\n.\narray\n([\n0.229\n,\n0.224\n,\n0.225\n])\ninp\n=\nstd\n*\ninp\n+\nmean\ninp\n=\nnp\n.\nclip\n(\ninp\n,\n0\n,\n1\n)\nplt\n.\nimshow\n(\ninp\n)\nif\ntitle\nis\nnot\nNone\n:\nplt\n.\ntitle\n(\ntitle\n)\nplt\n.\npause\n(\n0.001\n)\n# pause a bit so that plots are updated\n# Get a batch of training data\ninputs\n,\nclasses\n=\nnext\n(\niter\n(\ndataloaders\n[\n'train'\n]))\n# Make a grid from batch\nout\n=\ntorchvision\n.\nutils\n.\nmake_grid\n(\ninputs\n)\nimshow\n(\nout\n,\ntitle\n=\n[\nclass_names\n[\nx\n]\nfor\nx\nin\nclasses\n])\nTraining the model\n#\nNow, let’s write a general function to train a model. Here, we will\nillustrate:\nScheduling the learning rate\nSaving the best model\nIn the following, parameter\nscheduler\nis an LR scheduler object from\ntorch.optim.lr_scheduler\n.\ndef\ntrain_model\n(\nmodel\n,\ncriterion\n,\noptimizer\n,\nscheduler\n,\nnum_epochs\n=\n25\n):\nsince\n=\ntime\n.\ntime\n()\n# Create a temporary directory to save training checkpoints\nwith\nTemporaryDirectory\n()\nas\ntempdir\n:\nbest_model_params_path\n=\nos\n.\npath\n.\njoin\n(\ntempdir\n,\n'best_model_params.pt'\n)\ntorch\n.\nsave\n(\nmodel\n.\nstate_dict\n(),\nbest_model_params_path\n)\nbest_acc\n=\n0.0\nfor\nepoch\nin\nrange\n(\nnum_epochs\n):\nprint\n(\nf\n'Epoch\n{\nepoch\n}\n/\n{\nnum_epochs\n-\n1\n}\n'\n)\nprint\n(\n'-'\n*\n10\n)\n# Each epoch has a training and validation phase\nfor\nphase\nin\n[\n'train'\n,\n'val'\n]:\nif\nphase\n==\n'train'\n:\nmodel\n.\ntrain\n()\n# Set model to training mode\nelse\n:\nmodel\n.\neval\n()\n# Set model to evaluate mode\nrunning_loss\n=\n0.0\nrunning_corrects\n=\n0\n# Iterate over data.\nfor\ninputs\n,\nlabels\nin\ndataloaders\n[\nphase\n]:\ninputs\n=\ninputs\n.\nto\n(\ndevice\n)\nlabels\n=\nlabels\n.\nto\n(\ndevice\n)\n# zero the parameter gradients\noptimizer\n.\nzero_grad\n()\n# forward\n# track history if only in train\nwith\ntorch\n.\nset_grad_enabled\n(\nphase\n==\n'train'\n):\noutputs\n=\nmodel\n(\ninputs\n)\n_\n,\npreds\n=\ntorch\n.\nmax\n(\noutputs\n,\n1\n)\nloss\n=\ncriterion\n(\noutputs\n,\nlabels\n)\n# backward + optimize only if in training phase\nif\nphase\n==\n'train'\n:\nloss\n.\nbackward\n()\noptimizer\n.\nstep\n()\n# statistics\nrunning_loss\n+=\nloss\n.\nitem\n()\n*\ninputs\n.\nsize\n(\n0\n)\nrunning_corrects\n+=\ntorch\n.\nsum\n(\npreds\n==\nlabels\n.\ndata\n)\nif\nphase\n==\n'train'\n:\nscheduler\n.\nstep\n()\nepoch_loss\n=\nrunning_loss\n/\ndataset_sizes\n[\nphase\n]\nepoch_acc\n=\nrunning_corrects\n.\ndouble\n()\n/\ndataset_sizes\n[\nphase\n]\nprint\n(\nf\n'\n{\nphase\n}\nLoss:\n{\nepoch_loss\n:\n.4f\n}\nAcc:\n{\nepoch_acc\n:\n.4f\n}\n'\n)\n# deep copy the model\nif\nphase\n==\n'val'\nand\nepoch_acc\n>\nbest_acc\n:\nbest_acc\n=\nepoch_acc\ntorch\n.\nsave\n(\nmodel\n.\nstate_dict\n(),\nbest_model_params_path\n)\nprint\n()\ntime_elapsed\n=\ntime\n.\ntime\n()\n-\nsince\nprint\n(\nf\n'Training complete in\n{\ntime_elapsed\n//\n60\n:\n.0f\n}\nm\n{\ntime_elapsed\n%\n60\n:\n.0f\n}\ns'\n)\nprint\n(\nf\n'Best val Acc:\n{\nbest_acc\n:\n4f\n}\n'\n)\n# load best model weights\nmodel\n.\nload_state_dict\n(\ntorch\n.\nload\n(\nbest_model_params_path\n,\nweights_only\n=\nTrue\n))\nreturn\nmodel\nVisualizing the model predictions\n#\nGeneric function to display predictions for a few images\ndef\nvisualize_model\n(\nmodel\n,\nnum_images\n=\n6\n):\nwas_training\n=\nmodel\n.\ntraining\nmodel\n.\neval\n()\nimages_so_far\n=\n0\nfig\n=\nplt\n.\nfigure\n()\nwith\ntorch\n.\nno_grad\n():\nfor\ni\n,\n(\ninputs\n,\nlabels\n)\nin\nenumerate\n(\ndataloaders\n[\n'val'\n]):\ninputs\n=\ninputs\n.\nto\n(\ndevice\n)\nlabels\n=\nlabels\n.\nto\n(\ndevice\n)\noutputs\n=\nmodel\n(\ninputs\n)\n_\n,\npreds\n=\ntorch\n.\nmax\n(\noutputs\n,\n1\n)\nfor\nj\nin\nrange\n(\ninputs\n.\nsize\n()[\n0\n]):\nimages_so_far\n+=\n1\nax\n=\nplt\n.\nsubplot\n(\nnum_images\n//\n2\n,\n2\n,\nimages_so_far\n)\nax\n.\naxis\n(\n'off'\n)\nax\n.\nset_title\n(\nf\n'predicted:\n{\nclass_names\n[\npreds\n[\nj\n]]\n}\n'\n)\nimshow\n(\ninputs\n.\ncpu\n()\n.\ndata\n[\nj\n])\nif\nimages_so_far\n==\nnum_images\n:\nmodel\n.\ntrain\n(\nmode\n=\nwas_training\n)\nreturn\nmodel\n.\ntrain\n(\nmode\n=\nwas_training\n)\nFinetuning the ConvNet\n#\nLoad a pretrained model and reset final fully connected layer.\nmodel_ft\n=\nmodels\n.\nresnet18\n(\nweights\n=\n'IMAGENET1K_V1'\n)\nnum_ftrs\n=\nmodel_ft\n.\nfc\n.\nin_features\n# Here the size of each output sample is set to 2.\n# Alternatively, it can be generalized to ``nn.Linear(num_ftrs, len(class_names))``.\nmodel_ft\n.\nfc\n=\nnn\n.\nLinear\n(\nnum_ftrs\n,\n2\n)\nmodel_ft\n=\nmodel_ft\n.\nto\n(\ndevice\n)\ncriterion\n=\nnn\n.\nCrossEntropyLoss\n()\n# Observe that all parameters are being optimized\noptimizer_ft\n=\noptim\n.\nSGD\n(\nmodel_ft\n.\nparameters\n(),\nlr\n=\n0.001\n,\nmomentum\n=\n0.9\n)\n# Decay LR by a factor of 0.1 every 7 epochs\nexp_lr_scheduler\n=\nlr_scheduler\n.\nStepLR\n(\noptimizer_ft\n,\nstep_size\n=\n7\n,\ngamma\n=\n0.1\n)\nDownloading: \"https://download.pytorch.org/models/resnet18-f37072fd.pth\" to /var/lib/ci-user/.cache/torch/hub/checkpoints/resnet18-f37072fd.pth\n\n  0%|          | 0.00/44.7M [00:00<?, ?B/s]\n 82%|████████▏ | 36.8M/44.7M [00:00<00:00, 385MB/s]\n100%|██████████| 44.7M/44.7M [00:00<00:00, 392MB/s]\nTrain and evaluate\n#\nIt should take around 15-25 min on CPU. On GPU though, it takes less than a\nminute.\nmodel_ft\n=\ntrain_model\n(\nmodel_ft\n,\ncriterion\n,\noptimizer_ft\n,\nexp_lr_scheduler\n,\nnum_epochs\n=\n25\n)\nEpoch 0/24\n----------\ntrain Loss: 0.5205 Acc: 0.7459\nval Loss: 0.2264 Acc: 0.9346\n\nEpoch 1/24\n----------\ntrain Loss: 0.6626 Acc: 0.7664\nval Loss: 0.1903 Acc: 0.9412\n\nEpoch 2/24\n----------\ntrain Loss: 0.5609 Acc: 0.7787\nval Loss: 0.3774 Acc: 0.8758\n\nEpoch 3/24\n----------\ntrain Loss: 0.7814 Acc: 0.7500\nval Loss: 0.2727 Acc: 0.9020\n\nEpoch 4/24\n----------\ntrain Loss: 0.6930 Acc: 0.7459\nval Loss: 0.3126 Acc: 0.9216\n\nEpoch 5/24\n----------\ntrain Loss: 0.4284 Acc: 0.7951\nval Loss: 0.5403 Acc: 0.8497\n\nEpoch 6/24\n----------\ntrain Loss: 0.5188 Acc: 0.8033\nval Loss: 0.2928 Acc: 0.9085\n\nEpoch 7/24\n----------\ntrain Loss: 0.3480 Acc: 0.8525\nval Loss: 0.2384 Acc: 0.9216\n\nEpoch 8/24\n----------\ntrain Loss: 0.2616 Acc: 0.8934\nval Loss: 0.2462 Acc: 0.9477\n\nEpoch 9/24\n----------\ntrain Loss: 0.2707 Acc: 0.8689\nval Loss: 0.2243 Acc: 0.9477\n\nEpoch 10/24\n----------\ntrain Loss: 0.3472 Acc: 0.8525\nval Loss: 0.2290 Acc: 0.9281\n\nEpoch 11/24\n----------\ntrain Loss: 0.3364 Acc: 0.8525\nval Loss: 0.2171 Acc: 0.9346\n\nEpoch 12/24\n----------\ntrain Loss: 0.2545 Acc: 0.8934\nval Loss: 0.2192 Acc: 0.9412\n\nEpoch 13/24\n----------\ntrain Loss: 0.2924 Acc: 0.8566\nval Loss: 0.2536 Acc: 0.9281\n\nEpoch 14/24\n----------\ntrain Loss: 0.3376 Acc: 0.8525\nval Loss: 0.2309 Acc: 0.9412\n\nEpoch 15/24\n----------\ntrain Loss: 0.2256 Acc: 0.9098\nval Loss: 0.2390 Acc: 0.9216\n\nEpoch 16/24\n----------\ntrain Loss: 0.3108 Acc: 0.8525\nval Loss: 0.2411 Acc: 0.9346\n\nEpoch 17/24\n----------\ntrain Loss: 0.2519 Acc: 0.8893\nval Loss: 0.2426 Acc: 0.9281\n\nEpoch 18/24\n----------\ntrain Loss: 0.2091 Acc: 0.9262\nval Loss: 0.2414 Acc: 0.9346\n\nEpoch 19/24\n----------\ntrain Loss: 0.1760 Acc: 0.9385\nval Loss: 0.2335 Acc: 0.9346\n\nEpoch 20/24\n----------\ntrain Loss: 0.2554 Acc: 0.9057\nval Loss: 0.2307 Acc: 0.9412\n\nEpoch 21/24\n----------\ntrain Loss: 0.2806 Acc: 0.8811\nval Loss: 0.2672 Acc: 0.9216\n\nEpoch 22/24\n----------\ntrain Loss: 0.2358 Acc: 0.9221\nval Loss: 0.2293 Acc: 0.9281\n\nEpoch 23/24\n----------\ntrain Loss: 0.3191 Acc: 0.8730\nval Loss: 0.2418 Acc: 0.9216\n\nEpoch 24/24\n----------\ntrain Loss: 0.1808 Acc: 0.9221\nval Loss: 0.2293 Acc: 0.9346\n\nTraining complete in 0m 37s\nBest val Acc: 0.947712\nvisualize_model\n(\nmodel_ft\n)\nConvNet as fixed feature extractor\n#\nHere, we need to freeze all the network except the final layer. We need\nto set\nrequires_grad\n=\nFalse\nto freeze the parameters so that the\ngradients are not computed in\nbackward()\n.\nYou can read more about this in the documentation\nhere\n.\nmodel_conv\n=\ntorchvision\n.\nmodels\n.\nresnet18\n(\nweights\n=\n'IMAGENET1K_V1'\n)\nfor\nparam\nin\nmodel_conv\n.\nparameters\n():\nparam\n.\nrequires_grad\n=\nFalse\n# Parameters of newly constructed modules have requires_grad=True by default\nnum_ftrs\n=\nmodel_conv\n.\nfc\n.\nin_features\nmodel_conv\n.\nfc\n=\nnn\n.\nLinear\n(\nnum_ftrs\n,\n2\n)\nmodel_conv\n=\nmodel_conv\n.\nto\n(\ndevice\n)\ncriterion\n=\nnn\n.\nCrossEntropyLoss\n()\n# Observe that only parameters of final layer are being optimized as\n# opposed to before.\noptimizer_conv\n=\noptim\n.\nSGD\n(\nmodel_conv\n.\nfc\n.\nparameters\n(),\nlr\n=\n0.001\n,\nmomentum\n=\n0.9\n)\n# Decay LR by a factor of 0.1 every 7 epochs\nexp_lr_scheduler\n=\nlr_scheduler\n.\nStepLR\n(\noptimizer_conv\n,\nstep_size\n=\n7\n,\ngamma\n=\n0.1\n)\nTrain and evaluate\n#\nOn CPU this will take about half the time compared to previous scenario.\nThis is expected as gradients don’t need to be computed for most of the\nnetwork. However, forward does need to be computed.\nmodel_conv\n=\ntrain_model\n(\nmodel_conv\n,\ncriterion\n,\noptimizer_conv\n,\nexp_lr_scheduler\n,\nnum_epochs\n=\n25\n)\nEpoch 0/24\n----------\ntrain Loss: 0.6425 Acc: 0.6557\nval Loss: 0.2534 Acc: 0.9216\n\nEpoch 1/24\n----------\ntrain Loss: 0.4432 Acc: 0.7910\nval Loss: 0.2115 Acc: 0.9346\n\nEpoch 2/24\n----------\ntrain Loss: 0.4601 Acc: 0.7910\nval Loss: 0.2607 Acc: 0.9085\n\nEpoch 3/24\n----------\ntrain Loss: 0.4369 Acc: 0.8115\nval Loss: 0.1869 Acc: 0.9477\n\nEpoch 4/24\n----------\ntrain Loss: 0.5486 Acc: 0.7705\nval Loss: 0.1862 Acc: 0.9477\n\nEpoch 5/24\n----------\ntrain Loss: 0.5443 Acc: 0.7582\nval Loss: 0.1941 Acc: 0.9346\n\nEpoch 6/24\n----------\ntrain Loss: 0.4544 Acc: 0.8238\nval Loss: 0.2137 Acc: 0.9281\n\nEpoch 7/24\n----------\ntrain Loss: 0.3578 Acc: 0.8484\nval Loss: 0.1795 Acc: 0.9477\n\nEpoch 8/24\n----------\ntrain Loss: 0.3237 Acc: 0.8607\nval Loss: 0.2263 Acc: 0.9216\n\nEpoch 9/24\n----------\ntrain Loss: 0.3785 Acc: 0.8197\nval Loss: 0.2008 Acc: 0.9281\n\nEpoch 10/24\n----------\ntrain Loss: 0.4293 Acc: 0.8033\nval Loss: 0.1791 Acc: 0.9477\n\nEpoch 11/24\n----------\ntrain Loss: 0.3794 Acc: 0.8115\nval Loss: 0.1876 Acc: 0.9412\n\nEpoch 12/24\n----------\ntrain Loss: 0.3922 Acc: 0.7951\nval Loss: 0.1922 Acc: 0.9281\n\nEpoch 13/24\n----------\ntrain Loss: 0.4501 Acc: 0.7910\nval Loss: 0.1799 Acc: 0.9412\n\nEpoch 14/24\n----------\ntrain Loss: 0.3923 Acc: 0.8279\nval Loss: 0.1772 Acc: 0.9477\n\nEpoch 15/24\n----------\ntrain Loss: 0.3802 Acc: 0.7992\nval Loss: 0.1963 Acc: 0.9412\n\nEpoch 16/24\n----------\ntrain Loss: 0.3290 Acc: 0.8484\nval Loss: 0.1803 Acc: 0.9346\n\nEpoch 17/24\n----------\ntrain Loss: 0.3138 Acc: 0.8607\nval Loss: 0.1835 Acc: 0.9412\n\nEpoch 18/24\n----------\ntrain Loss: 0.3473 Acc: 0.8648\nval Loss: 0.2228 Acc: 0.9216\n\nEpoch 19/24\n----------\ntrain Loss: 0.3194 Acc: 0.8893\nval Loss: 0.2135 Acc: 0.9477\n\nEpoch 20/24\n----------\ntrain Loss: 0.3600 Acc: 0.8525\nval Loss: 0.1900 Acc: 0.9477\n\nEpoch 21/24\n----------\ntrain Loss: 0.3843 Acc: 0.8443\nval Loss: 0.2042 Acc: 0.9281\n\nEpoch 22/24\n----------\ntrain Loss: 0.3638 Acc: 0.8443\nval Loss: 0.1995 Acc: 0.9281\n\nEpoch 23/24\n----------\ntrain Loss: 0.2802 Acc: 0.8770\nval Loss: 0.2017 Acc: 0.9346\n\nEpoch 24/24\n----------\ntrain Loss: 0.4518 Acc: 0.8156\nval Loss: 0.2125 Acc: 0.9216\n\nTraining complete in 0m 28s\nBest val Acc: 0.947712\nvisualize_model\n(\nmodel_conv\n)\nplt\n.\nioff\n()\nplt\n.\nshow\n()\nInference on custom images\n#\nUse the trained model to make predictions on custom images and visualize\nthe predicted class labels along with the images.\ndef\nvisualize_model_predictions\n(\nmodel\n,\nimg_path\n):\nwas_training\n=\nmodel\n.\ntraining\nmodel\n.\neval\n()\nimg\n=\nImage\n.\nopen\n(\nimg_path\n)\nimg\n=\ndata_transforms\n[\n'val'\n](\nimg\n)\nimg\n=\nimg\n.\nunsqueeze\n(\n0\n)\nimg\n=\nimg\n.\nto\n(\ndevice\n)\nwith\ntorch\n.\nno_grad\n():\noutputs\n=\nmodel\n(\nimg\n)\n_\n,\npreds\n=\ntorch\n.\nmax\n(\noutputs\n,\n1\n)\nax\n=\nplt\n.\nsubplot\n(\n2\n,\n2\n,\n1\n)\nax\n.\naxis\n(\n'off'\n)\nax\n.\nset_title\n(\nf\n'Predicted:\n{\nclass_names\n[\npreds\n[\n0\n]]\n}\n'\n)\nimshow\n(\nimg\n.\ncpu\n()\n.\ndata\n[\n0\n])\nmodel\n.\ntrain\n(\nmode\n=\nwas_training\n)\nvisualize_model_predictions\n(\nmodel_conv\n,\nimg_path\n=\n'data/hymenoptera_data/val/bees/72100438_73de9f17af.jpg'\n)\nplt\n.\nioff\n()\nplt\n.\nshow\n()\nFurther Learning\n#\nIf you would like to learn more about the applications of transfer learning,\ncheckout our\nQuantized Transfer Learning for Computer Vision Tutorial\n.\nTotal running time of the script:\n(1 minutes 7.408 seconds)\nDownload\nJupyter\nnotebook:\ntransfer_learning_tutorial.ipynb\nDownload\nPython\nsource\ncode:\ntransfer_learning_tutorial.py\nDownload\nzipped:\ntransfer_learning_tutorial.zip",
  "metadata": {
    "title": "Transfer Learning for Computer Vision Tutorial — PyTorch Tutorials 2.14.0+cu130 documentation",
    "description": null,
    "keywords": null,
    "author": null,
    "og:image": "https://docs.pytorch.org/docs/stable/_static/img/pytorch_seo.png",
    "article:modified_time": "2022-07-20T23:02:43+00:00"
  },
  "paywall": {
    "listed_paid": false,
    "detected": false,
    "marker": "",
    "public_only": false,
    "policy": "付费/会员内容只保留页面公开可见部分，不绕过付费墙"
  },
  "crawl": {
    "success": true,
    "status_code": 200,
    "error": ""
  },
  "code_blocks": [
    {
      "file": "attachments/61289ce42707/code/body-000.txt",
      "chars": 445,
      "language": "text"
    },
    {
      "file": "attachments/61289ce42707/code/body-001.txt",
      "chars": 48,
      "language": "text"
    },
    {
      "file": "attachments/61289ce42707/code/body-002.txt",
      "chars": 1453,
      "language": "text"
    },
    {
      "file": "attachments/61289ce42707/code/body-003.txt",
      "chars": 18,
      "language": "text"
    },
    {
      "file": "attachments/61289ce42707/code/body-004.txt",
      "chars": 588,
      "language": "text"
    },
    {
      "file": "attachments/61289ce42707/code/body-005.txt",
      "chars": 2681,
      "language": "text"
    },
    {
      "file": "attachments/61289ce42707/code/body-006.txt",
      "chars": 849,
      "language": "text"
    },
    {
      "file": "attachments/61289ce42707/code/body-007.txt",
      "chars": 573,
      "language": "text"
    },
    {
      "file": "attachments/61289ce42707/code/body-008.txt",
      "chars": 293,
      "language": "text"
    },
    {
      "file": "attachments/61289ce42707/code/body-009.txt",
      "chars": 114,
      "language": "text"
    },
    {
      "file": "attachments/61289ce42707/code/body-010.txt",
      "chars": 2141,
      "language": "text"
    },
    {
      "file": "attachments/61289ce42707/code/body-011.txt",
      "chars": 26,
      "language": "text"
    },
    {
      "file": "attachments/61289ce42707/code/body-012.txt",
      "chars": 656,
      "language": "text"
    },
    {
      "file": "attachments/61289ce42707/code/body-013.txt",
      "chars": 122,
      "language": "text"
    },
    {
      "file": "attachments/61289ce42707/code/body-014.txt",
      "chars": 2141,
      "language": "text"
    },
    {
      "file": "attachments/61289ce42707/code/body-015.txt",
      "chars": 51,
      "language": "text"
    },
    {
      "file": "attachments/61289ce42707/code/body-016.txt",
      "chars": 509,
      "language": "text"
    },
    {
      "file": "attachments/61289ce42707/code/body-017.txt",
      "chars": 140,
      "language": "text"
    }
  ],
  "images": [
    {
      "status": "ok",
      "url": "https://docs.pytorch.org/tutorials/_images/sphx_glr_transfer_learning_tutorial_001.png",
      "bytes": 152590,
      "reused": false,
      "local_path": "attachments/61289ce42707/images/body-b3f270de957d7893b964.png",
      "src": "https://docs.pytorch.org/tutorials/_images/sphx_glr_transfer_learning_tutorial_001.png",
      "alt": "['bees', 'bees', 'bees', 'bees']",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://docs.pytorch.org/tutorials/_images/sphx_glr_transfer_learning_tutorial_002.png",
      "bytes": 170890,
      "reused": false,
      "local_path": "attachments/61289ce42707/images/body-4a083d1f3076b2367fbc.png",
      "src": "https://docs.pytorch.org/tutorials/_images/sphx_glr_transfer_learning_tutorial_002.png",
      "alt": "predicted: bees, predicted: ants, predicted: bees, predicted: ants, predicted: ants, predicted: ants",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://docs.pytorch.org/tutorials/_images/sphx_glr_transfer_learning_tutorial_003.png",
      "bytes": 174278,
      "reused": false,
      "local_path": "attachments/61289ce42707/images/body-2e11273ed1cbc3b3154b.png",
      "src": "https://docs.pytorch.org/tutorials/_images/sphx_glr_transfer_learning_tutorial_003.png",
      "alt": "predicted: ants, predicted: bees, predicted: ants, predicted: bees, predicted: ants, predicted: bees",
      "downloaded": true
    },
    {
      "status": "ok",
      "url": "https://docs.pytorch.org/tutorials/_images/sphx_glr_transfer_learning_tutorial_004.png",
      "bytes": 75090,
      "reused": false,
      "local_path": "attachments/61289ce42707/images/body-2e30b49e5b6574c6dc3a.png",
      "src": "https://docs.pytorch.org/tutorials/_images/sphx_glr_transfer_learning_tutorial_004.png",
      "alt": "Predicted: bees",
      "downloaded": true
    }
  ],
  "audio": [],
  "videos": [],
  "links": [
    {
      "href": "https://chsasank.github.io/",
      "label": "Sasank Chilamkurthy",
      "type": "a"
    },
    {
      "href": "https://cs231n.github.io/transfer-learning/",
      "label": "cs231n notes",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/backends.html",
      "label": "cudnn . benchmark",
      "type": "a"
    },
    {
      "href": "https://download.pytorch.org/tutorial/hymenoptera_data.zip",
      "label": "here",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/vision/stable/generated/torchvision.transforms.Compose.html",
      "label": "transforms . Compose",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/vision/stable/generated/torchvision.transforms.RandomResizedCrop.html",
      "label": "transforms . RandomResizedCrop",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/vision/stable/generated/torchvision.transforms.RandomHorizontalFlip.html",
      "label": "transforms . RandomHorizontalFlip",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/vision/stable/generated/torchvision.transforms.ToTensor.html",
      "label": "transforms . ToTensor",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/vision/stable/generated/torchvision.transforms.Normalize.html",
      "label": "transforms . Normalize",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/vision/stable/generated/torchvision.transforms.Resize.html",
      "label": "transforms . Resize",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/vision/stable/generated/torchvision.transforms.CenterCrop.html",
      "label": "transforms . CenterCrop",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/vision/stable/generated/torchvision.datasets.ImageFolder.html",
      "label": "datasets . ImageFolder",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/data.html",
      "label": "torch . utils . data . DataLoader",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/tensors.html",
      "label": "classes",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.accelerator.current_accelerator.html",
      "label": "torch . accelerator . current_accelerator",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.accelerator.is_available.html",
      "label": "torch . accelerator . is_available",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/vision/stable/generated/torchvision.utils.make_grid.html",
      "label": "torchvision . utils . make_grid",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html",
      "label": "criterion",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.save.html",
      "label": "torch . save",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.autograd.grad_mode.set_grad_enabled.html",
      "label": "torch . set_grad_enabled",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.max.html",
      "label": "torch . max",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.sum.html",
      "label": "torch . sum",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.load.html",
      "label": "torch . load",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.no_grad.html",
      "label": "torch . no_grad",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/vision/stable/models/generated/torchvision.models.resnet18.html",
      "label": "models . resnet18",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.nn.Linear.html",
      "label": "model_ft . fc",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.nn.Module.html",
      "label": "model_ft . to",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.optim.SGD.html",
      "label": "optimizer_ft",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.optim.lr_scheduler.StepLR.html",
      "label": "exp_lr_scheduler",
      "type": "a"
    },
    {
      "href": "https://pytorch.org/docs/notes/autograd.html",
      "label": "here",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/docs/stable/generated/torch.nn.parameter.Parameter.html",
      "label": "param",
      "type": "a"
    },
    {
      "href": "https://pytorch.org/tutorials/intermediate/quantized_transfer_learning_tutorial.html",
      "label": "Quantized Transfer Learning for Computer Vision Tutorial",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/tutorials/_downloads/74249e7f9f1f398f57ccd094a4f3021b/transfer_learning_tutorial.ipynb",
      "label": "Download Jupyter notebook: transfer_learning_tutorial.ipynb",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/tutorials/_downloads/d923ca53b1bfbeb3c222ae46d65d485e/transfer_learning_tutorial.py",
      "label": "Download Python source code: transfer_learning_tutorial.py",
      "type": "a"
    },
    {
      "href": "https://docs.pytorch.org/tutorials/_downloads/1baf319766772c6431fef590c87c2d3f/transfer_learning_tutorial.zip",
      "label": "Download zipped: transfer_learning_tutorial.zip",
      "type": "a"
    }
  ],
  "repair_version": 2,
  "repaired_at": "2026-10-14T10:53:55Z",
  "source_url": "https://pytorch.org/tutorials/beginner/transfer_learning_tutorial.html",
  "papers": [],
  "actual_video_files": [],
  "body_chars": 15741,
  "expected_body_images": 4,
  "discovery_status": "ok",
  "delivery_status": "ok",
  "missing_reason": "",
  "raw_html": "attachments/61289ce42707/pages/source.html",
  "local_html": "attachments/61289ce42707/pages/article.html",
  "body_base_path": "attachments/61289ce42707/pages/",
  "body_markdown_path": "attachments/61289ce42707/pages/article.md"
}