Pytorch: 空洞卷积神经网络

Copyright: Jingmin Wei, Pattern Recognition and Intelligent System, School of Artificial and Intelligence, Huazhong University of Science and Technology

Pytorch教程专栏链接


文章目录

    • Pytorch: 空洞卷积神经网络
  • @[toc]
    • 空洞卷积神经网络搭建
    • 数据预处理
    • 空洞卷积神经网络的训练和预测

本教程不商用,仅供学习和参考交流使用,如需转载,请联系本人。

相对于普通卷积,空洞卷积通过在卷积核中添加空洞( 000 元素),从而增大感受野,获取更多信息。感受野为在卷积神经网络中,决定某一层输出结果中一个元素对应的输入层的区域大小,通俗解释就是特征映射上的一个点对应输入图上的区域大小。

对于一个 3×33\times33×3 的 222-空洞卷积运算,实际的卷积核大小还是 3×33\times33×3 。但是空洞为 111 ,这样卷积核就会扩充一个 7×77\times77×7 的图像块,但只有 999 个红色的点会有权重取值进行卷积操作。也可以理解为卷积核的大小为 7×77\times77×7 ,但只有图中的 999 个点的权重不为 000 ,其他均为 000 。实际卷积权重只有 3×33\times33×3 ,但感受野实际为 7×77\times77×7 。对于 15×1515\times1515×15 的,实际卷积只有 9×99\times99×9 。

在 nn.Conv2d() 函数中,调节 dilation 的取值,即可进行不同大小卷积核的空洞卷积运算。

我们搭建的空洞卷积神经网络有两个空洞卷积层,两个池化层和两个全连接层,分类器依旧包含 101010 个神经元,除了卷积方式差异,与前文识别 FashionMNIST 的网络结构完全相同。

空洞卷积神经网络搭建

import numpy as np
import pandas as pd
from sklearn.metrics import accuracy_score, confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns
import copy
import time
import torch
import torch.nn as nn
from torch.optim import Adam
import torch.utils.data as Data
from torchvision import transforms
from torchvision.datasets import FashionMNIST
class MyConvDilaNet(nn.Module):def __init__(self):super(MyConvDilaNet, self).__init__()# 定义第一层卷积self.conv1 = nn.Sequential(nn.Conv2d(in_channels = 1,    # 输入图像通道数out_channels = 16,   # 输出特征数(卷积核个数)kernel_size = 3,    # 卷积核大小stride = 1,     # 卷积核步长1padding = 1,    # 边缘填充1dilation = 2,),nn.ReLU(),  # 激活函数nn.AvgPool2d(kernel_size = 2,    # 平均值池化,2*2stride = 2,     # 池化步长2),)self.conv2 = nn.Sequential(nn.Conv2d(16, 32, 3, 1, 0, dilation = 2),nn.ReLU(),nn.AvgPool2d(2, 2),)self.classifier = nn.Sequential(nn.Linear(32 * 4 * 4, 256),nn.ReLU(),nn.Linear(256, 128),nn.ReLU(),nn.Linear(128, 10),)def forward(self, x):# 定义前向传播路径x = self.conv1(x)x = self.conv2(x)x = x.view(x.size(0), -1)   # 展平多维的卷积图层output = self.classifier(x)return output

数据预处理

数据预处理部分和上文相同。

# 使用 FashionMNIST 数据,准备训练数据集
train_data = FashionMNIST(root = './data/FashionMNIST',train = True,transform = transforms.ToTensor(),download = False
)# 定义一个数据加载器
train_loader = Data.DataLoader(dataset = train_data,   # 数据集batch_size = 64,    # 批量处理的大小shuffle = False,   # 不打乱数据num_workers = 2,    # 两个进程
)# 计算 batch 数
print(len(train_loader))# 获得 batch 的数据for step, (b_x, b_y) in enumerate(train_loader):if step > 0:break# 可视化一个 batch 的图像
batch_x = b_x.squeeze().numpy()
batch_y = b_y.numpy()
label = train_data.classes
label[0] = 'T-shirt'plt.figure(figsize = (12, 5))
for i in np.arange(len(batch_y)):plt.subplot(4, 16, i + 1)plt.imshow(batch_x[i, :, :], cmap = plt.cm.gray)plt.title(label[batch_y[i]], size = 9)plt.axis('off')plt.subplots_adjust(wspace = 0.05)# 处理测试集
test_data = FashionMNIST(root = './data/FashionMNIST',train = False, # 不使用训练数据集download = False
)# 为数据添加一个通道维度,并且取值范围归一化
test_data_x = test_data.data.type(torch.FloatTensor) / 255.0
test_data_x = torch.unsqueeze(test_data_x, dim = 1)
test_data_y = test_data.targets # 测试集标签print(test_data_x.shape)
print(test_data_y.shape)
938
torch.Size([10000, 1, 28, 28])
torch.Size([10000])

# 定义空洞网络对象
myconvdilanet = MyConvDilaNet()
from torchsummary import summary
summary(myconvdilanet, input_size=(1, 28, 28))
----------------------------------------------------------------Layer (type)               Output Shape         Param #
================================================================Conv2d-1           [-1, 16, 26, 26]             160ReLU-2           [-1, 16, 26, 26]               0AvgPool2d-3           [-1, 16, 13, 13]               0Conv2d-4             [-1, 32, 9, 9]           4,640ReLU-5             [-1, 32, 9, 9]               0AvgPool2d-6             [-1, 32, 4, 4]               0Linear-7                  [-1, 256]         131,328ReLU-8                  [-1, 256]               0Linear-9                  [-1, 128]          32,896ReLU-10                  [-1, 128]               0Linear-11                   [-1, 10]           1,290
================================================================
Total params: 170,314
Trainable params: 170,314
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.00
Forward/backward pass size (MB): 0.24
Params size (MB): 0.65
Estimated Total Size (MB): 0.89
----------------------------------------------------------------
# 输出网络结构
from torchviz import make_dotx = torch.randn(1, 1, 28, 28).requires_grad_(True)
y = myconvdilanet(x)
myDilaCNN_vis = make_dot(y, params=dict(list(myconvdilanet.named_parameters()) + [('x', x)]))
myDilaCNN_vis

空洞卷积神经网络的训练和预测

网络训练和测试部分和上文相同。

# 定义网络训练过程函数
def train_model(model, traindataloader, train_rate, criterion, optimizer, num_epochs = 25):'''模型,训练数据集(待切分),训练集百分比,损失函数,优化器,训练轮数'''# 计算训练使用的 batch 数量batch_num = len(traindataloader)train_batch_num = round(batch_num * train_rate)# 复制模型参数best_model_wts = copy.deepcopy(model.state_dict())best_acc = 0.0train_loss_all = []val_loss_all =[]train_acc_all = []val_acc_all = []since = time.time()# 训练框架for epoch in range(num_epochs):print('Epoch {}/{}'.format(epoch, num_epochs - 1))print('-' * 10)train_loss = 0.0 train_corrects = 0train_num = 0val_loss = 0.0val_corrects = 0val_num = 0for step, (b_x, b_y) in enumerate(traindataloader):if step < train_batch_num:model.train()   # 设置为训练模式output = model(b_x)pre_lab = torch.argmax(output, 1)loss = criterion(output, b_y)   # 计算误差损失optimizer.zero_grad()   # 清空过往梯度loss.backward() # 误差反向传播optimizer.step()    # 根据误差更新参数train_loss += loss.item() * b_x.size(0)train_corrects += torch.sum(pre_lab == b_y.data)train_num += b_x.size(0)else:model.eval()    # 设置为验证模式output = model(b_x)pre_lab = torch.argmax(output, 1)loss = criterion(output, b_y)val_loss += loss.item() * b_x.size(0)val_corrects += torch.sum(pre_lab == b_y.data)val_num += b_x.size(0)# ======================小循环结束========================# 计算一个epoch在训练集和验证集上的损失和精度train_loss_all.append(train_loss / train_num)train_acc_all.append(train_corrects.double().item() / train_num)val_loss_all.append(val_loss / val_num)val_acc_all.append(val_corrects.double().item() / val_num)print('{} Train Loss: {:.4f} Train Acc: {:.4f}'.format(epoch, train_loss_all[-1], train_acc_all[-1]))print('{} Val Loss: {:.4f} Val Acc: {:.4f}'.format(epoch, val_loss_all[-1], val_acc_all[-1]))# 拷贝模型最高精度下的参数if val_acc_all[-1] > best_acc:best_acc = val_acc_all[-1]best_model_wts = copy.deepcopy(model.state_dict())time_use = time.time() - sinceprint('Train and Val complete in {:.0f}m {:.0f}s'.format(time_use // 60, time_use % 60))# ===========================大循环结束===========================# 使用最好模型的参数model.load_state_dict(best_model_wts)train_process = pd.DataFrame(data = {'epoch': range(num_epochs),'train_loss_all': train_loss_all,'val_loss_all': val_loss_all,'train_acc_all': train_acc_all,'val_acc_all': val_acc_all})return model, train_process
# 对模型进行训练
optimizer = Adam(myconvdilanet.parameters(), lr = 0.0003)
criterion = nn.CrossEntropyLoss()
myconvdilanet, train_process = train_model(myconvdilanet, train_loader, 0.8, criterion, optimizer, num_epochs = 25)
Epoch 0/24
----------
0 Train Loss: 0.8922 Train Acc: 0.6718
0 Val Loss: 0.6322 Val Acc: 0.7498
Train and Val complete in 1m 2s
Epoch 1/24
----------
1 Train Loss: 0.6028 Train Acc: 0.7656
1 Val Loss: 0.5610 Val Acc: 0.7837
Train and Val complete in 2m 3s
Epoch 2/24
----------
2 Train Loss: 0.5331 Train Acc: 0.7948
2 Val Loss: 0.5047 Val Acc: 0.8107
Train and Val complete in 3m 3s
Epoch 3/24
----------
3 Train Loss: 0.4868 Train Acc: 0.8159
3 Val Loss: 0.4738 Val Acc: 0.8266
Train and Val complete in 3m 60s
Epoch 4/24
----------
4 Train Loss: 0.4540 Train Acc: 0.8320
4 Val Loss: 0.4491 Val Acc: 0.8369
Train and Val complete in 4m 54s
Epoch 5/24
----------
5 Train Loss: 0.4275 Train Acc: 0.8433
5 Val Loss: 0.4279 Val Acc: 0.8455
Train and Val complete in 5m 50s
Epoch 6/24
----------
6 Train Loss: 0.4047 Train Acc: 0.8512
6 Val Loss: 0.4075 Val Acc: 0.8531
Train and Val complete in 6m 45s
Epoch 7/24
----------
7 Train Loss: 0.3851 Train Acc: 0.8591
7 Val Loss: 0.3897 Val Acc: 0.8608
Train and Val complete in 7m 41s
Epoch 8/24
----------
8 Train Loss: 0.3690 Train Acc: 0.8655
8 Val Loss: 0.3762 Val Acc: 0.8653
Train and Val complete in 8m 36s
Epoch 9/24
----------
9 Train Loss: 0.3557 Train Acc: 0.8708
9 Val Loss: 0.3652 Val Acc: 0.8672
Train and Val complete in 9m 31s
Epoch 10/24
----------
10 Train Loss: 0.3440 Train Acc: 0.8751
10 Val Loss: 0.3552 Val Acc: 0.8710
Train and Val complete in 10m 26s
Epoch 11/24
----------
11 Train Loss: 0.3341 Train Acc: 0.8776
11 Val Loss: 0.3473 Val Acc: 0.8735
Train and Val complete in 11m 22s
Epoch 12/24
----------
12 Train Loss: 0.3250 Train Acc: 0.8812
12 Val Loss: 0.3412 Val Acc: 0.8762
Train and Val complete in 12m 21s
Epoch 13/24
----------
13 Train Loss: 0.3166 Train Acc: 0.8840
13 Val Loss: 0.3355 Val Acc: 0.8791
Train and Val complete in 13m 25s
Epoch 14/24
----------
14 Train Loss: 0.3092 Train Acc: 0.8870
14 Val Loss: 0.3299 Val Acc: 0.8810
Train and Val complete in 14m 26s
Epoch 15/24
----------
15 Train Loss: 0.3023 Train Acc: 0.8889
15 Val Loss: 0.3250 Val Acc: 0.8816
Train and Val complete in 15m 28s
Epoch 16/24
----------
16 Train Loss: 0.2956 Train Acc: 0.8921
16 Val Loss: 0.3182 Val Acc: 0.8838
Train and Val complete in 16m 30s
Epoch 17/24
----------
17 Train Loss: 0.2896 Train Acc: 0.8939
17 Val Loss: 0.3138 Val Acc: 0.8862
Train and Val complete in 17m 32s
Epoch 18/24
----------
18 Train Loss: 0.2836 Train Acc: 0.8961
18 Val Loss: 0.3093 Val Acc: 0.8872
Train and Val complete in 18m 33s
Epoch 19/24
----------
19 Train Loss: 0.2783 Train Acc: 0.8984
19 Val Loss: 0.3054 Val Acc: 0.8894
Train and Val complete in 19m 34s
Epoch 20/24
----------
20 Train Loss: 0.2728 Train Acc: 0.9004
20 Val Loss: 0.3020 Val Acc: 0.8911
Train and Val complete in 20m 52s
Epoch 21/24
----------
21 Train Loss: 0.2676 Train Acc: 0.9021
21 Val Loss: 0.2989 Val Acc: 0.8922
Train and Val complete in 21m 54s
Epoch 22/24
----------
22 Train Loss: 0.2625 Train Acc: 0.9038
22 Val Loss: 0.2960 Val Acc: 0.8942
Train and Val complete in 22m 55s
Epoch 23/24
----------
23 Train Loss: 0.2578 Train Acc: 0.9049
23 Val Loss: 0.2932 Val Acc: 0.8942
Train and Val complete in 23m 56s
Epoch 24/24
----------
24 Train Loss: 0.2531 Train Acc: 0.9062
24 Val Loss: 0.2907 Val Acc: 0.8942
Train and Val complete in 24m 58s

使用折线图可视化训练过程:

# 可视化训练过程
plt.figure(figsize = (12, 4))
plt.subplot(1, 2, 1)
plt.plot(train_process.epoch, train_process.train_loss_all, 'ro-', label = 'Train loss')
plt.plot(train_process.epoch, train_process.val_loss_all, 'bs-', label = 'Val loss')
plt.legend()
plt.xlabel('epoch')
plt.ylabel('Loss')plt.subplot(1, 2, 2)
plt.plot(train_process.epoch, train_process.train_acc_all, 'ro-', label = 'Train acc')
plt.plot(train_process.epoch, train_process.val_acc_all, 'bs-', label = 'Val acc')
plt.legend()
plt.xlabel('epoch')
plt.ylabel('Acc')plt.show()


计算空洞卷积模型的泛化能力:

# 测试集预测,并可视化预测效果
myconvdilanet.eval()
output = myconvdilanet(test_data_x)
pre_lab = torch.argmax(output, 1)
acc = accuracy_score(test_data_y, pre_lab)
print(test_data_y)
print(pre_lab)
print('测试集上的预测精度为', acc)
tensor([9, 2, 1,  ..., 8, 1, 5])
tensor([9, 2, 1,  ..., 8, 1, 5])
测试集上的预测精度为 0.8841

使用热力图,观察每类数据上的预测情况:

# 计算测试集上的混淆矩阵并可视化
conf_mat = confusion_matrix(test_data_y, pre_lab)
df_cm = pd.DataFrame(conf_mat, index = label, columns = label)
heatmap = sns.heatmap(df_cm, annot = True, fmt = 'd', cmap = 'YlGnBu')
heatmap.yaxis.set_ticklabels(heatmap.yaxis.get_ticklabels(), rotation = 0, ha = 'right')
heatmap.xaxis.set_ticklabels(heatmap.xaxis.get_ticklabels(), rotation = 45, ha = 'right')
plt.ylabel('True label')
plt.xlabel('Predicted label')
plt.show()

Pytorch:卷积神经网络-空洞卷积相关推荐

  1. 膨胀卷积(空洞卷积 dilated convolution)

    学习的B站大佬的视频大部分图片来自于课中,文章结尾有大佬视频链接,以及阅读<深度学习之pytorch物体检测实战>,刚开始学习可能有些错误,希望大佬指正 1.空洞卷积了解 空洞卷积最初是为 ...

  2. 【扩张卷积or空洞卷积】如何理解Dilated Convolutions(空洞卷积)

    文章来源:https://blog.csdn.net/alxe_made/article/details/88594550 1. 扩张卷积的提出 Multi-Scale Context Aggrega ...

  3. 卷积,反卷积,空洞卷积

    卷积神经网络中卷积核的作用在于特征的抽取,越是大的卷积核尺寸就意味着更大的感受野,当然随之而来的是更多的参数.早在1998年,LeCun大神发布的LetNet-5模型中就会出,图像空域内具有局部相关性 ...

  4. 卷积神经网络之卷积计算、作用与思想 深度学习

    博客:blog.shinelee.me | 博客园 | CSDN 卷积运算与相关运算 在计算机视觉领域,卷积核.滤波器通常为较小尺寸的矩阵,比如3×33×3.从这个角度看,多层卷积是在进行逐层映射,整 ...

  5. 【数据挖掘】卷积神经网络 ( 视觉原理 | CNN 模仿视觉 | 卷积神经网络简介 | 卷积神经网络组成 | 整体工作流程 | 卷积计算图示 | 卷积计算简介 | 卷积计算示例 | 卷积计算参数 )

    文章目录 I . 人类的视觉原理 II . 卷积神经网络 模仿 视觉原理 III . 卷积神经网络简介 IV . 卷积神经网络 组成 V . 卷积神经网络 工作流程 VI . 降低样本参数数量级 VI ...

  6. 04.卷积神经网络 W1.卷积神经网络(作业:手动/TensorFlow 实现卷积神经网络)

    文章目录 作业1:实现卷积神经网络 1. 导入一些包 2. 模型框架 3. 卷积神经网络 3.1 Zero-Padding 3.2 单步卷积 3.3 卷积神经网络 - 前向传播 4. 池化层 5. 卷 ...

  7. 深入学习卷积神经网络中卷积层和池化层的意义(转)

    为什么要使用卷积呢? 在传统的神经网络中,比如多层感知机(MLP),其输入通常是一个特征向量:需要人工设计特征,然后将这些特征计算的值组成特征向量,在过去几十年的经验来看,人工找到的特征并不是怎么好用 ...

  8. 【卷积神经网络】卷积神经网络(Convolutional Neural Networks, CNN)基础

    卷积神经网络(Convolutional Neural Networks, CNN),是一种 针对图像 的特殊的 神经网络. 卷积神经网络概述 Why not DNN? 图像数据的维数很高,比如 1, ...

  9. 卷积、空洞卷积、反卷积与空洞反卷积的计算公式(全)

    前言: 经常使用的卷积有卷积.空洞卷积.反卷积与空洞反卷积的,下面总结了他们的计算公式. 一.卷积计算公式 卷积神将网络的计算公式为: N=(W-F+2P)/S+1 其中 N:输出大小 W:输入大小 ...

  10. 卷积、转置卷积、可分离卷积、分组卷积、空洞卷积的理解

    文章目录 卷积.转置卷积.可分离卷积.分组卷积.空洞卷积的理解 转置卷积 深度可分离卷积 分组卷积 空洞卷积 卷积.转置卷积.可分离卷积.分组卷积.空洞卷积的理解 这里主要是汇总一些本人觉得比较好的文 ...

最新文章

  1. 上一局APP玩边画边猜,第1次见人使用道具,我的游戏体验上升了
  2. 刷新DNS解析缓存+追踪+域名解析命令
  3. [html] 你觉得新开发一个网站最困难的是哪些部分?
  4. python连接MySQL数据库搭建简易博客
  5. 信息学奥赛C++语言:十位能被个位和百位之和整除
  6. 10年老电脑如何提速_电脑上如何提取图片中的文字?教你3个方法,10秒轻松搞定...
  7. 故障解决 | win10没声音及找不到Realtek高清音频管理器
  8. 技术年货:美团技术沙龙合辑大放送
  9. linux nfs共享目录访问速度慢,linux之间共享文件夹选nfs还是选samba--
  10. Datawhale:愿竞赛圈少一些人身攻击和热点炒作
  11. win7笔记本做wifi热点
  12. 网络游戏怎么样推广引流,游戏推广怎么做引流
  13. 小米雷军现身国庆 70 周年花车!
  14. 南柯服务器压力,性能/负载/压力测试 - Mr.南柯 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...
  15. 阿里云PHP SDK(升级版)使用说明:
  16. mysql压缩包安装教程_MySQL5.7压缩包安装教程
  17. 使用Navicat复制MySQL数据库
  18. 抖音现在做的竞价推广都是怎么操作的?
  19. sublime text3 配置python、ruby、c/c++(c/c++不推荐这个方法)
  20. 数据分析常用分析方法

热门文章

  1. c语言课程设计题目 吃豆子,C语言吃豆子游戏
  2. php vld解密zend,基于PHP7维护vld扩展的总结
  3. ngix请求转发配置
  4. 显示 think-cell 用户界面时出现错误
  5. 线性内插和双线性内插
  6. 互动直播系统源码,直播系统依托于IM技术
  7. (三)空域图像增强:像素联系和模板运算
  8. 进入Mysql数据库操作
  9. 使用Photoshop制作名片
  10. 平面设计中有趣的词云图如何设计