@@ -0,0 +1,157 @@ | |||
{ | |||
"cells": [ | |||
{ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"# LeNet5\n", | |||
"\n", | |||
"LeNet 诞生于 1994 年,是最早的卷积神经网络之一,并且推动了深度学习领域的发展。自从 1988 年开始,在多次迭代后这个开拓性成果被命名为 LeNet5。LeNet5 的架构的提出是基于如下的观点:图像的特征分布在整张图像上,通过带有可学习参数的卷积,从而有效的减少了参数数量,能够在多个位置上提取相似特征。\n", | |||
"\n", | |||
"在LeNet5提出的时候,没有 GPU 帮助训练,甚至 CPU 的速度也很慢,因此,LeNet5的规模并不大。其包含七个处理层,每一层都包含可训练参数(权重),当时使用的输入数据是 $32 \\times 32$ 像素的图像。LeNet-5 这个网络虽然很小,但是它包含了深度学习的基本模块:卷积层,池化层,全连接层。它是其他深度学习模型的基础,这里对LeNet5进行深入分析和讲解,通过实例分析,加深对与卷积层和池化层的理解。" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 1, | |||
"metadata": { | |||
"collapsed": true | |||
}, | |||
"outputs": [], | |||
"source": [ | |||
"import sys\n", | |||
"sys.path.append('..')\n", | |||
"\n", | |||
"import numpy as np\n", | |||
"import torch\n", | |||
"from torch import nn\n", | |||
"from torch.autograd import Variable\n", | |||
"from torchvision.datasets import CIFAR10\n", | |||
"from torchvision import transforms as tfs" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 1, | |||
"metadata": { | |||
"collapsed": true | |||
}, | |||
"outputs": [], | |||
"source": [ | |||
"import torch\n", | |||
"from torch import nn\n", | |||
"\n", | |||
"lenet5 = nn.Sequential(\n", | |||
" nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.Sigmoid(),\n", | |||
" nn.AvgPool2d(kernel_size=2, stride=2),\n", | |||
" nn.Conv2d(6, 16, kernel_size=5), nn.Sigmoid(),\n", | |||
" nn.AvgPool2d(kernel_size=2, stride=2),\n", | |||
" nn.Flatten(),\n", | |||
" nn.Linear(16 * 5 * 5, 120), nn.Sigmoid(),\n", | |||
" nn.Linear(120, 84), nn.Sigmoid(),\n", | |||
" nn.Linear(84, 10) )" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": null, | |||
"metadata": { | |||
"collapsed": true | |||
}, | |||
"outputs": [], | |||
"source": [ | |||
"from utils import train\n", | |||
"\n", | |||
"# 使用数据增强\n", | |||
"def train_tf(x):\n", | |||
" im_aug = tfs.Compose([\n", | |||
" tfs.Resize(224),\n", | |||
" tfs.ToTensor(),\n", | |||
" tfs.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])\n", | |||
" ])\n", | |||
" x = im_aug(x)\n", | |||
" return x\n", | |||
"\n", | |||
"def test_tf(x):\n", | |||
" im_aug = tfs.Compose([\n", | |||
" tfs.Resize(224),\n", | |||
" tfs.ToTensor(),\n", | |||
" tfs.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])\n", | |||
" ])\n", | |||
" x = im_aug(x)\n", | |||
" return x\n", | |||
" \n", | |||
"train_set = CIFAR10('../../data', train=True, transform=train_tf)\n", | |||
"train_data = torch.utils.data.DataLoader(train_set, batch_size=64, shuffle=True)\n", | |||
"test_set = CIFAR10('../../data', train=False, transform=test_tf)\n", | |||
"test_data = torch.utils.data.DataLoader(test_set, batch_size=128, shuffle=False)\n", | |||
"\n", | |||
"net = lenet5\n", | |||
"optimizer = torch.optim.SGD(net.parameters(), lr=1e-1)\n", | |||
"criterion = nn.CrossEntropyLoss()" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": null, | |||
"metadata": { | |||
"collapsed": true | |||
}, | |||
"outputs": [], | |||
"source": [ | |||
"(l_train_loss, l_train_acc, l_valid_loss, l_valid_acc) = train(net, \n", | |||
" train_data, test_data, \n", | |||
" 20, \n", | |||
" optimizer, criterion,\n", | |||
" use_cuda=False)" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": null, | |||
"metadata": { | |||
"collapsed": true | |||
}, | |||
"outputs": [], | |||
"source": [ | |||
"import matplotlib.pyplot as plt\n", | |||
"%matplotlib inline\n", | |||
"\n", | |||
"plt.plot(l_train_loss, label='train')\n", | |||
"plt.plot(l_valid_loss, label='valid')\n", | |||
"plt.xlabel('epoch')\n", | |||
"plt.legend(loc='best')\n", | |||
"plt.savefig('fig-res-lenet5-train-validate-loss.pdf')\n", | |||
"plt.show()\n", | |||
"\n", | |||
"plt.plot(l_train_acc, label='train')\n", | |||
"plt.plot(l_valid_acc, label='valid')\n", | |||
"plt.xlabel('epoch')\n", | |||
"plt.legend(loc='best')\n", | |||
"plt.savefig('fig-res-lenet5-train-validate-acc.pdf')\n", | |||
"plt.show()" | |||
] | |||
} | |||
], | |||
"metadata": { | |||
"kernelspec": { | |||
"display_name": "Python 3", | |||
"language": "python", | |||
"name": "python3" | |||
}, | |||
"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.5.4" | |||
} | |||
}, | |||
"nbformat": 4, | |||
"nbformat_minor": 2 | |||
} |
@@ -0,0 +1,99 @@ | |||
{ | |||
"cells": [ | |||
{ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"# AlexNet\n", | |||
"\n", | |||
"\n", | |||
"第一个典型的卷积神经网络是 LeNet5 ,但是第一个开启深度学习的网络却是 AlexNet,这个网络在2012年的ImageNet竞赛中取得冠军。这网络提出了深度学习常用的技术:ReLU和Dropout。AlexNet网络结构在整体上类似于LeNet,都是先卷积然后在全连接,但在细节上有很大不同,AlexNet更为复杂,Alexnet模型由5个卷积层和3个池化Pooling层,其中还有3个全连接层构成,共有$6 \\times 10^7$个参数和65000个神经元,最终的输出层是1000通道的Softmax。AlexNet 跟 LeNet 结构类似,但使⽤了更多的卷积层和更⼤的参数空间来拟合⼤规模数据集 ImageNet,它是浅层神经⽹络和深度神经⽹络的分界线。\n" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": null, | |||
"metadata": { | |||
"collapsed": true | |||
}, | |||
"outputs": [], | |||
"source": [ | |||
"import torch.nn as nn\n", | |||
"import torch\n", | |||
"\n", | |||
"class AlexNet(nn.Module):\n", | |||
" def __init__(self, num_classes=1000, init_weights=False): \n", | |||
" super(AlexNet, self).__init__()\n", | |||
" self.features = nn.Sequential( \n", | |||
" nn.Conv2d(3, 96, kernel_size=11, stride=4, padding=2), \n", | |||
" nn.ReLU(inplace=True), #inplace 可以载入更大模型\n", | |||
" nn.MaxPool2d(kernel_size=3, stride=2), \n", | |||
"\n", | |||
" nn.Conv2d(96, 256, kernel_size=5, padding=2),\n", | |||
" nn.ReLU(inplace=True),\n", | |||
" nn.MaxPool2d(kernel_size=3, stride=2),\n", | |||
"\n", | |||
" nn.Conv2d(256, 384, kernel_size=3, padding=1),\n", | |||
" nn.ReLU(inplace=True),\n", | |||
"\n", | |||
" nn.Conv2d(384, 384, kernel_size=3, padding=1),\n", | |||
" nn.ReLU(inplace=True),\n", | |||
"\n", | |||
" nn.Conv2d(384, 256, kernel_size=3, padding=1),\n", | |||
" nn.ReLU(inplace=True),\n", | |||
" nn.MaxPool2d(kernel_size=3, stride=2),\n", | |||
" )\n", | |||
" self.classifier = nn.Sequential(\n", | |||
" nn.Dropout(p=0.5),\n", | |||
" nn.Linear(256*6*6, 4096), #全链接\n", | |||
" nn.ReLU(inplace=True),\n", | |||
" nn.Dropout(p=0.5),\n", | |||
" nn.Linear(4096, 4096),\n", | |||
" nn.ReLU(inplace=True),\n", | |||
" nn.Linear(4096, num_classes),\n", | |||
" )\n", | |||
" if init_weights:\n", | |||
" self._initialize_weights()\n", | |||
"\n", | |||
" def forward(self, x):\n", | |||
" x = self.features(x)\n", | |||
" x = torch.flatten(x, start_dim=1) #展平或者view()\n", | |||
" x = self.classifier(x)\n", | |||
" return x\n", | |||
"\n", | |||
" def _initialize_weights(self):\n", | |||
" for m in self.modules():\n", | |||
" if isinstance(m, nn.Conv2d):\n", | |||
" #何教授方法\n", | |||
" nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu') \n", | |||
" if m.bias is not None:\n", | |||
" nn.init.constant_(m.bias, 0)\n", | |||
" elif isinstance(m, nn.Linear):\n", | |||
" #正态分布赋值\n", | |||
" nn.init.normal_(m.weight, 0, 0.01) \n", | |||
" nn.init.constant_(m.bias, 0)" | |||
] | |||
} | |||
], | |||
"metadata": { | |||
"kernelspec": { | |||
"display_name": "Python 3", | |||
"language": "python", | |||
"name": "python3" | |||
}, | |||
"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.5.4" | |||
} | |||
}, | |||
"nbformat": 4, | |||
"nbformat_minor": 2 | |||
} |
@@ -48,7 +48,7 @@ | |||
"VGG网络的特点:\n", | |||
"* 小卷积核和连续的卷积层: VGG中使用的都是3×3卷积核,并且使用了连续多个卷积层。这样做的好处主要有,\n", | |||
" - 使用连续的的多个小卷积核(3×3),来代替一个大的卷积核(例如(5×5)。使用小的卷积核的问题是,其感受野必然变小。所以,VGG中就使用连续的3×3卷积核,来增大感受野。VGG认为2个连续的3×3卷积核能够替代一个5×5卷积核,三个连续的3×3能够代替一个7×7。\n", | |||
" - 小卷积核的参数较少。3个3×3的卷积核参数为3×3×=27,而一个7×7的卷积核参数为7×7=49\n", | |||
" - 小卷积核的参数较少。3个3×3的卷积核参数为3×3×3=27,而一个7×7的卷积核参数为7×7=49\n", | |||
" - 由于每个卷积层都有一个非线性的激活函数,多个卷积层增加了非线性映射。\n", | |||
"* 小池化核,使用的是2×2\n", | |||
"* 通道数更多,特征度更宽: 每个通道代表着一个FeatureMap,更多的通道数表示更丰富的图像特征。VGG网络第一层的通道数为64,后面每层都进行了翻倍,最多到512个通道,通道数的增加,使得更多的信息可以被提取出来。\n", | |||
@@ -64,7 +64,7 @@ | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 2, | |||
"execution_count": 1, | |||
"metadata": { | |||
"ExecuteTime": { | |||
"end_time": "2017-12-22T09:01:51.296457Z", | |||
@@ -81,7 +81,8 @@ | |||
"import torch\n", | |||
"from torch import nn\n", | |||
"from torch.autograd import Variable\n", | |||
"from torchvision.datasets import CIFAR10" | |||
"from torchvision.datasets import CIFAR10\n", | |||
"from torchvision import transforms as tfs" | |||
] | |||
}, | |||
{ | |||
@@ -98,7 +99,7 @@ | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 3, | |||
"execution_count": 2, | |||
"metadata": { | |||
"ExecuteTime": { | |||
"end_time": "2017-12-22T09:01:51.312500Z", | |||
@@ -108,7 +109,7 @@ | |||
}, | |||
"outputs": [], | |||
"source": [ | |||
"def vgg_block(num_convs, in_channels, out_channels):\n", | |||
"def VGG_Block(num_convs, in_channels, out_channels):\n", | |||
" net = [nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1), nn.ReLU(True)] # 定义第一层\n", | |||
"\n", | |||
" for i in range(num_convs-1): # 定义后面的很多层\n", | |||
@@ -128,7 +129,7 @@ | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 4, | |||
"execution_count": 3, | |||
"metadata": { | |||
"ExecuteTime": { | |||
"end_time": "2017-12-22T08:20:40.819497Z", | |||
@@ -153,13 +154,13 @@ | |||
} | |||
], | |||
"source": [ | |||
"block_demo = vgg_block(3, 64, 128)\n", | |||
"block_demo = VGG_Block(3, 64, 128)\n", | |||
"print(block_demo)" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 5, | |||
"execution_count": 4, | |||
"metadata": { | |||
"ExecuteTime": { | |||
"end_time": "2017-12-22T07:52:04.632406Z", | |||
@@ -193,7 +194,7 @@ | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 6, | |||
"execution_count": 5, | |||
"metadata": { | |||
"ExecuteTime": { | |||
"end_time": "2017-12-22T09:01:54.497712Z", | |||
@@ -203,12 +204,12 @@ | |||
}, | |||
"outputs": [], | |||
"source": [ | |||
"def vgg_stack(num_convs, channels):\n", | |||
"def VGG_Stack(num_convs, channels):\n", | |||
" net = []\n", | |||
" for n, c in zip(num_convs, channels):\n", | |||
" in_c = c[0]\n", | |||
" out_c = c[1]\n", | |||
" net.append(vgg_block(n, in_c, out_c))\n", | |||
" net.append(VGG_Block(n, in_c, out_c))\n", | |||
" return nn.Sequential(*net)" | |||
] | |||
}, | |||
@@ -221,7 +222,7 @@ | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 7, | |||
"execution_count": 6, | |||
"metadata": { | |||
"ExecuteTime": { | |||
"end_time": "2017-12-22T09:01:55.149378Z", | |||
@@ -280,7 +281,7 @@ | |||
} | |||
], | |||
"source": [ | |||
"vgg_net = vgg_stack((2, 2, 3, 3, 3), ((3, 64), (64, 128), (128, 256), (256, 512), (512, 512)))\n", | |||
"vgg_net = VGG_Stack((2, 2, 3, 3, 3), ((3, 64), (64, 128), (128, 256), (256, 512), (512, 512)))\n", | |||
"print(vgg_net)" | |||
] | |||
}, | |||
@@ -288,12 +289,12 @@ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"可以看到网络结构中有个 5 个 最大池化,说明图片的大小会减少 5 倍。可以验证一下,输入一张 256 x 256 的图片看看结果是什么" | |||
"可以看到网络结构中有个 5 个 最大池化,说明图片的大小会减少 5 倍。可以验证一下,输入一张 224 x 224 的图片看看结果是什么" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 8, | |||
"execution_count": 7, | |||
"metadata": { | |||
"ExecuteTime": { | |||
"end_time": "2017-12-22T08:52:44.049650Z", | |||
@@ -305,12 +306,12 @@ | |||
"name": "stdout", | |||
"output_type": "stream", | |||
"text": [ | |||
"torch.Size([1, 512, 8, 8])\n" | |||
"torch.Size([1, 512, 7, 7])\n" | |||
] | |||
} | |||
], | |||
"source": [ | |||
"test_x = Variable(torch.zeros(1, 3, 256, 256))\n", | |||
"test_x = Variable(torch.zeros(1, 3, 224, 224))\n", | |||
"test_y = vgg_net(test_x)\n", | |||
"print(test_y.shape)" | |||
] | |||
@@ -324,7 +325,7 @@ | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 9, | |||
"execution_count": 8, | |||
"metadata": { | |||
"ExecuteTime": { | |||
"end_time": "2017-12-22T09:01:57.323034Z", | |||
@@ -334,14 +335,14 @@ | |||
}, | |||
"outputs": [], | |||
"source": [ | |||
"class vgg(nn.Module):\n", | |||
"class VGG_Net(nn.Module):\n", | |||
" def __init__(self):\n", | |||
" super(vgg, self).__init__()\n", | |||
" self.feature = vgg_net\n", | |||
" super(VGG_Net, self).__init__()\n", | |||
" self.feature = VGG_Stack((2, 2, 3, 3, 3), ((3, 64), (64, 128), (128, 256), (256, 512), (512, 512)))\n", | |||
" self.fc = nn.Sequential(\n", | |||
" nn.Linear(512, 100),\n", | |||
" nn.Linear(512*7*7, 4096),\n", | |||
" nn.ReLU(True),\n", | |||
" nn.Linear(100, 10)\n", | |||
" nn.Linear(4096, 10)\n", | |||
" )\n", | |||
" def forward(self, x):\n", | |||
" x = self.feature(x)\n", | |||
@@ -359,74 +360,88 @@ | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 6, | |||
"execution_count": 9, | |||
"metadata": { | |||
"ExecuteTime": { | |||
"end_time": "2017-12-22T09:01:59.921373Z", | |||
"start_time": "2017-12-22T09:01:58.709531Z" | |||
}, | |||
"collapsed": true | |||
} | |||
}, | |||
"outputs": [], | |||
"source": [ | |||
"from utils import train\n", | |||
"\n", | |||
"def data_tf(x):\n", | |||
" x = np.array(x, dtype='float32') / 255\n", | |||
" x = (x - 0.5) / 0.5 # 标准化,这个技巧之后会讲到\n", | |||
" x = x.transpose((2, 0, 1)) # 将 channel 放到第一维,只是 pytorch 要求的输入方式\n", | |||
" x = torch.from_numpy(x)\n", | |||
"# 使用数据增强\n", | |||
"def train_tf(x):\n", | |||
" im_aug = tfs.Compose([\n", | |||
" tfs.Resize(224),\n", | |||
" tfs.ToTensor(),\n", | |||
" tfs.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])\n", | |||
" ])\n", | |||
" x = im_aug(x)\n", | |||
" return x\n", | |||
"\n", | |||
"def test_tf(x):\n", | |||
" im_aug = tfs.Compose([\n", | |||
" tfs.Resize(224),\n", | |||
" tfs.ToTensor(),\n", | |||
" tfs.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])\n", | |||
" ])\n", | |||
" x = im_aug(x)\n", | |||
" return x\n", | |||
" \n", | |||
"train_set = CIFAR10('../../data', train=True, transform=data_tf)\n", | |||
"train_set = CIFAR10('../../data', train=True, transform=train_tf)\n", | |||
"train_data = torch.utils.data.DataLoader(train_set, batch_size=64, shuffle=True)\n", | |||
"test_set = CIFAR10('../../data', train=False, transform=data_tf)\n", | |||
"test_set = CIFAR10('../../data', train=False, transform=test_tf)\n", | |||
"test_data = torch.utils.data.DataLoader(test_set, batch_size=128, shuffle=False)\n", | |||
"\n", | |||
"net = vgg()\n", | |||
"net = VGG_Net()\n", | |||
"optimizer = torch.optim.SGD(net.parameters(), lr=1e-1)\n", | |||
"criterion = nn.CrossEntropyLoss()" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 7, | |||
"execution_count": null, | |||
"metadata": { | |||
"ExecuteTime": { | |||
"end_time": "2017-12-22T09:12:46.868967Z", | |||
"start_time": "2017-12-22T09:01:59.924086Z" | |||
} | |||
}, | |||
"outputs": [ | |||
{ | |||
"name": "stdout", | |||
"output_type": "stream", | |||
"text": [ | |||
"Epoch 0. Train Loss: 2.303118, Train Acc: 0.098186, Valid Loss: 2.302944, Valid Acc: 0.099585, Time 00:00:32\n", | |||
"Epoch 1. Train Loss: 2.303085, Train Acc: 0.096907, Valid Loss: 2.302762, Valid Acc: 0.100969, Time 00:00:33\n", | |||
"Epoch 2. Train Loss: 2.302916, Train Acc: 0.097287, Valid Loss: 2.302740, Valid Acc: 0.099585, Time 00:00:33\n", | |||
"Epoch 3. Train Loss: 2.302395, Train Acc: 0.102042, Valid Loss: 2.297652, Valid Acc: 0.108782, Time 00:00:32\n", | |||
"Epoch 4. Train Loss: 2.079523, Train Acc: 0.202026, Valid Loss: 1.868179, Valid Acc: 0.255736, Time 00:00:31\n", | |||
"Epoch 5. Train Loss: 1.781262, Train Acc: 0.307625, Valid Loss: 1.735122, Valid Acc: 0.323279, Time 00:00:31\n", | |||
"Epoch 6. Train Loss: 1.565095, Train Acc: 0.400975, Valid Loss: 1.463914, Valid Acc: 0.449565, Time 00:00:31\n", | |||
"Epoch 7. Train Loss: 1.360450, Train Acc: 0.495225, Valid Loss: 1.374488, Valid Acc: 0.490803, Time 00:00:31\n", | |||
"Epoch 8. Train Loss: 1.144470, Train Acc: 0.585758, Valid Loss: 1.384803, Valid Acc: 0.524624, Time 00:00:31\n", | |||
"Epoch 9. Train Loss: 0.954556, Train Acc: 0.659287, Valid Loss: 1.113850, Valid Acc: 0.609968, Time 00:00:32\n", | |||
"Epoch 10. Train Loss: 0.801952, Train Acc: 0.718131, Valid Loss: 1.080254, Valid Acc: 0.639933, Time 00:00:31\n", | |||
"Epoch 11. Train Loss: 0.665018, Train Acc: 0.765945, Valid Loss: 0.916277, Valid Acc: 0.698972, Time 00:00:31\n", | |||
"Epoch 12. Train Loss: 0.547411, Train Acc: 0.811241, Valid Loss: 1.030948, Valid Acc: 0.678896, Time 00:00:32\n", | |||
"Epoch 13. Train Loss: 0.442779, Train Acc: 0.846228, Valid Loss: 0.869791, Valid Acc: 0.732496, Time 00:00:32\n", | |||
"Epoch 14. Train Loss: 0.357279, Train Acc: 0.875440, Valid Loss: 1.233777, Valid Acc: 0.671677, Time 00:00:31\n", | |||
"Epoch 15. Train Loss: 0.285171, Train Acc: 0.900096, Valid Loss: 0.852879, Valid Acc: 0.765131, Time 00:00:32\n", | |||
"Epoch 16. Train Loss: 0.222431, Train Acc: 0.923374, Valid Loss: 1.848096, Valid Acc: 0.614023, Time 00:00:31\n", | |||
"Epoch 17. Train Loss: 0.174834, Train Acc: 0.939478, Valid Loss: 1.137286, Valid Acc: 0.728639, Time 00:00:31\n", | |||
"Epoch 18. Train Loss: 0.144375, Train Acc: 0.950587, Valid Loss: 0.907310, Valid Acc: 0.776800, Time 00:00:31\n", | |||
"Epoch 19. Train Loss: 0.115332, Train Acc: 0.960878, Valid Loss: 1.009886, Valid Acc: 0.761175, Time 00:00:31\n" | |||
] | |||
} | |||
], | |||
"outputs": [], | |||
"source": [ | |||
"train(net, train_data, test_data, 20, optimizer, criterion)" | |||
"(l_train_loss, l_train_acc, l_valid_loss, l_valid_acc) = train(net, \n", | |||
" train_data, test_data, \n", | |||
" 20, \n", | |||
" optimizer, criterion,\n", | |||
" use_cuda=False)" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": null, | |||
"metadata": { | |||
"collapsed": true | |||
}, | |||
"outputs": [], | |||
"source": [ | |||
"import matplotlib.pyplot as plt\n", | |||
"%matplotlib inline\n", | |||
"\n", | |||
"plt.plot(l_train_loss, label='train')\n", | |||
"plt.plot(l_valid_loss, label='valid')\n", | |||
"plt.xlabel('epoch')\n", | |||
"plt.legend(loc='best')\n", | |||
"plt.savefig('fig-res-vgg-train-validate-loss.pdf')\n", | |||
"plt.show()\n", | |||
"\n", | |||
"plt.plot(l_train_acc, label='train')\n", | |||
"plt.plot(l_valid_acc, label='valid')\n", | |||
"plt.xlabel('epoch')\n", | |||
"plt.legend(loc='best')\n", | |||
"plt.savefig('fig-res-vgg-train-validate-acc.pdf')\n", | |||
"plt.show()" | |||
] | |||
}, | |||
{ |
@@ -403,7 +403,7 @@ | |||
"name": "python", | |||
"nbconvert_exporter": "python", | |||
"pygments_lexer": "ipython3", | |||
"version": "3.7.9" | |||
"version": "3.5.4" | |||
} | |||
}, | |||
"nbformat": 4, |
@@ -13,16 +13,22 @@ def get_acc(output, label): | |||
return num_correct / total | |||
def train(net, train_data, valid_data, num_epochs, optimizer, criterion): | |||
if torch.cuda.is_available(): | |||
def train(net, train_data, valid_data, num_epochs, optimizer, criterion, use_cuda=True): | |||
if use_cuda and torch.cuda.is_available(): | |||
net = net.cuda() | |||
l_train_loss = [] | |||
l_train_acc = [] | |||
l_valid_loss = [] | |||
l_valid_acc = [] | |||
prev_time = datetime.now() | |||
for epoch in range(num_epochs): | |||
train_loss = 0 | |||
train_acc = 0 | |||
net = net.train() | |||
for im, label in train_data: | |||
if torch.cuda.is_available(): | |||
if use_cuda and torch.cuda.is_available(): | |||
im = Variable(im.cuda()) # (bs, 3, h, w) | |||
label = Variable(label.cuda()) # (bs, h, w) | |||
else: | |||
@@ -48,7 +54,7 @@ def train(net, train_data, valid_data, num_epochs, optimizer, criterion): | |||
valid_acc = 0 | |||
net = net.eval() | |||
for im, label in valid_data: | |||
if torch.cuda.is_available(): | |||
if use_cuda and torch.cuda.is_available(): | |||
im = Variable(im.cuda(), volatile=True) | |||
label = Variable(label.cuda(), volatile=True) | |||
else: | |||
@@ -63,13 +69,21 @@ def train(net, train_data, valid_data, num_epochs, optimizer, criterion): | |||
% (epoch, train_loss / len(train_data), | |||
train_acc / len(train_data), valid_loss / len(valid_data), | |||
valid_acc / len(valid_data))) | |||
l_valid_acc.append(valid_acc / len(valid_data)) | |||
l_valid_loss.append(valid_loss / len(valid_data)) | |||
else: | |||
epoch_str = ("Epoch %d. Train Loss: %f, Train Acc: %f, " % | |||
(epoch, train_loss / len(train_data), | |||
train_acc / len(train_data))) | |||
l_train_acc.append(train_acc / len(train_data)) | |||
l_train_loss.append(train_loss / len(train_data)) | |||
prev_time = cur_time | |||
print(epoch_str + time_str) | |||
return (l_train_loss, l_train_acc, l_valid_loss, l_valid_acc) | |||
def conv3x3(in_channel, out_channel, stride=1): | |||
return nn.Conv2d( | |||
@@ -25,15 +25,17 @@ | |||
- CNN | |||
- [CNN Introduction](1_CNN/CNN_Introduction.pptx) | |||
- [CNN simple demo](../demo_code/3_CNN_MNIST.py) | |||
- [Basic of Conv](1_CNN/1-basic_conv.ipynb) | |||
- [VGG Network](1_CNN/2-vgg.ipynb) | |||
- [GoogleNet](1_CNN/3-googlenet.ipynb) | |||
- [ResNet](1_CNN/4-resnet.ipynb) | |||
- [DenseNet](1_CNN/5-densenet.ipynb) | |||
- [Batch Normalization](1_CNN/6-batch-normalization.ipynb) | |||
- [Learning Rate Decay](1_CNN/7-lr-decay.ipynb) | |||
- [Regularization](1_CNN/8-regularization.ipynb) | |||
- [Data Augumentation](1_CNN/9-data-augumentation.ipynb) | |||
- [Basic of Conv](1_CNN/01-basic_conv.ipynb) | |||
- [LeNet5](1_CNN/02-LeNet5.ipynb) | |||
- [AlexNet](1_CNN/03-AlexNet.ipynb) | |||
- [VGG Network](1_CNN/04-vgg.ipynb) | |||
- [GoogleNet](1_CNN/05-googlenet.ipynb) | |||
- [ResNet](1_CNN/06-resnet.ipynb) | |||
- [DenseNet](1_CNN/07-densenet.ipynb) | |||
- [Batch Normalization](1_CNN/08-batch-normalization.ipynb) | |||
- [Learning Rate Decay](1_CNN/09-lr-decay.ipynb) | |||
- [Regularization](1_CNN/10-regularization.ipynb) | |||
- [Data Augumentation](1_CNN/11-data-augumentation.ipynb) | |||
- RNN | |||
- [rnn/pytorch-rnn](2_RNN/pytorch-rnn.ipynb) | |||
- [rnn/rnn-for-image](2_RNN/rnn-for-image.ipynb) | |||
@@ -52,15 +52,17 @@ | |||
- CNN | |||
- [CNN Introduction](7_deep_learning/1_CNN/CNN_Introduction.pptx) | |||
- [CNN simple demo](demo_code/3_CNN_MNIST.py) | |||
- [Basic of Conv](7_deep_learning/1_CNN/1-basic_conv.ipynb) | |||
- [VGG Network](7_deep_learning/1_CNN/2-vgg.ipynb) | |||
- [GoogleNet](7_deep_learning/1_CNN/3-googlenet.ipynb) | |||
- [ResNet](7_deep_learning/1_CNN/4-resnet.ipynb) | |||
- [DenseNet](7_deep_learning/1_CNN/5-densenet.ipynb) | |||
- [Batch Normalization](7_deep_learning/1_CNN/6-batch-normalization.ipynb) | |||
- [Learning Rate Decay](7_deep_learning/1_CNN/7-lr-decay.ipynb) | |||
- [Regularization](7_deep_learning/1_CNN/8-regularization.ipynb) | |||
- [Data Augumentation](7_deep_learning/1_CNN/9-data-augumentation.ipynb) | |||
- [Basic of Conv](7_deep_learning/1_CNN/01-basic_conv.ipynb) | |||
- [LeNet5](7_deep_learning/1_CNN/02-LeNet5.ipynb) | |||
- [AlexNet](7_deep_learning/1_CNN/03-AlexNet.ipynb) | |||
- [VGG Network](7_deep_learning/1_CNN/04-vgg.ipynb) | |||
- [GoogleNet](7_deep_learning/1_CNN/05-googlenet.ipynb) | |||
- [ResNet](7_deep_learning/1_CNN/06-resnet.ipynb) | |||
- [DenseNet](7_deep_learning/1_CNN/07-densenet.ipynb) | |||
- [Batch Normalization](7_deep_learning/1_CNN/08-batch-normalization.ipynb) | |||
- [Learning Rate Decay](7_deep_learning/1_CNN/09-lr-decay.ipynb) | |||
- [Regularization](7_deep_learning/1_CNN/10-regularization.ipynb) | |||
- [Data Augumentation](7_deep_learning/1_CNN/11-data-augumentation.ipynb) | |||
- RNN | |||
- [rnn/pytorch-rnn](7_deep_learning/2_RNN/pytorch-rnn.ipynb) | |||
- [rnn/rnn-for-image](7_deep_learning/2_RNN/rnn-for-image.ipynb) | |||