From 2f8cadbc42f85be468a83a8f4a466f493714d077 Mon Sep 17 00:00:00 2001
From: Chuan <41295406+caalinlu@users.noreply.github.com>
Date: Wed, 15 May 2019 00:23:30 +0800
Subject: [PATCH 1/4] =?UTF-8?q?=E4=BD=BF=E7=94=A8=20Colaboratory=20?=
=?UTF-8?q?=E5=88=9B=E5=BB=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...346\200\247\345\233\236\345\275\222.ipynb" | 182 ++++++++++++++++++
1 file changed, 182 insertions(+)
create mode 100644 "PyTorch\345\256\236\347\216\260\347\272\277\346\200\247\345\233\236\345\275\222.ipynb"
diff --git "a/PyTorch\345\256\236\347\216\260\347\272\277\346\200\247\345\233\236\345\275\222.ipynb" "b/PyTorch\345\256\236\347\216\260\347\272\277\346\200\247\345\233\236\345\275\222.ipynb"
new file mode 100644
index 0000000..0535336
--- /dev/null
+++ "b/PyTorch\345\256\236\347\216\260\347\272\277\346\200\247\345\233\236\345\275\222.ipynb"
@@ -0,0 +1,182 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "PyTorch实现线性回归.ipynb",
+ "version": "0.3.2",
+ "provenance": [],
+ "collapsed_sections": [],
+ "include_colab_link": true
+ },
+ "kernelspec": {
+ "name": "python3",
+ "display_name": "Python 3"
+ }
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ "
"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5iQMYTB2EqaI",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "source": [
+ "import torch\n",
+ "# print(torch.__version__)\n",
+ "\n",
+ "# train data\n",
+ "x_data = torch.arange(1.0,4.0,1.0)\n",
+ "\n",
+ "# Numpy中的size是元素个数,但是在Pytorch中size等价为Numpy中的shape\n",
+ "# view 可以视作调整数组的size, -1 的作用是用来自动计算在列数确定的情况下行数\n",
+ "x_data = x_data.view(-1, 1)\n",
+ "y_data = torch.arange(2.0, 7.0, 2.0)\n",
+ "y_data = y_data.view(-1, 1)"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "xb9r5NSZG-rg",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "source": [
+ "# 超参数设置\n",
+ "learning_rate = 0.1\n",
+ "num_epoches = 40"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "4JPWaGhVHJ0t",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "source": [
+ "class LinearRegression(torch.nn.Module):\n",
+ " def __init__(self):\n",
+ " super().__init__()\n",
+ " self.linear = torch.nn.Linear(1, 1)\n",
+ " \n",
+ " def forward(self, x):\n",
+ " y_pred = self.linear(x)\n",
+ " return y_pred\n",
+ " \n",
+ "model = LinearRegression()"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "3awwus05H219",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 791
+ },
+ "outputId": "b87e7709-88af-4248-9c1d-293adcf2da6d"
+ },
+ "source": [
+ "\n",
+ "# 定义loss function损失函数\n",
+ "# PyTorch0.4以后,使用reduction参数控制损失函数的输出行为\n",
+ "criterion = torch.nn.MSELoss(reduction='mean')\n",
+ "# nn.Parameter - 张量的一种,当它作为一个属性分配给一个Module时,它会被自动注册为一个参数。\n",
+ "optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)\n",
+ "\n",
+ "\n",
+ "for epoch in range(num_epoches):\n",
+ " \n",
+ " # forward\n",
+ " y_pred = model(x_data)\n",
+ " \n",
+ " # computing loss \n",
+ " loss = criterion(y_pred, y_data)\n",
+ " print(epoch,'epoch\\'s loss:',loss.item())\n",
+ " \n",
+ " # backward:zero gradients + backward + step\n",
+ " optimizer.zero_grad()\n",
+ " loss.backward()\n",
+ " optimizer.step() # 执行梯度下降\n",
+ " \n",
+ " # testing\n",
+ "x_test=torch.Tensor([4.0])\n",
+ "print(\"the result of y when x is 4:\",model(x_test))\n",
+ "print('model.parameter:',list(model.parameters()))"
+ ],
+ "execution_count": 8,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "0 epoch's loss: 16.615921020507812\n",
+ "1 epoch's loss: 0.5019358992576599\n",
+ "2 epoch's loss: 0.29503700137138367\n",
+ "3 epoch's loss: 0.2788357734680176\n",
+ "4 epoch's loss: 0.26556479930877686\n",
+ "5 epoch's loss: 0.25294986367225647\n",
+ "6 epoch's loss: 0.24093462526798248\n",
+ "7 epoch's loss: 0.22949011623859406\n",
+ "8 epoch's loss: 0.21858921647071838\n",
+ "9 epoch's loss: 0.20820589363574982\n",
+ "10 epoch's loss: 0.1983160823583603\n",
+ "11 epoch's loss: 0.18889588117599487\n",
+ "12 epoch's loss: 0.1799231767654419\n",
+ "13 epoch's loss: 0.17137672007083893\n",
+ "14 epoch's loss: 0.16323624551296234\n",
+ "15 epoch's loss: 0.1554822474718094\n",
+ "16 epoch's loss: 0.14809675514698029\n",
+ "17 epoch's loss: 0.14106221497058868\n",
+ "18 epoch's loss: 0.1343616247177124\n",
+ "19 epoch's loss: 0.12797926366329193\n",
+ "20 epoch's loss: 0.12190017849206924\n",
+ "21 epoch's loss: 0.11610981822013855\n",
+ "22 epoch's loss: 0.1105945035815239\n",
+ "23 epoch's loss: 0.10534120351076126\n",
+ "24 epoch's loss: 0.10033739358186722\n",
+ "25 epoch's loss: 0.09557127952575684\n",
+ "26 epoch's loss: 0.09103161841630936\n",
+ "27 epoch's loss: 0.08670753240585327\n",
+ "28 epoch's loss: 0.08258878439664841\n",
+ "29 epoch's loss: 0.07866580039262772\n",
+ "30 epoch's loss: 0.07492917776107788\n",
+ "31 epoch's loss: 0.07136993110179901\n",
+ "32 epoch's loss: 0.06797981262207031\n",
+ "33 epoch's loss: 0.06475075334310532\n",
+ "34 epoch's loss: 0.06167503446340561\n",
+ "35 epoch's loss: 0.058745432645082474\n",
+ "36 epoch's loss: 0.0559549555182457\n",
+ "37 epoch's loss: 0.05329711735248566\n",
+ "38 epoch's loss: 0.05076548829674721\n",
+ "39 epoch's loss: 0.048354025930166245\n",
+ "the result of y when x is 4: tensor([7.5696], grad_fn=)\n",
+ "model.parameter: [Parameter containing:\n",
+ "tensor([[1.7507]], requires_grad=True), Parameter containing:\n",
+ "tensor([0.5666], requires_grad=True)]\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
From 355f664d219acdd6576e5de76e465ae569b0e02a Mon Sep 17 00:00:00 2001
From: Chuan <41295406+caalinlu@users.noreply.github.com>
Date: Wed, 15 May 2019 00:24:10 +0800
Subject: [PATCH 2/4] =?UTF-8?q?Delete=20PyTorch=E5=AE=9E=E7=8E=B0=E7=BA=BF?=
=?UTF-8?q?=E6=80=A7=E5=9B=9E=E5=BD=92.ipynb?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...346\200\247\345\233\236\345\275\222.ipynb" | 182 ------------------
1 file changed, 182 deletions(-)
delete mode 100644 "PyTorch\345\256\236\347\216\260\347\272\277\346\200\247\345\233\236\345\275\222.ipynb"
diff --git "a/PyTorch\345\256\236\347\216\260\347\272\277\346\200\247\345\233\236\345\275\222.ipynb" "b/PyTorch\345\256\236\347\216\260\347\272\277\346\200\247\345\233\236\345\275\222.ipynb"
deleted file mode 100644
index 0535336..0000000
--- "a/PyTorch\345\256\236\347\216\260\347\272\277\346\200\247\345\233\236\345\275\222.ipynb"
+++ /dev/null
@@ -1,182 +0,0 @@
-{
- "nbformat": 4,
- "nbformat_minor": 0,
- "metadata": {
- "colab": {
- "name": "PyTorch实现线性回归.ipynb",
- "version": "0.3.2",
- "provenance": [],
- "collapsed_sections": [],
- "include_colab_link": true
- },
- "kernelspec": {
- "name": "python3",
- "display_name": "Python 3"
- }
- },
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "view-in-github",
- "colab_type": "text"
- },
- "source": [
- "
"
- ]
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "5iQMYTB2EqaI",
- "colab_type": "code",
- "colab": {}
- },
- "source": [
- "import torch\n",
- "# print(torch.__version__)\n",
- "\n",
- "# train data\n",
- "x_data = torch.arange(1.0,4.0,1.0)\n",
- "\n",
- "# Numpy中的size是元素个数,但是在Pytorch中size等价为Numpy中的shape\n",
- "# view 可以视作调整数组的size, -1 的作用是用来自动计算在列数确定的情况下行数\n",
- "x_data = x_data.view(-1, 1)\n",
- "y_data = torch.arange(2.0, 7.0, 2.0)\n",
- "y_data = y_data.view(-1, 1)"
- ],
- "execution_count": 0,
- "outputs": []
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "xb9r5NSZG-rg",
- "colab_type": "code",
- "colab": {}
- },
- "source": [
- "# 超参数设置\n",
- "learning_rate = 0.1\n",
- "num_epoches = 40"
- ],
- "execution_count": 0,
- "outputs": []
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "4JPWaGhVHJ0t",
- "colab_type": "code",
- "colab": {}
- },
- "source": [
- "class LinearRegression(torch.nn.Module):\n",
- " def __init__(self):\n",
- " super().__init__()\n",
- " self.linear = torch.nn.Linear(1, 1)\n",
- " \n",
- " def forward(self, x):\n",
- " y_pred = self.linear(x)\n",
- " return y_pred\n",
- " \n",
- "model = LinearRegression()"
- ],
- "execution_count": 0,
- "outputs": []
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "3awwus05H219",
- "colab_type": "code",
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 791
- },
- "outputId": "b87e7709-88af-4248-9c1d-293adcf2da6d"
- },
- "source": [
- "\n",
- "# 定义loss function损失函数\n",
- "# PyTorch0.4以后,使用reduction参数控制损失函数的输出行为\n",
- "criterion = torch.nn.MSELoss(reduction='mean')\n",
- "# nn.Parameter - 张量的一种,当它作为一个属性分配给一个Module时,它会被自动注册为一个参数。\n",
- "optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)\n",
- "\n",
- "\n",
- "for epoch in range(num_epoches):\n",
- " \n",
- " # forward\n",
- " y_pred = model(x_data)\n",
- " \n",
- " # computing loss \n",
- " loss = criterion(y_pred, y_data)\n",
- " print(epoch,'epoch\\'s loss:',loss.item())\n",
- " \n",
- " # backward:zero gradients + backward + step\n",
- " optimizer.zero_grad()\n",
- " loss.backward()\n",
- " optimizer.step() # 执行梯度下降\n",
- " \n",
- " # testing\n",
- "x_test=torch.Tensor([4.0])\n",
- "print(\"the result of y when x is 4:\",model(x_test))\n",
- "print('model.parameter:',list(model.parameters()))"
- ],
- "execution_count": 8,
- "outputs": [
- {
- "output_type": "stream",
- "text": [
- "0 epoch's loss: 16.615921020507812\n",
- "1 epoch's loss: 0.5019358992576599\n",
- "2 epoch's loss: 0.29503700137138367\n",
- "3 epoch's loss: 0.2788357734680176\n",
- "4 epoch's loss: 0.26556479930877686\n",
- "5 epoch's loss: 0.25294986367225647\n",
- "6 epoch's loss: 0.24093462526798248\n",
- "7 epoch's loss: 0.22949011623859406\n",
- "8 epoch's loss: 0.21858921647071838\n",
- "9 epoch's loss: 0.20820589363574982\n",
- "10 epoch's loss: 0.1983160823583603\n",
- "11 epoch's loss: 0.18889588117599487\n",
- "12 epoch's loss: 0.1799231767654419\n",
- "13 epoch's loss: 0.17137672007083893\n",
- "14 epoch's loss: 0.16323624551296234\n",
- "15 epoch's loss: 0.1554822474718094\n",
- "16 epoch's loss: 0.14809675514698029\n",
- "17 epoch's loss: 0.14106221497058868\n",
- "18 epoch's loss: 0.1343616247177124\n",
- "19 epoch's loss: 0.12797926366329193\n",
- "20 epoch's loss: 0.12190017849206924\n",
- "21 epoch's loss: 0.11610981822013855\n",
- "22 epoch's loss: 0.1105945035815239\n",
- "23 epoch's loss: 0.10534120351076126\n",
- "24 epoch's loss: 0.10033739358186722\n",
- "25 epoch's loss: 0.09557127952575684\n",
- "26 epoch's loss: 0.09103161841630936\n",
- "27 epoch's loss: 0.08670753240585327\n",
- "28 epoch's loss: 0.08258878439664841\n",
- "29 epoch's loss: 0.07866580039262772\n",
- "30 epoch's loss: 0.07492917776107788\n",
- "31 epoch's loss: 0.07136993110179901\n",
- "32 epoch's loss: 0.06797981262207031\n",
- "33 epoch's loss: 0.06475075334310532\n",
- "34 epoch's loss: 0.06167503446340561\n",
- "35 epoch's loss: 0.058745432645082474\n",
- "36 epoch's loss: 0.0559549555182457\n",
- "37 epoch's loss: 0.05329711735248566\n",
- "38 epoch's loss: 0.05076548829674721\n",
- "39 epoch's loss: 0.048354025930166245\n",
- "the result of y when x is 4: tensor([7.5696], grad_fn=)\n",
- "model.parameter: [Parameter containing:\n",
- "tensor([[1.7507]], requires_grad=True), Parameter containing:\n",
- "tensor([0.5666], requires_grad=True)]\n"
- ],
- "name": "stdout"
- }
- ]
- }
- ]
-}
\ No newline at end of file
From 6c0f76c7169cb41857e2eb71e8cfc2b740e7e611 Mon Sep 17 00:00:00 2001
From: Chuan <41295406+caalinlu@users.noreply.github.com>
Date: Mon, 20 May 2019 20:03:07 +0800
Subject: [PATCH 3/4] =?UTF-8?q?=E4=BD=BF=E7=94=A8=20Colaboratory=20?=
=?UTF-8?q?=E5=88=9B=E5=BB=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...5\221\347\273\234\357\274\210LeNet).ipynb" | 949 ++++++++++++++++++
1 file changed, 949 insertions(+)
create mode 100644 "\347\224\250PyTorch\345\256\236\347\216\260\345\244\232\345\261\202\347\275\221\347\273\234\357\274\210LeNet).ipynb"
diff --git "a/\347\224\250PyTorch\345\256\236\347\216\260\345\244\232\345\261\202\347\275\221\347\273\234\357\274\210LeNet).ipynb" "b/\347\224\250PyTorch\345\256\236\347\216\260\345\244\232\345\261\202\347\275\221\347\273\234\357\274\210LeNet).ipynb"
new file mode 100644
index 0000000..dabc7aa
--- /dev/null
+++ "b/\347\224\250PyTorch\345\256\236\347\216\260\345\244\232\345\261\202\347\275\221\347\273\234\357\274\210LeNet).ipynb"
@@ -0,0 +1,949 @@
+{
+ "nbformat": 4,
+ "nbformat_minor": 0,
+ "metadata": {
+ "colab": {
+ "name": "用PyTorch实现多层网络(LeNet).ipynb",
+ "version": "0.3.2",
+ "provenance": [],
+ "include_colab_link": true
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.6.5"
+ },
+ "kernelspec": {
+ "display_name": "pytorch",
+ "language": "python",
+ "name": "pytorch"
+ },
+ "accelerator": "GPU"
+ },
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "view-in-github",
+ "colab_type": "text"
+ },
+ "source": [
+ "
"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "WHKI4G1G9dNO",
+ "colab_type": "text"
+ },
+ "source": [
+ "## 神经网络\n",
+ "Autograd实现了反向传播功能,但是直接用来写深度学习的代码在很多情况下还是稍显复杂,torch.nn是专门为神经网络设计的模块化接口。\n",
+ "nn构建于Autograded智商,可以用来定义和运行神经网络。nn.Module是nn中最重要的类,可把它看成是一个网络的封装,包含网络各层定义以及forward方法,调用forward(input)方法,可返回前向传播的结果。下面就以最早的卷积神经网络LeNet为例,来看看如何用nn.Module实现。\n",
+ "这是一个基础的前向传播(feed-forward)网络: 接收输入,经过层层传递运算,得到输出。\n",
+ "### 定义网络\n",
+ "定义网络是,需要继承nn.Module,并实践它的forward方法,把网络中具有可学习参数的层放在构造函数`__init__`中。如果某一层(如ReLU)不具有可学习的参数,则既可以放在构造函数中,也可以不放,但建议不放在其中,而在forward中使用nn.functional代替。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "VOKstA6u9dNP",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "source": [
+ "import torch.nn as nn\n",
+ "import torch.nn.functional as F\n",
+ "\n",
+ "class Net(nn.Module):\n",
+ " def __init__(self):\n",
+ " # nn.Module子类的函数必须在构造函数中执行父类的构造函数\n",
+ " # 下式等价于nn.Module.__init__(self)\n",
+ " super(Net, self).__init__()\n",
+ " \n",
+ " # 卷积层‘1’表示输入图片为单通道,‘6’表示输出通道数,‘5’表示卷积核为5\n",
+ " self.conv1 = nn.Conv2d(1, 6, 5)\n",
+ " # 卷积层\n",
+ " self.conv2 = nn.Conv2d(6, 16, 5)\n",
+ " # 仿射层/全连接层,y = Wx + b\n",
+ " self.fc1 = nn.Linear(16*5*5, 120)\n",
+ " self.fc2 = nn.Linear(120, 84)\n",
+ " self.fc3 = nn.Linear(84, 10)\n",
+ " \n",
+ " def forward(self, x):\n",
+ " # 卷积 -> 激活 -> 池化\n",
+ " x = F.max_pool2d(F.relu(self.conv1(x)), (2,2))\n",
+ " x = F.max_pool2d(F.relu(self.conv2(x)), 2)\n",
+ " # reshape, '-1'表示自适应\n",
+ " x = x.view(x.size()[0], -1)\n",
+ " x = F.relu(self.fc1(x))\n",
+ " x = F.relu(self.fc2(x))\n",
+ " x = self.fc3(x)\n",
+ " \n",
+ " return x\n",
+ " \n"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "YsWYbzgHAcsK",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 143
+ },
+ "outputId": "7d1f8fd2-db5d-4e30-c0b2-f28755eced37"
+ },
+ "source": [
+ "net = Net()\n",
+ "print(net)"
+ ],
+ "execution_count": 32,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "Net(\n",
+ " (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))\n",
+ " (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))\n",
+ " (fc1): Linear(in_features=400, out_features=120, bias=True)\n",
+ " (fc2): Linear(in_features=120, out_features=84, bias=True)\n",
+ " (fc3): Linear(in_features=84, out_features=10, bias=True)\n",
+ ")\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "eYmtrNk7Cd5z",
+ "colab_type": "text"
+ },
+ "source": [
+ "只要在nn.Module的子类中定义了forward函数,backward函数就会自动被实现(利用autograd)。在forward函数中可以使用任何tensor支持的函数,还可以使用if、for循环、print、log等Python语法,写法和标准的Python写法一致。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "MWl5QFKcDMho",
+ "colab_type": "text"
+ },
+ "source": [
+ "网络可学习参数通过net.parameters()返回,net.named_parameters可同时返回可学习的参数及名称。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "x441tWy4CTl9",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ },
+ "outputId": "e6ea3c39-6176-4703-a89f-24a9ce698852"
+ },
+ "source": [
+ "para = list(net.parameters())\n",
+ "print(len(para[9]))"
+ ],
+ "execution_count": 33,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "10\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Eu3yhdNaHY9v",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 197
+ },
+ "outputId": "6f5b21f7-eea1-4484-f1b5-adc30a08d7cc"
+ },
+ "source": [
+ "for name, parameter in net.named_parameters():\n",
+ " print(name, ':', parameter.size())"
+ ],
+ "execution_count": 34,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "conv1.weight : torch.Size([6, 1, 5, 5])\n",
+ "conv1.bias : torch.Size([6])\n",
+ "conv2.weight : torch.Size([16, 6, 5, 5])\n",
+ "conv2.bias : torch.Size([16])\n",
+ "fc1.weight : torch.Size([120, 400])\n",
+ "fc1.bias : torch.Size([120])\n",
+ "fc2.weight : torch.Size([84, 120])\n",
+ "fc2.bias : torch.Size([84])\n",
+ "fc3.weight : torch.Size([10, 84])\n",
+ "fc3.bias : torch.Size([10])\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "cb7t6T8DIxzG",
+ "colab_type": "text"
+ },
+ "source": [
+ "forward函数的输入和输出都是Tensor。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "MqJxKB26M5-M",
+ "colab_type": "text"
+ },
+ "source": [
+ "需要注意的是,torch.nn只支持mini_batches,不支持一次只输入一个样本,即一次必须是一个batch。但如果指向输入一个样本,则用input.unsqueeze(0)将batch_size设为1.例如nn.Conv2d的输入必须是4维的,形如nSamples * nChannel * Height * Width "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "iPUzeITEOjQV",
+ "colab_type": "text"
+ },
+ "source": [
+ "## 损失函数"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oc6rdzMOPA-7",
+ "colab_type": "text"
+ },
+ "source": [
+ " nn实现了神经网络中大多数的损失函数,例如nn.MSELoss用来计算均方误差,nn.CrossEntropyLoss用来计算交叉熵损失。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "cw_muTHjOhDI",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ },
+ "outputId": "c1e2f844-5e3c-4285-e93e-ba76f54ad69e"
+ },
+ "source": [
+ "input = t.randn(1, 1, 32, 32)\n",
+ "output = net(input)\n",
+ "target = t.arange(0, 10).view(1, 10)\n",
+ "target = target.float()\n",
+ "criterion = nn.MSELoss()\n",
+ "loss = criterion(output, target)\n",
+ "print(loss)"
+ ],
+ "execution_count": 38,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "tensor(28.6133, grad_fn=)\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "EYeKGUHpRoha",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 89
+ },
+ "outputId": "5d28fb8f-760d-4fe0-8f5f-10eed3372e8c"
+ },
+ "source": [
+ "# 运行backward, 观察调用之前和调用之后的grad\n",
+ "net.zero_grad() # 把net中所有可学习的参数清零\n",
+ "print('反向传播之前 conv1.bias的梯度')\n",
+ "print(net.conv1.bias.grad)\n",
+ "loss.backward()\n",
+ "print('反向传播之后 conv1.bias的梯度')\n",
+ "print(net.conv1.bias.grad)"
+ ],
+ "execution_count": 39,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "反向传播之前 conv1.bias的梯度\n",
+ "None\n",
+ "反向传播之后 conv1.bias的梯度\n",
+ "tensor([ 0.0448, -0.1094, -0.0264, 0.0420, 0.0564, 0.0838])\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "ZSciQPl8S6_V",
+ "colab_type": "text"
+ },
+ "source": [
+ "## 优化器"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "viVhJAMGTIZj",
+ "colab_type": "text"
+ },
+ "source": [
+ "在反向传播计算完所有参数的梯度后,还需要使用优化方法来更新网络的权重和参数,例如随机梯度下降法(SGD)的更新策略如下:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "4_bXHGZZTO1Q",
+ "colab_type": "text"
+ },
+ "source": [
+ "weight = weight - learning_rate * gradient"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "lkw0Z_AiTyae",
+ "colab_type": "text"
+ },
+ "source": [
+ "**手动实现如下**"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "8stHZQ1dUDKc",
+ "colab_type": "text"
+ },
+ "source": [
+ "\n",
+ "\n",
+ "```\n",
+ "learning_rate = 0.1\n",
+ "\n",
+ "for f in net.parameters(): \n",
+ " f.data.sub_(f.grad.data * learning_rate)\n",
+ "```\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5lr8k4NQT5rt",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "source": [
+ "import torch.optim as optim\n",
+ "# 新建一个优化器,设置优化器类型和学习率\n",
+ "op = optim.SGD(net.parameters(), lr = 0.1)\n",
+ "\n",
+ "\n",
+ "# 首先清零梯度\n",
+ "op.zero_grad()\n",
+ "\n",
+ "# 前向传播,计算损失\n",
+ "output = net(input)\n",
+ "loss = criterion(output, target)\n",
+ "\n",
+ "# 反向传播\n",
+ "loss.backward()\n",
+ "\n",
+ "# 参数调整\n",
+ "op.step()"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "rO23ulanYMhW",
+ "colab_type": "text"
+ },
+ "source": [
+ "## 数据加载与预处理\n",
+ "\n",
+ "\n",
+ "在深度学习中数据加载及预处理是非常复杂繁琐的,但PyTorch提供了一些可极大简化和加快处理流程的工具。同时,对于常用的数据集,PyTorch也提供了封装好的接口供用户快速调用,这些数据集主要保存在torchvision中。\n",
+ "torchvision实现了常用的图像数据加载功能,例如Imagenet、CIFAR10、MNIST等,以及常用的数据转换操作,这极大地方便了数据加载,并且代码具有可重用性。"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "uC30PgfRZkU9",
+ "colab_type": "text"
+ },
+ "source": [
+ "## 小试牛刀:CIFAR-10分类"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "m-wiJ_QwZobt",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "source": [
+ "import torchvision as tv\n",
+ "import torchvision.transforms as transforms\n",
+ "from torchvision.transforms import ToPILImage\n",
+ "show = ToPILImage() # 可以把Tensor转成Image,方便可视化"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "U5QtY3ljb1MJ",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 53
+ },
+ "outputId": "ab94a1a0-5ef7-4e2e-d07b-e0e7f7781fc7"
+ },
+ "source": [
+ "# 第一次运行程序torchvision会自动下载CIFAR-10数据集,\n",
+ "# 大约100M,需花费一定的时间,\n",
+ "# 如果已经下载有CIFAR-10,可通过root参数指定\n",
+ "\n",
+ "# 定义对数据的预处理\n",
+ "transform = transforms.Compose([\n",
+ " transforms.ToTensor(), # 转为Tensor\n",
+ " transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)), # 归一化\n",
+ " ])\n",
+ "\n",
+ "# 训练集\n",
+ "trainset = tv.datasets.CIFAR10(\n",
+ " root='/home/cy/tmp/data/', \n",
+ " train=True, \n",
+ " download=True,\n",
+ " transform=transform)\n",
+ "\n",
+ "trainloader = t.utils.data.DataLoader(\n",
+ " trainset, \n",
+ " batch_size=4,\n",
+ " shuffle=True, \n",
+ " num_workers=2)\n",
+ "\n",
+ "# 测试集\n",
+ "testset = tv.datasets.CIFAR10(\n",
+ " '/home/cy/tmp/data/',\n",
+ " train=False, \n",
+ " download=True, \n",
+ " transform=transform)\n",
+ "\n",
+ "testloader = t.utils.data.DataLoader(\n",
+ " testset,\n",
+ " batch_size=4, \n",
+ " shuffle=False,\n",
+ " num_workers=2)\n",
+ "\n",
+ "classes = ('plane', 'car', 'bird', 'cat',\n",
+ " 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')"
+ ],
+ "execution_count": 42,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "\r0it [00:00, ?it/s]"
+ ],
+ "name": "stderr"
+ },
+ {
+ "output_type": "stream",
+ "text": [
+ "Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to /home/cy/tmp/data/cifar-10-python.tar.gz\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "stream",
+ "text": [
+ "100%|█████████▉| 170459136/170498071 [00:14<00:00, 14320972.23it/s]"
+ ],
+ "name": "stderr"
+ },
+ {
+ "output_type": "stream",
+ "text": [
+ "Files already downloaded and verified\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "Y52AOzJYf4qA",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 135
+ },
+ "outputId": "0345efb6-b312-4929-bb40-4753ecc2bf2e"
+ },
+ "source": [
+ "(data, label) = trainset[100]\n",
+ "print(classes[label])\n",
+ "\n",
+ "# (data + 1) / 2是为了还原被归一化的数据\n",
+ "show((data + 1) / 2).resize((100, 100))"
+ ],
+ "execution_count": 43,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "ship\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "execute_result",
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAALVElEQVR4nO1cW3MVxxGe2d1zk46E\nhEASlpCEBaEo43K5UqmUKz8jpCo/MQ/Jj0j5JQllLGIw2NxsK4iLERJH17PXPEz316OZxdLoeb4X\nWruzvbPDfNOX6Tn64cuRUkopVde1OomqEbmsaqcZhIKbFTVJVVV5jRsWRGdRlaRc8d2Gbmtu3/AD\nTdM4Ql4m0tXavYs+NI1mVepjX9pUckUXlXMX7RMVcWbEwQpAppkCEACttMgsJiw1uOK1EYHvJWht\nvQWqUhY0s0FrJqbGYy5V00S6Bwjf5RpdSZKU/vaorRrpldau2oRfFGdWAOJgBSBLZMLy5OS/Ey1D\nCakRXqAZBDZJunEayRVrkguNEpe3iSwO3DkxWCCv9R0ed1J0hvsO9uFtYLTSNg3d5QhsjTMrAHGw\nApBZfHJnvj2zwYtaYTLz5GzQ5qQiS2w8U6tsHmm3WeL1wmK9e+VEJ+C7ijlkN5VvZQluJM5HqTbv\nF0Y6zqwAxMEKQBysAGRwWH0XO7GMqCxVWNr4AawFvivQ1O6CaLvdWpNLXXNEnYgn7boC0r0Ga6ul\nSvrAjgVPg6pkj58vQUOt8S2W68APIhiIHvx5EAcrAJk18wkWc+ygF3EsLnLuSey9qwNudC0+hJU5\nEp/Ddf0tEvqeDFwHiztYHBpXgzg0csv3VERV43EzevDnQRysAEg+S8JgvldbbEgSmBKka+mWzHyh\nFWJyNIJOC4hs4VJLPotttJDPzZbZy0cj7V2zqFJXuZh7lmp7zqAPSMYpV4g4HXGwAiCBdIt32tjW\nENlk7d/FE87f2mOHnSxqGtCQA1rtPqi8KxBOmjD0wPOQvTy45fm2JA1ASY3eeHyMOB1xsAKQiY/n\n08q68BteX4vQss9DQm3lfxEb4lErGhVb62mSXLXVP5ek1h0v2e0pP/HtkuJ2I9w4swIQBysAWcPT\nrvIqAM6I1CcdiMIzuYBHmGR4MEFWl1mQ8pNlUzhv0QolCOzxCotV3fD/OvIwKLNgVbVmd9oLRWtR\nLouD1q6vHGdWAOJgBUBI0VKMcDYknt8olUaNn8axd114ejeunRKC1O5mkrWDeyI6dL7DN82+oYQ1\nTKz8rV8A4Wd7Ik5HHKwAZFq5+/26JegTaEmQIg/jjnjLhEey0dr8hJXBbgjebO3XukkebM3aqkBk\nLQkc3PXKJrxMqd3hunYXkxQ+s/tVER9HHKwAZLLm+5nEVrRUyzGJavdOW+7UripgS4dSPNGIJCZt\nKaZI47CG1OonzC7KpPx9B+isGrwOHRUaViBpTZ5qmqb8FRFnRhysAMTBCoCUSYK24H9b4liWNvHF\nUZXfkrjlhYP5n1mrQ8aBcCUmPOFuUbMclf68q4QOpFYVJ+JorINwgLAdlXiOQtW6THsZ7RhInwdx\nsAJgbbJaRbzm38r2tgE/Nhan2fWMMZNB0IP9D9C0vf3OCEXB2StW1ZuYcl47nBxSr/hQTpL15TO4\n82VJroZfoCDuiFecUdvBAF/WnBqLZ3fOgzhYAcjatm1cwYb2JrNVe8R/s+1Dk4QLfp/98BCq7t69\na4TxeGyEPCc+Fg1Zyi++/NIIn9++bQTQcHK2B1U4QqekNApW3k1tV6UbFdi5A1hPmGZvszXiDIiD\nFYAsscp86N/W3BPguay1xmRmTR5/Gy6xXbh0ERdXlz+hFzEdtt+/N0JeEw0zVvr4+wdGuH79Bt86\n8Qb+CPSKbTrTFoF3guJcvlLZpcbMOkmXt5Q2RpyGOFgBaNndCd/fYQ1ylo6Jyf8X+TGZuV5X3njz\nxroRpqbIBf3mm3tG6A5njXBwdER9YtZfnL3g99M6g4cKRWTZvEIoT0r8PLhStXcsPs6sAMTBCoCY\nlMqLqqQw1vb6pJCBnTdVOQ+CAjjR8fbtKyN8d/9b6Dw+PjbC5i+/GCHNiKTXrpOw9XLLCF999Sfu\nFPWqKqQeIvUOi9f8OR22ffiZCvldB8mQW7UOqPzDOHBqO86sAMTBCkBWeT+XIlV6lt2QX3GQ/U9q\nX1aF00YOjLEvOneZrJvqiDVMFQV3U3Nz1GyOXNa8yo2w9YpoOL+wyMq5JMi22rUwivopd9wtnFq5\nYeOJPSfv5EyTRGsYjjhYAcgQOllzklDVYiPQLFMwgkix8hlLsaL0f3BhetoIPzx5YoT5K8vQeXBw\nYISpGaLh/v6+EV5vEfuevPjJCH/7+z+M8Jc7fzVCryuZUuvnlOhKXoBE2hFg2cUVtew+fNESzWKt\nwzkQBysAcbACkB0XpXNJ9kUsM4/cccXubJmT/52mXW5BQ//zTz8b4e3bX42wf3hohPxEJRScD96w\n6Q2MsLh01QhXr103wmBIy193YpJ7YvWZ/Ymyoe6N+St6aYe/y1udJeQQVVhwk9oNSOLMCkAcrABk\n9+7/10jwtuEldKzcU6/DfnNN/vrkgPzvJCEaNglduXdvwwgbG/eNsLu3Z4SF1TXoXF4mN+Lp06dG\nmGNXfmVlxQjrN24aYW2Nkl9vft02wrgQHoJZ45w2ipBTyziQxg6TtfdLRCtKey1q4SZpcC9EfBxx\nsAKQvf+wa6TBgCxRxkmlzLKGmoPJNSbIzDTlgvsDqkJ49uJ/dGuGMr/r69eMsDMi13x6fhE6//Xv\n/xhhc3PTCCWnqO7c+bMRZmcptH786LER3rwmGua2OWQTdshmt9MhIwinPpX9Hg6k4dNbNMTeKtYl\nv4Y64nTEwQpABpNSHNAEnp2l3FOv30W7hUt0scPcHI12jbC3T/Gw4jNqv7tJlmtpiUi3u0c03DnM\nofOPf/i9Eb74/DNqtks6+/zqmRnyRY8OaJvnYH/EfWeiWdVRiIgrzohhdwe0bbyAv2yj4W9UL0Wc\njjhYAcgSnszb22Rl9njCPzvaQbseVwpcmiVepFLaQCPe53I9mNGq5NxQ2bJBsrJ8hVRxVT4MMRzj\nfEz28ZPFy0bY3KRUV29yILqYUKMRkTTPmYZcnIsMV8qVvzCCRdFCQ+tcbsxnhSMOVgCyhmfdxUs0\nz1EOW42lWLbhY9mDASVzUQePCp5KUZuDQ7KPBVfyjXMOPGsxYTnzGDSE3cmYKSknWLocga6vXnUe\nV0qV7HlWnDhqeM8JDNOpe1K8kjNDkjgqeenAmlDHFM05EAcrABkog1mHdAccQqWULjkvyns5OVfN\n9jPKzHSEO8je8OOY+aX1Yww1NjvlPdyM+ctv2d+jDmRMzP60dC/nOG5+boaUF2TT9yoUPXT4HbKB\nRVcSoXQxphdVXAQMWxlnVgDiYAUgO2YaznEyBDwBv5RSyyuU1ex1aTI/evS9EV5uvTHCYEhbCUh4\ndlLyG3WXnUxl5yS50LxyDWuGA6mcGtIDEsbwNot9UcQBYMo1VDOTE0Y4PqRDL3VO2VosF3ND3h9Z\nmIcq1Dq8eU0PVtXgRHcjzoI4WAGIgxWAbOEy0fWIyzQS9iFu3/4M7VaWKTO1NyLmT0xQNvnwmIz0\n0xfPjfDkx2eknVUhRzbJJ+GU5a9P8PrS4aieM2MSig/6tHCguPKoOIYq/KbTaIeC//l5itKHvJIO\np+gtV68sGGHpCn17t2M5NLwX++7dB/5k+sA4swIQBysAGfI+MMljrtPf2JDK4offkYBULJJWq2tr\nRrh165YRUGb14AEduHn+nBi6s7MLnb0eu/68EwNh0KFb3Q7Fz91u12lTWbWNSUqdQeHFCgf8K4ur\nRri6St7PBU6E9bFzbKnCNm2vR+m50ZAS7nFmBSAOVgAyJGum+QDN+JBouPVqE+0O93aNAIp1mBf/\n/PprI3Q9WoE7S0tLRsjzH6ETaazhkExkxldqjl1hm0bcAcTkCJ6VUkfHtIZ8yiVKO2wWYaw7XVI+\n9SkRM0mQ/hYavt+mF/X7ZD3n5siUx5kVgDhYAfg/pQ4eZ65sAxcAAAAASUVORK5CYII=\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 43
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "2w42GpDS3sAF",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 135
+ },
+ "outputId": "b017d14a-4255-419d-a094-0979cc144ac3"
+ },
+ "source": [
+ "dataiter = iter(trainloader)\n",
+ "# trainloader中batchsize为4,迭代器一次读4张图\n",
+ "images, labels = dataiter.next()\n",
+ "print(' '.join('%11s'%classes[labels[j]] for j in range(4)))\n",
+ "show(tv.utils.make_grid((images+1)/2)).resize((400,100))"
+ ],
+ "execution_count": 44,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ " bird cat car cat\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "execute_result",
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZAAAABkCAIAAAAnqfEgAAA2BUlEQVR4nO19SZAj6XXeByCxo1Co\nvbq6q7u6e7qnuzmchUNyhou1BCWHJNOyZIftcIRkRkiWt7tvPvjkm0MH6yDJoZMjHJJlhSRb5iJa\nlEIznCE5w1k4nGFPr9VL7QuAwr4k0of/+x5QBRRl31zh/x26XwGZf/75ZyLzfW/5HuDFixcvXrx4\n8eLFixcvXrx48eLFixcvXrx48eLFi5f/vyQ2/tEv/JtPOSWdTDjl0W4ZQCmbdH+eXznnlEa37pTb\n399xyo3PX3RKu9FzyoVLy04pV/ac8tF31p0yW5oBkEml3J/b27tO+dlf/ZxT7r+95ZSHHz9xyvw5\nbhyrcW6HnYZT5i4vOWV1eQHAox884AY1bpCIBU7px/uc23OcbbqbcUq+eOSUva2qU6aSeaf84b9/\nDyPy8s1npXINY1rLeDyuT2InFfwNEo+oDCJpCY7W7HSc0upSyWdynH/AU4sHA+6UcIfjKkWRjjyQ\nYuMP50YlAr+KcW+EHBX9XgxAf8ANev2ONug65cM790+c0d7egVM6Hd4SvW5fu4cAooGdMw8ThqaE\n+oafDPRJGGlOwxPiOP1+CKDf72vfUFtw03icy5UI+ElCi5xM8qt8Pqtt+FUQxAGk02n3Z0r3rV1c\nm2Snw9VoNdtOaTRaUppO+fwXPoMR+bdf+TmNZmvL0fo65S7Xb3hv1KuHTimXa05p69C9MASQzXK2\n55fnnTI9VdDp8OecTlPJZbhxPsf7Kkjy3HttnkgilQSQ1Y3X7fDzw3LFKXcf85nwYIs/56kcL0QU\n8gQSSe0+4Bpm0AOwep7Pipm5Oaf8u9/+AxyXOLx48eLljEgw/lG7ReMiHvCJe+PlBQD339p0fx6U\n+VyvHvH5OtCb1t7knTofq90mXynNKl8CeQ1b3tkDcPXqZffn6vlFpzx5suGUBw9ouJnhEejdGOpF\nlMjJnNGr9umDpwB2nvJJnyrQTojpTZvL8ZNUgoN0mjzQzPKUUwo5vmAHPb2fj0siYcaLDARTJOOG\nlX1i4na3z+PxkxZQs821bbT5ljYDp93klZou0AwslvjuinEcvZBkjoy8oWRGxeInT0TzDfVJo8k5\nNFvdY7NNcNxk8tQ3ny1UIi7jaGiBDgAMZCv1+3wDh31tOWZhja3fcNVt6VKpAEAqlRybiy2ybgnd\nRUGQ0InwBkulU5q/nUh89HRGLpmde0yj8dBBsn9ifDuRE9KRqeImPzqs1nh4gRIB5xY3y1pfxSPu\nlU6lABSL0/wzyxs7SPPGzmZzo+cFoNVpaVhOO6PbJZfXfZWIj55gMkNoktYdeFDbdsqddf6Ko7zO\nPcm9div8bT7eobI8WwCwV+ef/faHOEW8heXFi5czI/6B5cWLlzMjEyDhQL6xwx1ahqVzcwDqezQ7\n80JhCGmafupFwrrCQtEpCzk6+S6tzjrl6QeEXYcP6AWPZuIA2hGPksrRvNy/zwnUH9JEzJ7noatV\nKqmQtm6qRIB5VKW/fFBrA6hXOOzlJU4pmaFtnZnjgVIyfQdCsusP6CGez3OvWquFSRKNAUCDKxNA\n4jiSGe7kvuKWNmhfAHZnj8EKCAgsnVtxSuWAkLBc5ZLGBM3y+dzI4Oj1zANtICWQYgCNirmrqzXC\n+VaLrtx8bgoAzOENQsVUcsKNpEPzarbluG23OZpzTg+GTvdQi6DVsK+0fuNALC6MZhjQnZptMHI1\nTBNU141skM3wUWK4LNzLobmh+38M3I3EWE4e0dzkp0FCizPYnAb6JNIlGwgpRwneCYFAVkqO82E8\nJAwBNJu8ew91gQL5y5MyViIdsaaN+4rqRFOKPGihMpkUgF6XlzIeCWAWS065uMpp318nNhwkdPPI\nOdPo0Ds0XRjoRFIAOiG3PDpq4hTxFpYXL17OjPgHlhcvXs6MTLDkUwoo7G0TcTy8fQigsk478MJl\norDCHA3C3CyN4IVzzPJIdGm1bq6vO6UroBEpwWS2WAAQpmgH1pSrUt0kiIgpQBLvcZ4LRUYSL167\n5pTt8mOnbKw/dUoynwGw+oLCIoIMmWkOkpshJOzUGe5stTi33V2C0OJNQsJBfDKaG4/3/V/Jid3H\nAnRD6XS5Phjw7VKYmnFKMqB5v7nBiMyh4i+dfh9ApKyrphKCBgbAFQVLp04mFrValj3EQxcKJacs\nLKwAaDYqPEqboyVOWaVjZzqelRaLje6bEJ4dCZVqV30SjxkSjOtEOH/LkBoJ27kxDGAOJ8VP9JGN\nbwBwCNK1jcN3hukM7o1HVy0KmTTIprXNKKx2QlJpS/sSuOu3pfCIvR4/sZivofiEAP4gZrlOAYC0\nrnJKV7knpNmRlyAVKQ6q0boKF2IqowMK0iIOwK5P2CN4DOIlp5w7R1/QjetXnXJ/k9mUszMC7xk+\nJfJZYsNOqw3g4JCejV5bKWdj4i0sL168nBnxDywvXrycGZkACeeXGICr7sswi4UAiss0VlsNxq3M\nPu9EBFCIaLVulded8nSPwbtuk3bkjSsMKeYKMQB5He7pNk3HmMIK6VmltPX5yV6Nh07VaOJW9pRs\nxuMgzPYBLK0QLt3/mHCp2OYkLxR4xGaTJ9hqK6c0EFoc8ET2Dhr4sfJjsOF4jc5pew1hk94gZuS7\nAAqAWkt1MEplvXjpCj8R9Hv8hJUxjb0ygCCR1AaQInyhkFyz1dSwtM8N4eRyJaesXnrGKdlUEkCt\nVh47QZwmto3hoxFoFh/dNzlWKGOrZOma48HBpIKDJ1J5Y2NB22E4Mjr5VSx+EgBaOLXftwzb2LEJ\nTFAs1Hhy/H6Pw+ZU9XJCOqq7shsASgGNB7aLEms1mgUHY6qistiiO6OBfjgW1+upCm2QzZ6YZKQV\nqzV5z8cPbcX4v8ujzthxNbOjQ/4wS3OEhLdurDql2tQcWrzBZoo8dFzVcuWDJoCdLcboM4lTDSlv\nYXnx4uXMyAQLqy/jotXig3aqmAJQWuJzMehROdzkY3XmIl8Ce/u0krpVvqDmB6xJvpnnw/H6Aksc\nXT7Og0f77s/pJC2gzrRMCJXOZAZ8on/ieVpniTztjicf8Klc2aKpNT1fApBc5C7ZFF8pUVfFzx2O\nrxcVsgV6ARcXNew23wa5TB6T5McYTZOKNv4GMe8prORIeUAZlVAcVHmmDVU75fKc9vwCYxFb20+1\nTQNAIpfWIKo00ivK8rAsVael9KhikRfi/AWu9uwcx++2GhhJ1AqGvupTT80Mn5QsLDPMk8nU6AYj\nFtaYnx6nrm3M8q1wzBQazYbiLjhpL4zkdynFKbI5nPSXu1Sp8QkkhmamUqg0vhmV6czk9CsTiyH0\numZHhxpW66Z7pD+si1ZplEyejOzNeJAEkJZBF0+opk0mdlslXwndGzGrewt5juVD/grielC4u9Lq\npa2CLW+VZFVezeIcKRKev0rl9sd8sDT3eeisjMf0bAlA/iYDZYMe7/AP/+o1HBdvYXnx4uXMiH9g\nefHi5czIBEh4VJXBJluxWEwDyGRlP7cJslpdwqWpGSpWxp2tcpuV+AWnzM4S+q3IQV+OAcCDDwnl\nEnlOphVxAm1Lx+iKcqgjfgVVtzf2iVszsuGPtuoAniqHK52jSd8Rn1CzwdFywj6P71Sccv4lepfT\nOz/kuc9govyfQELDd5bdEw0zgGy3uNuCJyg4YYgjZ1X1MWaNVfaJxPf2CMCN0cEorBJBAkDf/Nsa\n1jiPBn2byUkqqEDO4/n5WY3G3Q/LewCiSIlyw/fd6ZEHAb2kEEdSAN+hk+Eg4ikbrpvV0BhSiwyI\n6dYdocLgGcWG/45+bvlLcSlDx/zwzX0yuypS+psDqjZWwjLCxrz7YewkOUYmY9QRk7GhMVUEgsN2\noFCOc6hypS/wHvbFmpDmgbJZAdhEBkAqw59wWsB2vPSnF+qWU8VPTHGejghC2vq5OcqTTkfRNvEr\ndBpU8vrELtDK+RnNjbmT5X1uY9gzmc0CSBW45VGP4/++h4RevHg5u+IfWF68eDkzMgES5nLEd8kF\nwoe9nQqAl1+65P7c2aZFd3OFNt6lSyWnDJQe9eIaszDm08zLePP7b3N38aK+8LlVAA0BwCev33ZK\n6YImMKdiC83NSkxCKCwypVQjhdVa7TaAdshhC2mG0kqzRKkzGralQEzriGBke5NRtqzwb28wma1h\nhAzgeHDqGFo0JHiSjMFCPq5iaUiqq2SraJg5RSVhaTJHFadsbjHFrGVIWQllDpvHhfIsHmrD9nvc\nJTkM3vFMmw2mtG1tkpl6ZpaZa5XKNoAY+idP+fR4aBQX/rKPpLminGE0z5C0LrglW8VUPmKkzwaq\nwyg8/gHjX3Xll1VqrDCrGPFklXlkjQb9CRb3nBM5762bt5xy4dx5HTpm/2IIW4fK8PwECY0z0tK7\njJ/vhNR1Y0/lM9r3JFMFBNVtDUZS2IQNk8dztYz4UCjeOLJDnXJTv4KU3AWpHF0loUKWRrmRTgUA\nApGn95Q+Zn6k0FizhWTPPfMJp6w+w7TBcxd5xLZRoUTuHy5Otj05Ww3ewvLixcsZEv/A8uLFy5mR\nCQZqKPNvZ4dxPccX0O7SkDtSRODVl192SrtDYzvRE4ibX3DKbIk29ksRN/7aN77OYcMagFc+c939\nee9j8i58WJGNusREsqLAaTCgLarcScyco/larxPIBC4LNKXkxhR3mV2inTmlNNFGmRxj/ZCmaSJN\nEzo7x4BFWuOckHEAOIHSbxgT5ItBARnUVf1QrdYANEWQ0LOuMNZCRqUhfTPvdYG2dYHCUCX+VrSR\nSQEIUoowDtI6U04go5TCaMCZNIVfOjLmnz7lFTmq8UJE/Q6AqZxVwyh4dzpbQ5QwyMxPLNLnYn8W\nbrPERQtg2bl3RCrZ7fFK1WrMadzfIzHk1hZjphubmwA2ttiCYGeX7VsqR7xDDHsad8IQHwmkXL/G\n2/If/vLfd8qLzz0HIKEMzEiTTAmODXNKh0Hhk2m6p0lLiC1vMbuxJTXHguHvaAg5jcmDVyrW7GAk\neBe2ta8RLdh9ZRFYMUZMGxO8sGH96EBzAICc8kVjwuM9xambisVHAx56++Edp6SSvAlnVhmLLy6v\naDIhgOoOrxQOD3GKeAvLixcvZ0b8A8uLFy9nRiZYqjubNLZTAQ0/F2RqNERpkKUhXRWR28MfMpyU\nStKo280zubF/6UWnrOZZj/bMGlNJyztbAHCdNuSXvnjTKY1vP3TKfkfQI815NtQrrGrZrbPcZuk8\nS5Zq9Q6AjQ3OpKsAnGHG2iHxZEFxw9llgsSUbN1Giwbt4sICJsmPCQ6ORAkVkRF8KIt4vnrEE3HN\nRAdK+IyLxM5aXVlKoVEJDlR3ZtDGGppGMETZA4A+hz13/rKG5S7FHLHDk0cfOKXbbWhfzrbeMP4G\nfjJdyOIYd4JBwlPffBZAHFkUQacoDqCjNMiKLm5DvW9ty/1qxSl3H/He2NjgLffo/j2n3P6YUebD\ng0NMItibFxf+K1/4Aj9RTNAKBnd2CDBv3+Zo/+E3f9Mpv/6VrwC4uLqqSfIOubzGtV2YZ0DcXAPx\nMdqJ0ySW5uXoDXi5M6KZD3tcHwOAtuxdtaSNhKateNClSXcVNbbSyKTClMbkFzOqeHXDbauI2EpQ\ng7SG7bUBtHXcWCQUr8Bxu2NtU7UIFeK7x7ffd0qjxl/B8lX+5JPpPICWtqzsbOAU8RaWFy9ezoxM\nKs3ZFSVQjw/adDIJYEO9p2emmCf1WA1d9jfoMy4tq+NOn6ku+AHfBr/60t9xytIsPXnFqA1gQ91S\n7XW0Km6AohJOduVdboEvgcWLrBqpKikpLSus3m0CWFziBuV9tX5p6pUrYt+43KXFWZ7RQA7ggw0Z\nFzLQTshIa89xw0rb6FV7UGYq0MEhl8U86K4pZqhNrb1KQuURwz6aPXvBGhWUhSB4pfJ5ntHqpWUA\n23s83OwC3agrSp1rVCpO2dulKbG6SjfzxqbM5L2mJnmM83f8TOOnWxCxIfkUPwn1yZONDQDvvPOe\n+/PeA/r4rbJlTebMY2WElWX5WiqQwjDY2ORr+WB/HyOcE5YxN9BL//LlNX6iq2DbXLnKXKGCOoN+\n57XXnfI7v/u7AD710qc4t4sXnTIlP/fC4oLmP7Ya+uA073tmmrZep8afQ0zU2FFoWW8nKaSt45GZ\nWuJzY8PUtPaNLIYzdOqriks/nJFCpWOtdwAkRZueiNIAWjL6gmHGnPFTcwJdsSdXBRE6imwY6Okq\nDy47NQ3gqMqfSfnwAKeIt7C8ePFyZsQ/sLx48XJmZIKBGm/JJyogkM3mACTkee01VBXRUR9EjZOK\n0UvXHdCv9vCA+GIwU3LKpQusdXhU3wZQFUnY4RFxZUFV4y3l2lTu0FZcu0W0WBOn7V6Lc6g2ecSj\nowaAlUUSB0YDQcW6cre6OhE1yykt0+INRYxbqygxqj85D2tcxqnd6nVavPsHhLRt2fmGAdHtYQQ8\nxmzNle9jVe/R8OUisjc1PjE7fHmZft9/9a9/A8Bb75Bz4rEw++d/8otO+eidd5yysvDTTvmZn/mM\nU/7L7/+xU/7kT7/J8QVGJuWaASOYcVySIFiIlLT1wUc/csp//cM/BHB/nUgwPVVySiBIWBe5YKhm\nP/k5YtviDC9ZX5lZswt0ArTaTQCh0FCjzg0Odpl29/57rBJLCBaljcTCmsqo6KRY5IEeP3wE4Edy\nxt+8cUP7EoZZDpfV39j4Jqd536dneeH2arxV4uJmSNkgAmgJIcy+3UTCVnZ9koGjnzbMqIoZEW8Y\n9bb544dUIprjQODcbtdUZgqAWALRVdjNmuAGavdrsHHQISTsW46hYKktsoOEoVxAnVYVp4i3sLx4\n8XJmxD+wvHjxcmZkAiRMKwZRWqaNnczkAVRatKhDNUnt6pNO2fJBaOMt3mBm06ayuh5Vaeu+UqIJ\nXU4DwJ7SQJ7uV5wynaFleL3E7I8Hm2IUEC/g+VnO/HHIgEJb2NBZoAUF/sQRhr0tZnnMlEREXeBo\nPaWr9FQCkrCiCkzufGkyHiU0Nu6KWAG6VsIuy7lvRTrxAUas8bgVTMiQTqfFSW+UC9o3iImyXf0y\nG3Xa4Xc+fgggDp7p4hIRx6tfeMUpZaW6VDY5yU6bsLFSIbjO5go6Sf7f63UBxEWoHxg5X/LU0pO0\nMEJd+VZf/do3nPLD23cAXLzKQo2C8pgOthgpK6uypJDniRzJS/Bkk0DyL772PzhtkTGkEkkAA6tC\nkhwpmeu1v/pLp6ytrTllcYkOhOlpQs4LSuubf+55p8z9vV8GUBCPfkHEivv76iqgwKuhyAUl8dmw\np0VTC0X+1nbivNWbSoYKRKA+5N4zO8PKnnSF2upG3IvHAaQzys/SbC1U2lMBVqvZ0VfqTWutAAQb\nraFOtx8CSIoBJVdSydeRivN0RqUZnlFH5B9GFRLolg6U0emOHMn90hen+7h4C8uLFy9nRvwDy4sX\nL2dGJljyS4IP+SVR4nVDAEJLaCnsEtRoKGaSihv21TOqQ2MynqQduHXE6vn2NA3mWqMJYOeQEYGB\nwgo/2KfVenOF2XSfu8IDvbvPjVsfindco/WKYuNL9wG0FWAyfrVA5mqqQBvb+mWlCkp7U5QlL6sV\nk8NiE1IlbcOmsJU7QQBR/GT8JbKC/kGIkWiOtZmKjNx9GHwUiZ0Rtw+z9USoJjT63bc+AhAKz375\nF/+JU+ZKJadcusSczG//JSHVx/cYUrz34JFTStPcOKYAsSO6G2nMZTM5NUpoy7S3sy2FgeMXPvk8\ngJvPkeDNCOSOVtgI7uk6ZxIoDvr+D1jecftHnO2B8pmzQj3zM/MAFhaI8lZUkWP5omtSlvXVzAzJ\nOaypWiBew8CiswNgNAOzbzEvy4eksr9bcUq5bLCOp3bu3CImiatNAZCbIpI6qHGQUP1HMxmxy9u9\nZ63GdPeFIkvodAYA4gGHTSk71Pg6eopp9pWQPBjSZih1XPd0Oqtmd7E4gLbSd1td3uGBSnMSKRGr\nqElqXGU9FstOCVYP2wYnAgAdoeCO/CHj4i0sL168nBmZYGEFKeurwWdwtVwHkJ/nc7Gj2tRFvZdi\nCdoUlo/fU9+L9oCfbFZFrpRkxeP+YRNykQJYmOZT/MkBX8Wv3yVh8XW9l+bkRHznLsmP8iVaWHNT\nnF5UyAOo7fIlUNQra3GWs603LcuDZuDyKj2smw94aHPDZ2dPcZMqRSWSvWPVNkeiu22JhjiKyXk5\n3J/vkPjxL0ZasavUWV5Sa5YZqCjd6jzMg794gTTWP/1zXwYwpZ4/Lz5PMrK43sDPPvusU26++Fmn\nfPzxRzzlgsxYebgHvfbo9IaEyLIcbbbjYuzDm5s0sVPy0F+5dAnAfImTNCttUS7qvkzgtmzVafF3\nLyhx6bkbPJHLl1lVc+3aswAuXKAJOafm6TmV8iatPmaCD9zqeE6GOPi5jM3EkOzYOq0qoiKbRQ1P\n8UBVR3vqeHTyqMPqZVUUicus3Vb9imwWwyJ9JeKlVDMf02/WNftpNdraUuzDaiKVkcO7C25jxvCQ\n5ljXN0yZ4ZnCiGUUWpKgDKtEruSUZFoV8n0eKCGjdWaJyKlr17dSBtBSWlY3PDX50VtYXrx4OTPi\nH1hevHg5MzIBEgp1IVLR+TPLlwHUZ9VMURkcvSO1UWzyk6Qym4alJ5JOWqUz6mJyYXkewPwCTcfy\nPlM5nld5xIH4Fe4f8tBzGv/qZVqVG7tybG/RjMwuBQDCRfEgH9FIHqjsxkh8knnii06LD+7aIRFT\nS9BpKjU5D8v6oESyjxtCglUxJdlXKQ0yGLpszeiNRv492VEGI5AwIW6JnHyWSbly49pt7RnmNP3s\nz/88gPPnlnVeBHcGsqY1yK/8yj91ysNH9HD/p9/+Pad89P73NUlzx0YYYb8KRLBhXVvGpaIS/EPl\nSZkX3J30vjg/QoV1zMVuuU6LgnUXBfQiLcvsXMkpU1MEU9lsHiNcxlbbZNOOGZeZrfqw963mPfRA\nq2lopwOgJ6dHTsxTaV0FA78d8QW3dRclxS3xSIt8QoyQKy2e4mRKqWcqgEsn+CuLqSNUKEgYi4mm\n2Xg1EimMVAt1etpA0aS8IGFi+HvncnStgbGRTCTEmRWLAejpyTBIKKMqxZ9SVzzI1jy4OEd/SyBX\nQLowq0Myha3TqAFI6dFTKKjt65h4C8uLFy9nRvwDy4sXL2dGJkDClRXWE7z/gIXpK1dWAdSUXhRl\naOwdPCT26dZpmk5foeWZ7Qof7ag9Z5sbH/RZo3N1uQQgsyDG5Pt3nRJXwlRwoIQv1YKk1Irj2nkG\nkrL5klOScZrQ5doBgEqc9nNZLA6JjCqK+nxM92VsV58SMRUUsjxQ0cPcXBETRZChr8SWsrBPS4hg\nyEur+Ei3qzfEsH3oMew8QqJGGRiJmqK3WUW70qI5XhJQel70clOFIoCkAm+Bxuuq2CWmivvz52ix\nF0SWsHZFTH6PSJvXaYhQLWpjtFlOwrDhqaU5j59wkK6a/Tx7neO7zqAxS1ITyq5WWC00vygqR7Hx\nWZ5RJqt8H52IoSpG3IwvUAs4zMgbokUrq+JXFu207jKG649qbQBl0fhWjzjJqq775samjsifw4WL\na07ZO6w4xa7dCUkILg1hvnLrrBNSWQwiSZE62vxDJS4V8gSqsX4MI/G+QOwm7SpvgExAXFYolpxi\nCzhcDbkyEik6EMJYDCNuCmPCSGU4WmlGN6eOmExmdEZKIdBP0rK30ukcgJ5iwVNWEzYm3sLy4sXL\nmRH/wPLixcuZkQmW/O4uLdv9bVpod8K7ADpTshjzssYLhF0dFVcPVJGfiTNqEFdepdGZ13IMXWVy\nJQCtOuFGJlBgTs1spmWark7RzpxSzmTFkJSo3TYOeejp5CyAPTUBzS6KpG2eAKq1y3EbZRq0l28y\n5tgOOMhRVXUeK5MhodXQGH9ATXR9MWPLHgNKIwR40eh/w/xFOy0Ls469UyzaUlRB/Gc/xzYwn3z+\nRad0e/3RSWZFMletEL8U1E0WukCiBceVa6SmuyOmvc3HxBGpRAxASimsw9Kc2KmlOaGA3s2bTBi2\nFp7uPyupsazjVotVNSlB6Ui4u664mOV1doWGHj48VlHUU/bmjiqBLIPUqp1WLzBeaXQXRtdRFfR7\nKqr4j+/eBfD4Me+r/f19jU9uCWNrsLZSv/Yb/8IpL3yK5IgpJViekGEjooRdDs6kZ4rOuWd0HVr1\nnDgehsHnXhNARtmbvYEINqZ4q2fm13jo7Mk7waKoQcY65ireHaQAxI2cI84I77aaGNUOee7zM0KC\nguLGkphRzm1abB/9cICRcqh+4KOEXrx4OfviH1hevHg5MzIJEtaVyNeiLVdr9gBk5vh0m1P53kqB\nxvwHNZbgxXrCIMp/m5rmNg1Bp+YcDb/0zDKAd0WwfU7JdX3RhuWytIHvqfHUsuoZF9W36llBGzNs\ny/U2gN6W2nCtcErza6xZ6xzQbi4fVJySSIvDTJzrC8o7TeSFPY5LRzGvgzIH6ViWoBBTYqyn02mc\n6OOJoyOceWqkGhF417SSV65xEW7evOWU+XlGeBvNFoDKEVFqXJCqI1a7QHVuPZWb1ZUuePUao3ir\nl646pbzHys1ue3d0jqnAsOHpNrzhFgExa0rWbnUAtHOqdxMcG7aZUnGZsQDaOhla7CkXd+MpsVuQ\nSAGo1Qlj23JTPFYU77XXX3PKT/4tQulbz7L72Xff4Ffff/u7Ttna4l61Rh1AW1MasjWIlNGWZaCO\npNZ6bkkdwL7xjW9iksTlPTAqx3ZTIfg2L7eFO3uKQuaV+Wzx6Hibq1GamQMwO7OsA9CzUT/iXbTx\nYF1H7Gn+SlG2PnLK5MxZUm6uCCA/zT9TirzPzNM7cVShh2e3woWayXGQvmp4e8ZSL1dPNp8GEI9y\nOorIIcbEW1hevHg5MzLBwsqJNaFY5KM3n0tjxBeelik0Z70q03wLGYtvd8DXZkqvjv1tPl/vzdAc\n6868DKA/ZYPQJ5fWm7YVGdODms0oBSw3LQehiCIuzqrxSbcBoKCneFnVNmZdTGWVPaQ0lqMWE0Mq\nu3z5J2bUwKOuWvbjUj1S43v52q3nh1EOqUph2CPWyBii4y71mN4c9nIzW8ze5JF1A1e9xd4u3b0b\nj9edsniOb3Ik4gAePuF1KSihJpfhxd1VPk6nwhd4IH9wNsf33rXrJEJ4fJ/e9/J+GSN5OlYSFIy1\nhzGxhdrZpuVuvekHYQQgOlChTMwU7pvRLbEl6+nrX/+6U7785S875dYLpDC+eYtmZrPRAlC2nrVa\nwL6WNCcK44/vMfUvJw6DDz760Cnvvk/iLauqce7wjMIXlmxlFTl2oGGinHz5H2nY3/qt/4hJMpCZ\n1lKiXKtiuW9qoGvIQ3UwaTW4jylwkSvRpz49vwIgErdEqHK3vMimU2k2r7I295aoZklhxt+WUp1Q\nbroEIKskuKSI8IrTDGisrJEzI6v8uGSHP/xmmTipfsh4hbWkSg0yANJ5GW6i0BoXb2F58eLlzIh/\nYHnx4uXMyARI2GrQBM0XaQwvzRcBlEr0Q2/v0Mjfb9LqnlviV4GxmsmOnS7SujvYIvSoghkuD1uH\nAOYWaMTm5as+V6SdWV+i6Tun9plJgbi0QNaWPKlxmd9zuR6AFy/wuB9tycv4tXVOQBU5qczJiplk\n3nJSiEbrO5MhYbnKRbD2kDFl0AxL/4eedKtlEb6wopDjZA0GDWIqiDdsaMOmM6rjV+LPn/zxf+Op\nqUPJqz/xkwASaklbV5JVV053DY++dc0ULVxT7t498SjU1YvFAaK8fKLJ+EmoOy5f/7OvOuWzr77K\n8VsdnVEcI11aUye98xioUuaHHxKg3b1HlsF336M7eekck7aMxOKo1wawItJHy7qyOMnqee4b07ob\npd9znyDAXH/IfKumltRdmm6HqxQN9yVITCUVcRKhcGaMGmFF7Xk+wDHpqdFpZZ+4qS9q5tw0d4kF\nyn9MCHJaXZqqaqwXzs7WOoBEwm4sCwnoVhcpc5C0hjqKeinhy/BpWOevLJPPY4SCcX6JE1g8T0io\nWiDEk5zk9LnLTplZYhFYfYdr26jyUdBrdQHEhwjUO929ePFy9sU/sLx48XJmZAIk7AwUycrSvKw2\n2wBmA+YxXblAfoWdp8zHz4hSOp7lgD21NS0V+NWF8yWntMWG/va9BwA+PUuLt6/+qbNqhFNq09Bd\nLNLa31Wkqa7x55dYXbH0SXLX9dplAIevvev+jD0RyZkSQ9DhgTLTtFrbW2JYz/KrxSXOIbTMpePS\nFCWDpWlZ55K0DGYDI8NAlepFEkPGuwEAKJnISAIQ2iccLZ9lDCVtdIAh4erGo3tOeftNbvPCS58G\ncOO5NR43VGBO5S+hzG/VuiBUiHfriFT6777/PadUykQEa4tTANICcYak4sN5n5TyIc3+7S1Gh4si\ncXc9fiz9Jy7YEggJdgWU+ipPefVVNoKdLvFMdxUqvXKFN8ny0iJGCB5aCqpaWZJVPRkpvuHutTXi\nF2OIf+/d72ubY/2N7ISt/slGmx52G1IO4CzTlP7Zr/+aU77x9T/DiFTLjAnub/M3FQq9G+njoM1L\nlVGYu9fnXoYoZ+d51oXcFEa7Gek2tZImi1N3xJ1gg/SN5CNDtFhcZvQ5iAcAkvq9d3RjN5X/Zc2J\nO22udlVpj5DPIUjyx1VcFPdhqw4gkndlSKwxJt7C8uLFy5kR/8Dy4sXLmZEJkHBuhSG5/T3mdzXC\nOoB7t+nbv/aJNad0GoIt1mZqseSUjY9o/1+4QWOynaZlbpmW7+/8EEBngZDhiy+zmj8S9rGoQfeo\nwq80yeSCyKRDmq8fP+UR3/jejwC8+TZzHfd3RUWv9pCZaRqi5+c52yhNxNHscpJz5xm7fKTGXydk\nMNZh1Ux3a76UUDQno7qhuDiwGw3GTF14raXAnIXMNBgySqIb8isoZbGpog2r59gUl8B3X38NwNoa\nif0WloxFm+feEQBsNjnak23u+9YbrzvFKnIiYc9kogAgpRCt0d3FTrfhrUfpkycc/xW5FNKZHEbw\nciTSx0ihUqP0mxGksrzHUIwFT54QwF69Sp+AI1k3EoVvfetbTrlyhZVGX/jCF51ilHV11fHYRbx2\njcU677/3js4xgZFqmJzSa41twtJE84pXfvABu73u7zGebpwlJ2R/m2fR1I2RUd2bK7IBkBPDYlv5\nlvubPMdAZAxdRcAbaAMIAoF3q7ZRpZSVTA079eppEDVVDdZXeZAcFKGrkVIyQEyR/abaO2SGdXVc\nqEi9FMIOsWfYFwmHAsP9QRxARrx9WZ3puHgLy4sXL2dGJlhYbRFLtWj6YHotBT0FAfSsSHJKG8iL\nZtW+GeWMFJSBUpMV0JeVUa40ALx9jw7j888wTeOZWTo+s/L5hUkRb2U4SDWgmfbtr91xyhsPaQ48\n3m4B2N8zm0UdPkIqyQ5fzqlLfJstBKoJGPAEqjID2+Fkp7vVtQ4NBPNiKlUnmeIRb33iJafcvEWq\nKWu5vr+3g5Eim7aKhPoqw47JnLHUtlBtTbtq7T3QscsDlrD8+f/87xjpPvLlX/pFp8wuLGpu/Kq5\nX+EuX2PP+m9+9U95IppMPi2TKhHHSM/xuHUVHbM3TayW5d6Dh065/qzS9xZSGOGPjovkOpIJaVRQ\nRdH4zs5SqSoP7vZt3gBWE+5M0bYYvf/6r//aKVvy+r/4Ii+HFZYfqX7IPPRLSph6+eVP66sGgIE8\n9maLWdccm8Dbb7Oe/zvfYQV1TrZDTR2VTsjhDsMapVleoMVztI7PXVhzSkI20f4eN26UiYH2ldAU\nhyqHum0AAwVbrHIqq/s2pWua0wUKRKqVSakSThXy/SqTGXtIAAhV8xyqRqcrz32nwYu7uMyfc9rY\n01SqFihqFKr9j6Piqje5+PHMNE4Rb2F58eLlzIh/YHnx4uXMyARI2NhTr5oyEc3ctSyAzFVu3D5k\nhkUsI4asZfoFq82KU7ICI2GNVp9Vb5unrdxuAOhUeLjX33/PKfMppvn/xK2XOSc1Oi23SYO7Wabl\n+doP6K28r5YbnU6IkVSRwhxncnRg7SF5XusfMaurrFMunDOuLrqKo+7kFqGFAvFLs6lCkyG7sfmz\niREePX7AvaZoDGdVFbS0vAhgdZWl8115/d97R+k/wqTm6g5VftFpqYmsZtWTv/+oVgHwn3/vd9yf\nFWGHf/wV5gHlp2h1v68DvfXmt51SV1V9X5MJxFvk0GAsZv5aRV1Oh4RGXWCIaWOTiMZl8RgdRVLX\nxbryWGZTSygbch7PzfMm6XRY5fLgARd5cXERwMICoz2vvMLUrbKYy6ybqeVqWR6Wed9tm6MjlZRV\nKqNbGtQ1pg0j3trY2Na+ag8jzpKFhSVMEkOC80ssG5pdEJN4VimBQsopcQ2HXfoEGlXdyYdc27Rb\nOkUthqVgA+MuVzafVdOpUWsQ2PobiQgP7eq3LAjTOlICpk5k0C85JT/FX5AFZHoRx08p4S6pjMVM\ncR5A0rLFEpN/dPAWlhcvXs6Q+AeWFy9ezoxMgIRxVXgvXaAtmk7FAWQTFubjBmbt9xKqrgj4VWGG\nQCyboAnaTyu2JTa+8mETwGKJgzQGtJ//9FtvOmU+e9EpJeV91KVsbBINJT+h5BFGZpDJpQAkSzIv\n01TmphhznFqhRb3+NrHtvoo2ZldpmVfUw7UtxHdCiuIdbLdEN9jkeVnny37IQe7dZ0zw4UPiFwvS\nuUjo/AIBzvwcJ5DSmfa7SoFRPkutxoVqNrkIw+4y4j7sDyIAG4+5wR/9we87JVdkQtPK6iWn/MWf\nf8Mpm0/XOWyDq9Fpc/5pAdgwigMYDCnfrEnLqZDQqkOsaYphw2euXcdIEplFsgZh/8S+KdEePFLW\n1UUlc62uMpq2vs75P/fccxhpRPqlL31Jxz2ZbPVUvID7+4RUH35Ipr23vveWU7a3ie9cuNl4KQyu\njvRGirQlt5kuEncXCvwpWeeeza11jMjNlz7rlHyeW1rxlhUDWVZaUrG5teuf1MY82fe+94ZTeu0u\ngIKikxbCHjoulOTYD23aXPakfukDJXxZLlWQyWKE6zEaqG2SsgLMBtpdZ/S2PctfyvQc7724CK+t\nRVC747rmcJCUmmONi7ewvHjxcmbEP7C8ePFyZmQCJMyr4U1RPUQvXJ8F8MM7TPxbVkX4pSUGAnZV\n9dKrE4OsLNP0zSm8c3+DkLCtINcACQCZoqItClJU+9xyc5eQ5G5tnZ80mSD3cZ2wpT2lXixH3H1p\nrQSgtErz0jIM8zn1Rr1ClLr1A46fXaL5PTXLbZqqLB+oD9AJcdXwABKLXMNDVV1UBDD7keWUqnWo\nslA7TZ5jp1EDUD0kJHma4SJbob9xM3QVAWxLCZLqVSlE0FP4xpF5G+f6wS4Df9/8Kun0Xv4sY2c9\n4b5GXW2NFHy0OVjnzr7LG4xxuQZDropTxaBTX12F/viP/sgpP7p9G8DFiwSns2JxsFRM60h6cEBa\ngoYo5YoCWcaXf/s2i7Fc/K5Q4FUe6XjKRXj0mLhyc2PjxPgGVw022ho6MBgTJDQ+RaOsSAu3GluD\nRRJTuoiJU+Jf88sXTnwyjOvpk1BTiim4ZsHHy9d1RUT7d/eHHwAI1WXWqp0sF3ekPZM+SVvwV+hc\naxskrT1PHkAiZjcGb5VuW12EBectu7jD+wvtpmCjCEhU8IN4vAcgkRCVyODU+8pbWF68eDkz4h9Y\nXrx4OTMyARJeusKMu0jfptsZACW57hemyZnXidPaS7aFfTp8AqYXGAg47NDY3tglYrp6lUVGSwtd\nAM9c5WjVDjfoxrjv1i67ML35FkOAG3VCwsIyJ/P0IyK+XEH8dvMpAPUebdRz1xh3W15lyKbe5S7F\nS5ztuYucUk0lUfNCHIks0dD3cUwW55kBGEW0gRcWGASpVhV8FEjsWddS41Yf0rNFGKWBH1jcTR8M\nDH+JINDaTKq60zItB+JRC3sdAClhq2vXn3PK3/7STznlpU9/ximW3HioCrXvvs7CxksCa5/+LOnY\nb968ASBQBuDOw9s8XLeJU6Qq4vknSsV8eJ/Vo5tPnwJ45hmyLGSEm5rKAbYOWsbk5yKAANYuMDj4\n6BFB9DvKgH3zO28AiFT012jwTrCs2miIRE5y0qcVvbUKR0N8LlJpncfSgntG0mCQMB4XAFSytHWc\nTSm+hncxKplh69BjCBQjNP9x4/vvCxIOI5UEcVdvvOCUfrsJ4PZ7XJNup63RePKdnkqDlR3aU2eD\nXFYhbHlR5PJBv38EoKsaQCPFHzZ80wLavReLCDm7xlCiYmSEOe2VAYBUTrM9tWuct7C8ePFyZmSC\nhVVt0zdZAAtunGft4jJrBeamaY8cpfgqjvZlHClrqVLlJ7WBurHO8bUT6f3sqIU+ukNO2KXzfL7O\nzPMxunFwVwp90k1rsWlJT1V9JPd+LJEBMDUjOp6s2lsuqakJZGq9yNkebNNwyxdFmizH89H+5Dys\nL36BFsq+2py02s0T+z5cp0+301VXVLkZu/KGOl4nM7DsXRYNW+6Ir1Yu9r4GMTe2vYQzWQ50WKkB\nuCmWiN/45//SKZ95hdOeUopQS073e3fotP7wfb79f+4X/q5Tfukf/CPuNT0NoFmhG/sN7buhTqvj\nsrXJ9anVaOksKNcsk0kD6Gkp2upZ27OIh8wB69L+8D7tqVyed8uDdVbkHBxUdMxjRmtS61bIyziy\nlrFKJDRzID1mIGQUg8pkUhih0DLrJjhuggFIylJIKOFopFvSZBMhqSlZoMNylMxUtES8hPLgBjLc\nLGkrIVf9jRdeBtBq0ai5/8EPOIhW0orAWnbz6ExjWrFBk18FwlJB1McInUZS1mWgTqsJ8WHF9QnE\nyt0XzVY/xgsdxBSSC+Yw8isITk/r8xaWFy9ezoz4B5YXL17OjEyAhNu79MKuFpXFE08BaIpWITND\nk/7CCt3zd7dURw6a/QUZw9tbhA8lpTh1zATNJQFEkVhWldRzbpH7fniPVRGxpMZXV9NiUWRgU9xr\nYZkYp13rAFh7hvwHyRwfyo0y5185UvqVeMJmL/KTeXEA1I8YK+juNzBJDg+UwqM0H2uxaRxvhZyh\nCUMECW0jBypcdo+Sbsx9bqkoMpQNephVH/ZPwtVQpRJ75SaAF18ScaB81eZGNT+9ES5nld2zep5L\n94mbJK1eUOVQFE8ASCphan6ezoGn9+7gFAlUtHHrJutIhq1n3alZkpq1hwmPRSQwQlTQVdTi3r11\npzTE+ra6yj43zi9uLvBA7nMrYDLcZwlf44pBQnO6u3HSY5/Hx+DeQFUv1p7HEvHCU/ggrVTLxCCt\nQcL4WHseA4mB3PBxa2A8dx7ArZc+7/5si4P76b27OoAG6YttQkVg+4cVp+RErJLPceNsEAOQVH6W\nZaVZfZXlcA2MgTLiXRopB03ngU5f+X2dEEAhrcXpTaY5hLewvHjxcobEP7C8ePFyZmQCJCxkS045\nPFLuxsERgNUrRIKtGGN2hYCQoVVXTFB0ffkkU3gWisRWTZmgrRbtwOBcCkCyTpPeSCAOmkRhCVn1\nn3xZTVJlUffE8r52i0qzI8tzJwSQFmX13CoL1ntCgrvrBHE9NYzZrVd4RlOMLQ7SHDY7Y2Xox+T+\nvfvc0qCbnv5WXp9StCUhI3jY2FLicITV90OUeEbTbkBjZF8hjUFaX4kWXUh8bj4GIKZKnW//1Z/z\n8wVGfjOK71TLjJDubjFP6rkbxFZPHzL29790fePpNIC45nawyUY48eSEG8lJLq9CrktqeGNlIt0e\nRtCxYUNrm2p8+QYJLcxquNLKOKxOxS2UIcGE8EtSobRAs53wifYajqayJ4fRDKlZOG88lDmIxj7R\nNoYNT0jSgmtDkGUtT3HiiBZBNkgY9jVJW8xYDMDSeV7KT73605yJWvk+EcU+IkvR4g9ETPfogJfM\negO7HqvDoOfwxtMGYpFPWsOejKj6k7oBAiY5tjXtVK8DIKuYJlIWNT8p3sLy4sXLmRH/wPLixcuZ\nkQmW/Pwci042HjClc7G4CKh/ELC9w2L3QJDkwnnxT0eMu8WU5n9xiSR8bdnJsbZ6eeYA4EmbhRqF\nGU5m/4ClLZHophPJklPCNHFf44hKaZogbiHNkOXTyh6AvQ2al0m1EJ0WCEoIdh3UCFcz6niaVQzI\nSsxXnyGG+g6OSZBguE3l8cN0PoOE4zGUIaAYtiCNYwS2GAG2dScbggj9nxwr1h/GnnRExxk/UBHS\n+l3mDT5ZVzhpSPKt6yIWjYUZUSqWWazTrIrlPZ7ACDaBtYxNnlpLYdBsGE3T+jhsaHBp2IzVYmrD\nuOFgdJeRTWDrYkR6bpFHcjWFx4dxvZOMC8NLNo5FdCAHQi1mNzLZcZR3at7jaWKztSkZHLbZWojZ\nwqmRSA9jcgWEKYOlEUbWdukCm8je+hR/XNUKXQHbm/TA9HuRRtOBRC1h/b7q7RBAT3QdCd2KNqVA\nFJ6BuAOT6otcVd1Y45AgNKXSpekgASBUAVYrOtWQ8haWFy9evHjx4sWLFy9evHjx4sWLFy9evHjx\n4sWLFy9evHjx4uX/UfnfwKeFo1TDJLIAAAAASUVORK5CYII=\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 44
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "rnmDYZGh4kB6",
+ "colab_type": "text"
+ },
+ "source": [
+ "## 定义网络\n",
+ "\n",
+ "拷贝上面的LeNet网络,修改self.conv1第一个参数为3通道,因CIFAR-10是3通道彩图"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "VT1NhD1I4Tbz",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "source": [
+ "class LeNet(nn.Module):\n",
+ " def __init__(self):\n",
+ " super(LeNet, self).__init__()\n",
+ " self.conv1 = nn.Conv2d(3, 6, 5)\n",
+ " self.conv2 = nn.Conv2d(6, 16, 5)\n",
+ " self.fc1 = nn.Linear(16*5*5, 120)\n",
+ " self.fc2 = nn.Linear(120, 84)\n",
+ " self.fc3 = nn.Linear(84, 10)\n",
+ " \n",
+ " def forward(self, x):\n",
+ " x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))\n",
+ " x = F.max_pool2d(F.relu(self.conv2(x)), 2)\n",
+ " x = x.view(x.size()[0], -1)\n",
+ " x = F.relu(self.fc1(x))\n",
+ " x = F.relu(self.fc2(x))\n",
+ " x = self.fc3(x)\n",
+ " \n",
+ " return x\n",
+ " "
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "q7-g11Io6p2w",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 143
+ },
+ "outputId": "e90e1521-b3e4-4c54-c582-e521834bdeb7"
+ },
+ "source": [
+ "net = LeNet()\n",
+ "print(net)"
+ ],
+ "execution_count": 46,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "LeNet(\n",
+ " (conv1): Conv2d(3, 6, kernel_size=(5, 5), stride=(1, 1))\n",
+ " (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))\n",
+ " (fc1): Linear(in_features=400, out_features=120, bias=True)\n",
+ " (fc2): Linear(in_features=120, out_features=84, bias=True)\n",
+ " (fc3): Linear(in_features=84, out_features=10, bias=True)\n",
+ ")\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "0wHFeKLA61R1",
+ "colab_type": "text"
+ },
+ "source": [
+ "## 定义损失函数和优化器"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "X9vvj7Ca6zSj",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "source": [
+ "from torch import optim\n",
+ "criterion = nn.CrossEntropyLoss()\n",
+ "opti = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)"
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "oNtcwaYX7gqN",
+ "colab_type": "text"
+ },
+ "source": [
+ "## 训练网络\n",
+ "所有网络的训练流程都类似的,不断地执行如下流程:\n",
+ "\n",
+ "* 输入数据\n",
+ "* 前向传播+反向传播\n",
+ "* 更新参数\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "5pE0O94o7fOh",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 251
+ },
+ "outputId": "6d0148df-4a52-4e0b-ebfc-e59e3ca153a0"
+ },
+ "source": [
+ "t.set_num_threads(8)\n",
+ "for epoch in range(2):\n",
+ " \n",
+ " running_loss = 0.0\n",
+ " \n",
+ " for i, data in enumerate(trainloader, 0):\n",
+ " \n",
+ " input, label = data\n",
+ "\n",
+ " # 梯度清零\n",
+ " opti.zero_grad()\n",
+ " \n",
+ " # 输入数据\n",
+ " output = net(input)\n",
+ " # 前向传播\n",
+ " loss = criterion(output, label)\n",
+ " # 反向传播\n",
+ " loss.backward()\n",
+ " \n",
+ " # 更新参数\n",
+ " opti.step()\n",
+ " \n",
+ " # 打印log参数\n",
+ " # loss 是一个scalar,需用使用loss.item()来获取值,不能是用loss[0]\n",
+ " running_loss += loss.item()\n",
+ " if i % 2000 == 1999:# 每2000个batch打印一下训练状态\n",
+ " print('[%d, %5d] loss: %.3f' \\\n",
+ " % (epoch+1, i+1, running_loss / 2000))\n",
+ " running_loss = 0.0\n",
+ " \n",
+ "\n",
+ "print('Finished Training') \n",
+ " \n"
+ ],
+ "execution_count": 48,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "[1, 2000] loss: 2.178\n",
+ "[1, 4000] loss: 1.837\n",
+ "[1, 6000] loss: 1.691\n",
+ "[1, 8000] loss: 1.570\n",
+ "[1, 10000] loss: 1.513\n",
+ "[1, 12000] loss: 1.449\n",
+ "[2, 2000] loss: 1.394\n",
+ "[2, 4000] loss: 1.375\n",
+ "[2, 6000] loss: 1.336\n",
+ "[2, 8000] loss: 1.301\n",
+ "[2, 10000] loss: 1.296\n",
+ "[2, 12000] loss: 1.275\n",
+ "Finished Training\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "YEzGRZ0mBVJO",
+ "colab_type": "text"
+ },
+ "source": [
+ "此处训练了2个epoch(遍历完一遍数据集称为一个epoch),来看看网络有没有效果。将测试图片输入到网络中,计算它的label,然后与实际的label进行比较。"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "A1bnWKRiBxGi",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 135
+ },
+ "outputId": "3e75d047-b935-43df-b912-f549cc228242"
+ },
+ "source": [
+ "dataiter = iter(testloader)\n",
+ "images, labels = dataiter.next() # 一个batch返回4张图片\n",
+ "print('实际的label: ', ' '.join(\\\n",
+ " '%08s'%classes[labels[j]] for j in range(4)))\n",
+ "show(tv.utils.make_grid(images / 2 - 0.5)).resize((400,100))"
+ ],
+ "execution_count": 49,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "实际的label: cat ship ship plane\n"
+ ],
+ "name": "stdout"
+ },
+ {
+ "output_type": "execute_result",
+ "data": {
+ "image/png": "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\nEyf/z8r/Ab+8NWulkQjIAAAAAElFTkSuQmCC\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 49
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "08fGnBfwD4EY",
+ "colab_type": "code",
+ "colab": {}
+ },
+ "source": [
+ "correct = 0 # 预测正确的图片数\n",
+ "total = 0 # "
+ ],
+ "execution_count": 0,
+ "outputs": []
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "aqBaRvMCEExC",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ },
+ "outputId": "1f2504fb-7f4c-4068-e485-f92d5c7bbfa0"
+ },
+ "source": [
+ "# 计算图片在每个类别上的分数\n",
+ "outputs = net(images)\n",
+ "# 得分最高得那个类\n",
+ "_, predicted = t.max(outputs.data, 1)\n",
+ "\n",
+ "print('预测结果: ', ' '.join('%5s'\\\n",
+ " % classes[predicted[j]] for j in range(4)))"
+ ],
+ "execution_count": 58,
+ "outputs": [
+ {
+ "output_type": "stream",
+ "text": [
+ "预测结果: cat car ship ship\n"
+ ],
+ "name": "stdout"
+ }
+ ]
+ },
+ {
+ "cell_type": "code",
+ "metadata": {
+ "id": "mgVs57EpEy5q",
+ "colab_type": "code",
+ "colab": {
+ "base_uri": "https://localhost:8080/",
+ "height": 35
+ },
+ "outputId": "4763060a-4af0-4e01-a1ea-5c1452ae7233"
+ },
+ "source": [
+ "# 在GPU训练\n",
+ "device = t.device(\"cuda:0\" if t.cuda.is_available() else \"cpu\")\n",
+ "\n",
+ "net.to(device)\n",
+ "images = images.to(device)\n",
+ "labels = labels.to(device)\n",
+ "output = net(images)\n",
+ "loss= criterion(output,labels)\n",
+ "\n",
+ "loss\n",
+ "\n",
+ "# 如果发现在GPU上并没有比CPU提速很多,实际上是因为网络比较小,GPU没有完全发挥自己的真正实力。"
+ ],
+ "execution_count": 59,
+ "outputs": [
+ {
+ "output_type": "execute_result",
+ "data": {
+ "text/plain": [
+ "tensor(1.2888, device='cuda:0', grad_fn=)"
+ ]
+ },
+ "metadata": {
+ "tags": []
+ },
+ "execution_count": 59
+ }
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {
+ "id": "LwyYI8m7Fp6P",
+ "colab_type": "text"
+ },
+ "source": [
+ "对PyTorch的基础介绍至此结束。总结一下,本节主要包含一下内容。\n",
+ "\n",
+ "\n",
+ "1. Tensor:类似与numpy的array的数据结构,与Numpy的接口类似,可以方便地互相转换。\n",
+ "2. autograd:为tensor提供自动求导功能\n",
+ "3. nn:为神经网络设计的接口,提供了很多有用的功能(神经网络层,损失函数,优化器)\n",
+ "4. 神经网络的训练:以CIFAR-10分类为例演示了神经网络的训练流程,包括数据加载,网络搭建,训练,以及测试。\n"
+ ]
+ }
+ ]
+}
\ No newline at end of file
From 16aab3b9a67f5a7779c89a912d0b4fc4470310eb Mon Sep 17 00:00:00 2001
From: Chuan <41295406+caalinlu@users.noreply.github.com>
Date: Mon, 20 May 2019 20:03:28 +0800
Subject: [PATCH 4/4] =?UTF-8?q?Delete=20=E7=94=A8PyTorch=E5=AE=9E=E7=8E=B0?=
=?UTF-8?q?=E5=A4=9A=E5=B1=82=E7=BD=91=E7=BB=9C=EF=BC=88LeNet).ipynb?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...5\221\347\273\234\357\274\210LeNet).ipynb" | 949 ------------------
1 file changed, 949 deletions(-)
delete mode 100644 "\347\224\250PyTorch\345\256\236\347\216\260\345\244\232\345\261\202\347\275\221\347\273\234\357\274\210LeNet).ipynb"
diff --git "a/\347\224\250PyTorch\345\256\236\347\216\260\345\244\232\345\261\202\347\275\221\347\273\234\357\274\210LeNet).ipynb" "b/\347\224\250PyTorch\345\256\236\347\216\260\345\244\232\345\261\202\347\275\221\347\273\234\357\274\210LeNet).ipynb"
deleted file mode 100644
index dabc7aa..0000000
--- "a/\347\224\250PyTorch\345\256\236\347\216\260\345\244\232\345\261\202\347\275\221\347\273\234\357\274\210LeNet).ipynb"
+++ /dev/null
@@ -1,949 +0,0 @@
-{
- "nbformat": 4,
- "nbformat_minor": 0,
- "metadata": {
- "colab": {
- "name": "用PyTorch实现多层网络(LeNet).ipynb",
- "version": "0.3.2",
- "provenance": [],
- "include_colab_link": true
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.6.5"
- },
- "kernelspec": {
- "display_name": "pytorch",
- "language": "python",
- "name": "pytorch"
- },
- "accelerator": "GPU"
- },
- "cells": [
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "view-in-github",
- "colab_type": "text"
- },
- "source": [
- "
"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "WHKI4G1G9dNO",
- "colab_type": "text"
- },
- "source": [
- "## 神经网络\n",
- "Autograd实现了反向传播功能,但是直接用来写深度学习的代码在很多情况下还是稍显复杂,torch.nn是专门为神经网络设计的模块化接口。\n",
- "nn构建于Autograded智商,可以用来定义和运行神经网络。nn.Module是nn中最重要的类,可把它看成是一个网络的封装,包含网络各层定义以及forward方法,调用forward(input)方法,可返回前向传播的结果。下面就以最早的卷积神经网络LeNet为例,来看看如何用nn.Module实现。\n",
- "这是一个基础的前向传播(feed-forward)网络: 接收输入,经过层层传递运算,得到输出。\n",
- "### 定义网络\n",
- "定义网络是,需要继承nn.Module,并实践它的forward方法,把网络中具有可学习参数的层放在构造函数`__init__`中。如果某一层(如ReLU)不具有可学习的参数,则既可以放在构造函数中,也可以不放,但建议不放在其中,而在forward中使用nn.functional代替。"
- ]
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "VOKstA6u9dNP",
- "colab_type": "code",
- "colab": {}
- },
- "source": [
- "import torch.nn as nn\n",
- "import torch.nn.functional as F\n",
- "\n",
- "class Net(nn.Module):\n",
- " def __init__(self):\n",
- " # nn.Module子类的函数必须在构造函数中执行父类的构造函数\n",
- " # 下式等价于nn.Module.__init__(self)\n",
- " super(Net, self).__init__()\n",
- " \n",
- " # 卷积层‘1’表示输入图片为单通道,‘6’表示输出通道数,‘5’表示卷积核为5\n",
- " self.conv1 = nn.Conv2d(1, 6, 5)\n",
- " # 卷积层\n",
- " self.conv2 = nn.Conv2d(6, 16, 5)\n",
- " # 仿射层/全连接层,y = Wx + b\n",
- " self.fc1 = nn.Linear(16*5*5, 120)\n",
- " self.fc2 = nn.Linear(120, 84)\n",
- " self.fc3 = nn.Linear(84, 10)\n",
- " \n",
- " def forward(self, x):\n",
- " # 卷积 -> 激活 -> 池化\n",
- " x = F.max_pool2d(F.relu(self.conv1(x)), (2,2))\n",
- " x = F.max_pool2d(F.relu(self.conv2(x)), 2)\n",
- " # reshape, '-1'表示自适应\n",
- " x = x.view(x.size()[0], -1)\n",
- " x = F.relu(self.fc1(x))\n",
- " x = F.relu(self.fc2(x))\n",
- " x = self.fc3(x)\n",
- " \n",
- " return x\n",
- " \n"
- ],
- "execution_count": 0,
- "outputs": []
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "YsWYbzgHAcsK",
- "colab_type": "code",
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 143
- },
- "outputId": "7d1f8fd2-db5d-4e30-c0b2-f28755eced37"
- },
- "source": [
- "net = Net()\n",
- "print(net)"
- ],
- "execution_count": 32,
- "outputs": [
- {
- "output_type": "stream",
- "text": [
- "Net(\n",
- " (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))\n",
- " (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))\n",
- " (fc1): Linear(in_features=400, out_features=120, bias=True)\n",
- " (fc2): Linear(in_features=120, out_features=84, bias=True)\n",
- " (fc3): Linear(in_features=84, out_features=10, bias=True)\n",
- ")\n"
- ],
- "name": "stdout"
- }
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "eYmtrNk7Cd5z",
- "colab_type": "text"
- },
- "source": [
- "只要在nn.Module的子类中定义了forward函数,backward函数就会自动被实现(利用autograd)。在forward函数中可以使用任何tensor支持的函数,还可以使用if、for循环、print、log等Python语法,写法和标准的Python写法一致。"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "MWl5QFKcDMho",
- "colab_type": "text"
- },
- "source": [
- "网络可学习参数通过net.parameters()返回,net.named_parameters可同时返回可学习的参数及名称。"
- ]
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "x441tWy4CTl9",
- "colab_type": "code",
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 35
- },
- "outputId": "e6ea3c39-6176-4703-a89f-24a9ce698852"
- },
- "source": [
- "para = list(net.parameters())\n",
- "print(len(para[9]))"
- ],
- "execution_count": 33,
- "outputs": [
- {
- "output_type": "stream",
- "text": [
- "10\n"
- ],
- "name": "stdout"
- }
- ]
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "Eu3yhdNaHY9v",
- "colab_type": "code",
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 197
- },
- "outputId": "6f5b21f7-eea1-4484-f1b5-adc30a08d7cc"
- },
- "source": [
- "for name, parameter in net.named_parameters():\n",
- " print(name, ':', parameter.size())"
- ],
- "execution_count": 34,
- "outputs": [
- {
- "output_type": "stream",
- "text": [
- "conv1.weight : torch.Size([6, 1, 5, 5])\n",
- "conv1.bias : torch.Size([6])\n",
- "conv2.weight : torch.Size([16, 6, 5, 5])\n",
- "conv2.bias : torch.Size([16])\n",
- "fc1.weight : torch.Size([120, 400])\n",
- "fc1.bias : torch.Size([120])\n",
- "fc2.weight : torch.Size([84, 120])\n",
- "fc2.bias : torch.Size([84])\n",
- "fc3.weight : torch.Size([10, 84])\n",
- "fc3.bias : torch.Size([10])\n"
- ],
- "name": "stdout"
- }
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "cb7t6T8DIxzG",
- "colab_type": "text"
- },
- "source": [
- "forward函数的输入和输出都是Tensor。"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "MqJxKB26M5-M",
- "colab_type": "text"
- },
- "source": [
- "需要注意的是,torch.nn只支持mini_batches,不支持一次只输入一个样本,即一次必须是一个batch。但如果指向输入一个样本,则用input.unsqueeze(0)将batch_size设为1.例如nn.Conv2d的输入必须是4维的,形如nSamples * nChannel * Height * Width "
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "iPUzeITEOjQV",
- "colab_type": "text"
- },
- "source": [
- "## 损失函数"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "oc6rdzMOPA-7",
- "colab_type": "text"
- },
- "source": [
- " nn实现了神经网络中大多数的损失函数,例如nn.MSELoss用来计算均方误差,nn.CrossEntropyLoss用来计算交叉熵损失。"
- ]
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "cw_muTHjOhDI",
- "colab_type": "code",
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 35
- },
- "outputId": "c1e2f844-5e3c-4285-e93e-ba76f54ad69e"
- },
- "source": [
- "input = t.randn(1, 1, 32, 32)\n",
- "output = net(input)\n",
- "target = t.arange(0, 10).view(1, 10)\n",
- "target = target.float()\n",
- "criterion = nn.MSELoss()\n",
- "loss = criterion(output, target)\n",
- "print(loss)"
- ],
- "execution_count": 38,
- "outputs": [
- {
- "output_type": "stream",
- "text": [
- "tensor(28.6133, grad_fn=)\n"
- ],
- "name": "stdout"
- }
- ]
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "EYeKGUHpRoha",
- "colab_type": "code",
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 89
- },
- "outputId": "5d28fb8f-760d-4fe0-8f5f-10eed3372e8c"
- },
- "source": [
- "# 运行backward, 观察调用之前和调用之后的grad\n",
- "net.zero_grad() # 把net中所有可学习的参数清零\n",
- "print('反向传播之前 conv1.bias的梯度')\n",
- "print(net.conv1.bias.grad)\n",
- "loss.backward()\n",
- "print('反向传播之后 conv1.bias的梯度')\n",
- "print(net.conv1.bias.grad)"
- ],
- "execution_count": 39,
- "outputs": [
- {
- "output_type": "stream",
- "text": [
- "反向传播之前 conv1.bias的梯度\n",
- "None\n",
- "反向传播之后 conv1.bias的梯度\n",
- "tensor([ 0.0448, -0.1094, -0.0264, 0.0420, 0.0564, 0.0838])\n"
- ],
- "name": "stdout"
- }
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "ZSciQPl8S6_V",
- "colab_type": "text"
- },
- "source": [
- "## 优化器"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "viVhJAMGTIZj",
- "colab_type": "text"
- },
- "source": [
- "在反向传播计算完所有参数的梯度后,还需要使用优化方法来更新网络的权重和参数,例如随机梯度下降法(SGD)的更新策略如下:"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "4_bXHGZZTO1Q",
- "colab_type": "text"
- },
- "source": [
- "weight = weight - learning_rate * gradient"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "lkw0Z_AiTyae",
- "colab_type": "text"
- },
- "source": [
- "**手动实现如下**"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "8stHZQ1dUDKc",
- "colab_type": "text"
- },
- "source": [
- "\n",
- "\n",
- "```\n",
- "learning_rate = 0.1\n",
- "\n",
- "for f in net.parameters(): \n",
- " f.data.sub_(f.grad.data * learning_rate)\n",
- "```\n",
- "\n"
- ]
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "5lr8k4NQT5rt",
- "colab_type": "code",
- "colab": {}
- },
- "source": [
- "import torch.optim as optim\n",
- "# 新建一个优化器,设置优化器类型和学习率\n",
- "op = optim.SGD(net.parameters(), lr = 0.1)\n",
- "\n",
- "\n",
- "# 首先清零梯度\n",
- "op.zero_grad()\n",
- "\n",
- "# 前向传播,计算损失\n",
- "output = net(input)\n",
- "loss = criterion(output, target)\n",
- "\n",
- "# 反向传播\n",
- "loss.backward()\n",
- "\n",
- "# 参数调整\n",
- "op.step()"
- ],
- "execution_count": 0,
- "outputs": []
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "rO23ulanYMhW",
- "colab_type": "text"
- },
- "source": [
- "## 数据加载与预处理\n",
- "\n",
- "\n",
- "在深度学习中数据加载及预处理是非常复杂繁琐的,但PyTorch提供了一些可极大简化和加快处理流程的工具。同时,对于常用的数据集,PyTorch也提供了封装好的接口供用户快速调用,这些数据集主要保存在torchvision中。\n",
- "torchvision实现了常用的图像数据加载功能,例如Imagenet、CIFAR10、MNIST等,以及常用的数据转换操作,这极大地方便了数据加载,并且代码具有可重用性。"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "uC30PgfRZkU9",
- "colab_type": "text"
- },
- "source": [
- "## 小试牛刀:CIFAR-10分类"
- ]
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "m-wiJ_QwZobt",
- "colab_type": "code",
- "colab": {}
- },
- "source": [
- "import torchvision as tv\n",
- "import torchvision.transforms as transforms\n",
- "from torchvision.transforms import ToPILImage\n",
- "show = ToPILImage() # 可以把Tensor转成Image,方便可视化"
- ],
- "execution_count": 0,
- "outputs": []
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "U5QtY3ljb1MJ",
- "colab_type": "code",
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 53
- },
- "outputId": "ab94a1a0-5ef7-4e2e-d07b-e0e7f7781fc7"
- },
- "source": [
- "# 第一次运行程序torchvision会自动下载CIFAR-10数据集,\n",
- "# 大约100M,需花费一定的时间,\n",
- "# 如果已经下载有CIFAR-10,可通过root参数指定\n",
- "\n",
- "# 定义对数据的预处理\n",
- "transform = transforms.Compose([\n",
- " transforms.ToTensor(), # 转为Tensor\n",
- " transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)), # 归一化\n",
- " ])\n",
- "\n",
- "# 训练集\n",
- "trainset = tv.datasets.CIFAR10(\n",
- " root='/home/cy/tmp/data/', \n",
- " train=True, \n",
- " download=True,\n",
- " transform=transform)\n",
- "\n",
- "trainloader = t.utils.data.DataLoader(\n",
- " trainset, \n",
- " batch_size=4,\n",
- " shuffle=True, \n",
- " num_workers=2)\n",
- "\n",
- "# 测试集\n",
- "testset = tv.datasets.CIFAR10(\n",
- " '/home/cy/tmp/data/',\n",
- " train=False, \n",
- " download=True, \n",
- " transform=transform)\n",
- "\n",
- "testloader = t.utils.data.DataLoader(\n",
- " testset,\n",
- " batch_size=4, \n",
- " shuffle=False,\n",
- " num_workers=2)\n",
- "\n",
- "classes = ('plane', 'car', 'bird', 'cat',\n",
- " 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')"
- ],
- "execution_count": 42,
- "outputs": [
- {
- "output_type": "stream",
- "text": [
- "\r0it [00:00, ?it/s]"
- ],
- "name": "stderr"
- },
- {
- "output_type": "stream",
- "text": [
- "Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to /home/cy/tmp/data/cifar-10-python.tar.gz\n"
- ],
- "name": "stdout"
- },
- {
- "output_type": "stream",
- "text": [
- "100%|█████████▉| 170459136/170498071 [00:14<00:00, 14320972.23it/s]"
- ],
- "name": "stderr"
- },
- {
- "output_type": "stream",
- "text": [
- "Files already downloaded and verified\n"
- ],
- "name": "stdout"
- }
- ]
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "Y52AOzJYf4qA",
- "colab_type": "code",
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 135
- },
- "outputId": "0345efb6-b312-4929-bb40-4753ecc2bf2e"
- },
- "source": [
- "(data, label) = trainset[100]\n",
- "print(classes[label])\n",
- "\n",
- "# (data + 1) / 2是为了还原被归一化的数据\n",
- "show((data + 1) / 2).resize((100, 100))"
- ],
- "execution_count": 43,
- "outputs": [
- {
- "output_type": "stream",
- "text": [
- "ship\n"
- ],
- "name": "stdout"
- },
- {
- "output_type": "execute_result",
- "data": {
- "image/png": "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\n",
- "text/plain": [
- ""
- ]
- },
- "metadata": {
- "tags": []
- },
- "execution_count": 43
- }
- ]
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "2w42GpDS3sAF",
- "colab_type": "code",
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 135
- },
- "outputId": "b017d14a-4255-419d-a094-0979cc144ac3"
- },
- "source": [
- "dataiter = iter(trainloader)\n",
- "# trainloader中batchsize为4,迭代器一次读4张图\n",
- "images, labels = dataiter.next()\n",
- "print(' '.join('%11s'%classes[labels[j]] for j in range(4)))\n",
- "show(tv.utils.make_grid((images+1)/2)).resize((400,100))"
- ],
- "execution_count": 44,
- "outputs": [
- {
- "output_type": "stream",
- "text": [
- " bird cat car cat\n"
- ],
- "name": "stdout"
- },
- {
- "output_type": "execute_result",
- "data": {
- "image/png": "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\n",
- "text/plain": [
- ""
- ]
- },
- "metadata": {
- "tags": []
- },
- "execution_count": 44
- }
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "rnmDYZGh4kB6",
- "colab_type": "text"
- },
- "source": [
- "## 定义网络\n",
- "\n",
- "拷贝上面的LeNet网络,修改self.conv1第一个参数为3通道,因CIFAR-10是3通道彩图"
- ]
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "VT1NhD1I4Tbz",
- "colab_type": "code",
- "colab": {}
- },
- "source": [
- "class LeNet(nn.Module):\n",
- " def __init__(self):\n",
- " super(LeNet, self).__init__()\n",
- " self.conv1 = nn.Conv2d(3, 6, 5)\n",
- " self.conv2 = nn.Conv2d(6, 16, 5)\n",
- " self.fc1 = nn.Linear(16*5*5, 120)\n",
- " self.fc2 = nn.Linear(120, 84)\n",
- " self.fc3 = nn.Linear(84, 10)\n",
- " \n",
- " def forward(self, x):\n",
- " x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))\n",
- " x = F.max_pool2d(F.relu(self.conv2(x)), 2)\n",
- " x = x.view(x.size()[0], -1)\n",
- " x = F.relu(self.fc1(x))\n",
- " x = F.relu(self.fc2(x))\n",
- " x = self.fc3(x)\n",
- " \n",
- " return x\n",
- " "
- ],
- "execution_count": 0,
- "outputs": []
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "q7-g11Io6p2w",
- "colab_type": "code",
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 143
- },
- "outputId": "e90e1521-b3e4-4c54-c582-e521834bdeb7"
- },
- "source": [
- "net = LeNet()\n",
- "print(net)"
- ],
- "execution_count": 46,
- "outputs": [
- {
- "output_type": "stream",
- "text": [
- "LeNet(\n",
- " (conv1): Conv2d(3, 6, kernel_size=(5, 5), stride=(1, 1))\n",
- " (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))\n",
- " (fc1): Linear(in_features=400, out_features=120, bias=True)\n",
- " (fc2): Linear(in_features=120, out_features=84, bias=True)\n",
- " (fc3): Linear(in_features=84, out_features=10, bias=True)\n",
- ")\n"
- ],
- "name": "stdout"
- }
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "0wHFeKLA61R1",
- "colab_type": "text"
- },
- "source": [
- "## 定义损失函数和优化器"
- ]
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "X9vvj7Ca6zSj",
- "colab_type": "code",
- "colab": {}
- },
- "source": [
- "from torch import optim\n",
- "criterion = nn.CrossEntropyLoss()\n",
- "opti = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)"
- ],
- "execution_count": 0,
- "outputs": []
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "oNtcwaYX7gqN",
- "colab_type": "text"
- },
- "source": [
- "## 训练网络\n",
- "所有网络的训练流程都类似的,不断地执行如下流程:\n",
- "\n",
- "* 输入数据\n",
- "* 前向传播+反向传播\n",
- "* 更新参数\n"
- ]
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "5pE0O94o7fOh",
- "colab_type": "code",
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 251
- },
- "outputId": "6d0148df-4a52-4e0b-ebfc-e59e3ca153a0"
- },
- "source": [
- "t.set_num_threads(8)\n",
- "for epoch in range(2):\n",
- " \n",
- " running_loss = 0.0\n",
- " \n",
- " for i, data in enumerate(trainloader, 0):\n",
- " \n",
- " input, label = data\n",
- "\n",
- " # 梯度清零\n",
- " opti.zero_grad()\n",
- " \n",
- " # 输入数据\n",
- " output = net(input)\n",
- " # 前向传播\n",
- " loss = criterion(output, label)\n",
- " # 反向传播\n",
- " loss.backward()\n",
- " \n",
- " # 更新参数\n",
- " opti.step()\n",
- " \n",
- " # 打印log参数\n",
- " # loss 是一个scalar,需用使用loss.item()来获取值,不能是用loss[0]\n",
- " running_loss += loss.item()\n",
- " if i % 2000 == 1999:# 每2000个batch打印一下训练状态\n",
- " print('[%d, %5d] loss: %.3f' \\\n",
- " % (epoch+1, i+1, running_loss / 2000))\n",
- " running_loss = 0.0\n",
- " \n",
- "\n",
- "print('Finished Training') \n",
- " \n"
- ],
- "execution_count": 48,
- "outputs": [
- {
- "output_type": "stream",
- "text": [
- "[1, 2000] loss: 2.178\n",
- "[1, 4000] loss: 1.837\n",
- "[1, 6000] loss: 1.691\n",
- "[1, 8000] loss: 1.570\n",
- "[1, 10000] loss: 1.513\n",
- "[1, 12000] loss: 1.449\n",
- "[2, 2000] loss: 1.394\n",
- "[2, 4000] loss: 1.375\n",
- "[2, 6000] loss: 1.336\n",
- "[2, 8000] loss: 1.301\n",
- "[2, 10000] loss: 1.296\n",
- "[2, 12000] loss: 1.275\n",
- "Finished Training\n"
- ],
- "name": "stdout"
- }
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "YEzGRZ0mBVJO",
- "colab_type": "text"
- },
- "source": [
- "此处训练了2个epoch(遍历完一遍数据集称为一个epoch),来看看网络有没有效果。将测试图片输入到网络中,计算它的label,然后与实际的label进行比较。"
- ]
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "A1bnWKRiBxGi",
- "colab_type": "code",
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 135
- },
- "outputId": "3e75d047-b935-43df-b912-f549cc228242"
- },
- "source": [
- "dataiter = iter(testloader)\n",
- "images, labels = dataiter.next() # 一个batch返回4张图片\n",
- "print('实际的label: ', ' '.join(\\\n",
- " '%08s'%classes[labels[j]] for j in range(4)))\n",
- "show(tv.utils.make_grid(images / 2 - 0.5)).resize((400,100))"
- ],
- "execution_count": 49,
- "outputs": [
- {
- "output_type": "stream",
- "text": [
- "实际的label: cat ship ship plane\n"
- ],
- "name": "stdout"
- },
- {
- "output_type": "execute_result",
- "data": {
- "image/png": "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\nEyf/z8r/Ab+8NWulkQjIAAAAAElFTkSuQmCC\n",
- "text/plain": [
- ""
- ]
- },
- "metadata": {
- "tags": []
- },
- "execution_count": 49
- }
- ]
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "08fGnBfwD4EY",
- "colab_type": "code",
- "colab": {}
- },
- "source": [
- "correct = 0 # 预测正确的图片数\n",
- "total = 0 # "
- ],
- "execution_count": 0,
- "outputs": []
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "aqBaRvMCEExC",
- "colab_type": "code",
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 35
- },
- "outputId": "1f2504fb-7f4c-4068-e485-f92d5c7bbfa0"
- },
- "source": [
- "# 计算图片在每个类别上的分数\n",
- "outputs = net(images)\n",
- "# 得分最高得那个类\n",
- "_, predicted = t.max(outputs.data, 1)\n",
- "\n",
- "print('预测结果: ', ' '.join('%5s'\\\n",
- " % classes[predicted[j]] for j in range(4)))"
- ],
- "execution_count": 58,
- "outputs": [
- {
- "output_type": "stream",
- "text": [
- "预测结果: cat car ship ship\n"
- ],
- "name": "stdout"
- }
- ]
- },
- {
- "cell_type": "code",
- "metadata": {
- "id": "mgVs57EpEy5q",
- "colab_type": "code",
- "colab": {
- "base_uri": "https://localhost:8080/",
- "height": 35
- },
- "outputId": "4763060a-4af0-4e01-a1ea-5c1452ae7233"
- },
- "source": [
- "# 在GPU训练\n",
- "device = t.device(\"cuda:0\" if t.cuda.is_available() else \"cpu\")\n",
- "\n",
- "net.to(device)\n",
- "images = images.to(device)\n",
- "labels = labels.to(device)\n",
- "output = net(images)\n",
- "loss= criterion(output,labels)\n",
- "\n",
- "loss\n",
- "\n",
- "# 如果发现在GPU上并没有比CPU提速很多,实际上是因为网络比较小,GPU没有完全发挥自己的真正实力。"
- ],
- "execution_count": 59,
- "outputs": [
- {
- "output_type": "execute_result",
- "data": {
- "text/plain": [
- "tensor(1.2888, device='cuda:0', grad_fn=)"
- ]
- },
- "metadata": {
- "tags": []
- },
- "execution_count": 59
- }
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "id": "LwyYI8m7Fp6P",
- "colab_type": "text"
- },
- "source": [
- "对PyTorch的基础介绍至此结束。总结一下,本节主要包含一下内容。\n",
- "\n",
- "\n",
- "1. Tensor:类似与numpy的array的数据结构,与Numpy的接口类似,可以方便地互相转换。\n",
- "2. autograd:为tensor提供自动求导功能\n",
- "3. nn:为神经网络设计的接口,提供了很多有用的功能(神经网络层,损失函数,优化器)\n",
- "4. 神经网络的训练:以CIFAR-10分类为例演示了神经网络的训练流程,包括数据加载,网络搭建,训练,以及测试。\n"
- ]
- }
- ]
-}
\ No newline at end of file