Files
shusentang--dive-into-dl-py…/code/chapter05_CNN/5.9_googlenet.ipynb
T
2026-07-13 13:26:42 +08:00

233 lines
6.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 5.9 含并行连结的网络(GoogLeNet"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.4.0\n",
"cuda\n"
]
}
],
"source": [
"import time\n",
"import torch\n",
"from torch import nn, optim\n",
"import torch.nn.functional as F\n",
"\n",
"import sys\n",
"sys.path.append(\"..\") \n",
"import d2lzh_pytorch as d2l\n",
"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n",
"\n",
"print(torch.__version__)\n",
"print(device)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5.9.1 Inception 块"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"class Inception(nn.Module):\n",
" # c1 - c4为每条线路里的层的输出通道数\n",
" def __init__(self, in_c, c1, c2, c3, c4):\n",
" super(Inception, self).__init__()\n",
" # 线路1,单1 x 1卷积层\n",
" self.p1_1 = nn.Conv2d(in_c, c1, kernel_size=1)\n",
" # 线路21 x 1卷积层后接3 x 3卷积层\n",
" self.p2_1 = nn.Conv2d(in_c, c2[0], kernel_size=1)\n",
" self.p2_2 = nn.Conv2d(c2[0], c2[1], kernel_size=3, padding=1)\n",
" # 线路31 x 1卷积层后接5 x 5卷积层\n",
" self.p3_1 = nn.Conv2d(in_c, c3[0], kernel_size=1)\n",
" self.p3_2 = nn.Conv2d(c3[0], c3[1], kernel_size=5, padding=2)\n",
" # 线路43 x 3最大池化层后接1 x 1卷积层\n",
" self.p4_1 = nn.MaxPool2d(kernel_size=3, stride=1, padding=1)\n",
" self.p4_2 = nn.Conv2d(in_c, c4, kernel_size=1)\n",
"\n",
" def forward(self, x):\n",
" p1 = F.relu(self.p1_1(x))\n",
" p2 = F.relu(self.p2_2(F.relu(self.p2_1(x))))\n",
" p3 = F.relu(self.p3_2(F.relu(self.p3_1(x))))\n",
" p4 = F.relu(self.p4_2(self.p4_1(x)))\n",
" return torch.cat((p1, p2, p3, p4), dim=1) # 在通道维上连结输出"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5.9.2 GoogLeNet模型"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"b1 = nn.Sequential(nn.Conv2d(1, 64, kernel_size=7, stride=2, padding=3),\n",
" nn.ReLU(),\n",
" nn.MaxPool2d(kernel_size=3, stride=2, padding=1))"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"b2 = nn.Sequential(nn.Conv2d(64, 64, kernel_size=1),\n",
" nn.Conv2d(64, 192, kernel_size=3, padding=1),\n",
" nn.MaxPool2d(kernel_size=3, stride=2, padding=1))"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"b3 = nn.Sequential(Inception(192, 64, (96, 128), (16, 32), 32),\n",
" Inception(256, 128, (128, 192), (32, 96), 64),\n",
" nn.MaxPool2d(kernel_size=3, stride=2, padding=1))"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"b4 = nn.Sequential(Inception(480, 192, (96, 208), (16, 48), 64),\n",
" Inception(512, 160, (112, 224), (24, 64), 64),\n",
" Inception(512, 128, (128, 256), (24, 64), 64),\n",
" Inception(512, 112, (144, 288), (32, 64), 64),\n",
" Inception(528, 256, (160, 320), (32, 128), 128),\n",
" nn.MaxPool2d(kernel_size=3, stride=2, padding=1))"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"b5 = nn.Sequential(Inception(832, 256, (160, 320), (32, 128), 128),\n",
" Inception(832, 384, (192, 384), (48, 128), 128),\n",
" d2l.GlobalAvgPool2d())"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"output shape: torch.Size([1, 64, 24, 24])\n",
"output shape: torch.Size([1, 192, 12, 12])\n",
"output shape: torch.Size([1, 480, 6, 6])\n",
"output shape: torch.Size([1, 832, 3, 3])\n",
"output shape: torch.Size([1, 1024, 1, 1])\n",
"output shape: torch.Size([1, 1024])\n",
"output shape: torch.Size([1, 10])\n"
]
}
],
"source": [
"net = nn.Sequential(b1, b2, b3, b4, b5, d2l.FlattenLayer(), nn.Linear(1024, 10))\n",
"X = torch.rand(1, 1, 96, 96)\n",
"for blk in net.children(): \n",
" X = blk(X)\n",
" print('output shape: ', X.shape)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 5.9.3 获取数据和训练模型"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"training on cuda\n",
"epoch 1, loss 0.0087, train acc 0.570, test acc 0.831, time 45.5 sec\n",
"epoch 2, loss 0.0032, train acc 0.851, test acc 0.853, time 48.5 sec\n",
"epoch 3, loss 0.0026, train acc 0.880, test acc 0.883, time 45.4 sec\n",
"epoch 4, loss 0.0022, train acc 0.895, test acc 0.887, time 46.6 sec\n",
"epoch 5, loss 0.0020, train acc 0.906, test acc 0.896, time 43.5 sec\n"
]
}
],
"source": [
"batch_size = 128\n",
"# 如出现“out of memory”的报错信息,可减小batch_size或resize\n",
"train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=96)\n",
"\n",
"lr, num_epochs = 0.001, 5\n",
"optimizer = torch.optim.Adam(net.parameters(), lr=lr)\n",
"d2l.train_ch5(net, train_iter, test_iter, batch_size, optimizer, device, num_epochs)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python [default]",
"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.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}