最近在研究facebook推出的深度学习框架pytorch,在使用CNN对非常经典的MNIST数据集进行卷积运算时遇到了些问题,就是自己手动使用公式进行推导时,总是在最后一步的全连接层矩阵运算时出错

  • 开始也是比较的郁闷,为什么按照Stanford University CS231n上介绍的运算公式总是推算不对呢
  • 较劲的我又重新的返回来查看了这么一个非常简单的入门级别代码:
class CNN(nn.Module):def __init__(self):super(CNN, self).__init__()# 使用序列工具快速构建self.conv1 = nn.Sequential(nn.Conv2d(1, 16, kernel_size=5,stride=1, padding=2),nn.ReLU(),nn.MaxPool2d(2))self.conv2 = nn.Sequential(nn.Conv2d(16, 32, kernel_size=5,stride=1,padding=2),nn.BatchNorm2d(32),nn.ReLU(),nn.MaxPool2d(2))self.fc = nn.Linear(7*7*32, 10)def forward(self, x):out = self.conv1(x)out = self.conv2(out)out = out.view(out.size(0), -1)  # reshapeout = self.fc(out)return out

然后我又开始在验算纸继续按照公式又运算了一遍:



按照上面的代码公式可以总结为:

 W(out)=[W(in)+2p-F]/S+1H(out)=[H(in)+2p-F]/S+1

其中W(out),H(out)为输出维度,
W(in),H(in)为输入维度
p为padding
F为kernel_size

  • 结合这上面的公式对MNIST数据集的一张图片进行手动运算,原图像的维度为28*28
    计算:
    进行着第一步卷积之后的图像[28+22-5]/1+1
    可以看出此时的运算结果还为28 (可以自己的运算一遍进行验证)

  • 我们知道在进行卷积运算之后,是需要结合着pool的,也就是通常所说的池化,或者说降维,这里呢就介绍MaxPool

  • nn.MaxPool2d())

  • 看这其中的参数,个人认为这就是对输出数据进行折半处理咱们第一步开始进行验证自己的猜测
    如果猜测的正确的话,我们在进行四层卷积运算之后MNIST数据对应输出应该是

  • 14x14x16

  • 7x7x32

  • 3x3x64

  • 1x1x128
    验证:

import torch
import torch.nn as nn
import torchvision
from torch import optim
import torchvision.datasets as normal_datasets
import torchvision.transforms as transforms
from torch.autograd import Variable
num_epochs = 5 # 批次
batch_size = 100 # 批次数据
learning_rate = 0.001  # 学习率
# 将数据处理成Variable, 如果有GPU, 可以转成cuda形式
def get_variable(x):x = Variable(x)return x.cuda() if torch.cuda.is_available() else x
# 从torchvision.datasets中加载一些常用数据集
train_dataset = normal_datasets.MNIST(root='./MNIST_Model/',  # 数据集保存路径train=True,  # 是否作为训练集transform=transforms.ToTensor(),  # 数据如何处理, 可以自己自定义download=True)  # 路径下没有的话, 可以下载
# 见数据加载器和batch
test_dataset = normal_datasets.MNIST(root='./MNIST_Model/',train=False,transform=transforms.ToTensor())train_loader = torch.utils.data.DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True)test_loader = torch.utils.data.DataLoader(dataset=test_dataset,batch_size=batch_size,shuffle=False)# 两层卷积
class CNN(nn.Module):def __init__(self):super(CNN, self).__init__()# 使用序列工具快速构建self.conv1 = nn.Sequential(nn.Conv2d(1, 16, kernel_size=5,stride=1, padding=2),nn.ReLU(),nn.MaxPool2d(2))self.conv2 = nn.Sequential(nn.Conv2d(16, 32, kernel_size=5,stride=1,padding=2),nn.BatchNorm2d(32),nn.ReLU(),nn.MaxPool2d(2))self.conv3=nn.Sequential(nn.Conv2d(32,64,kernel_size=5,stride=1,padding=2),nn.BatchNorm2d(64),nn.ReLU(),nn.MaxPool2d(2))self.conv4=nn.Sequential(nn.Conv2d(64,128,kernel_size=5,stride=1,padding=2),nn.BatchNorm2d(128),nn.ReLU(),nn.MaxPool2d(2))self.fc = nn.Linear(1*1*128, 10)def forward(self, x):out = self.conv1(x)print(out.shape)out = self.conv2(out)print(out.shape)out=self.conv3(out)print(out.shape)out=self.conv4(out)print(out.shape)out = out.view(out.size(0), -1)  # reshapeout = self.fc(out)return out
cnn = CNN()
if torch.cuda.is_available():cnn = cnn.cuda()# 选择损失函数和优化方法
loss_func = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(cnn.parameters(), lr=learning_rate)
for epoch in range(num_epochs):for i, (images, labels) in enumerate(train_loader):images = get_variable(images)labels = get_variable(labels)outputs = cnn(images)loss = loss_func(outputs, labels)optimizer.zero_grad()loss.backward()optimizer.step()if (i + 1) % 100 == 0:print('Epoch [%d/%d], Iter [%d/%d] Loss: %.4f'% (epoch + 1, num_epochs, i + 1, len(train_dataset) // batch_size, loss.item()))


此时可以看到确实是我们猜想的那样
*总结:
上述都是个人理解,如有不正确的地方欢迎提出,一同进步

CNN中input,output的计算推导相关推荐

  1. CNN中parameters和FLOPs计算

    CNN中parameters和FLOPs计算 以AlexNet为例,先注意观察每层编注的通道数的变化. 1. 卷积网络的参数量的计算(parameters) CNN中的parameters分为两种:W ...

  2. Angular中父子组件传值@Input @Output @ViewChild最全面最简单的总结

    父组件传递给子组件: 值传递方式:@Input既可以传递数据也可以传递方法 传递数据(不举例了) 传递方法 // 父组件定义方法 parentRun(){alert('这是父组件的 run 方法'); ...

  3. docker中java应用new FileOutputStream直接报Input/output error

    为什么80%的码农都做不了架构师?>>>    一个docker容器中跑着java应用,是一个定时任务,每天拉取远端文件包存到本机,命名为:decrypt-20181020 就在这一 ...

  4. cnn stride and padding_彻底搞懂CNN中的卷积和反卷积

    前言 卷积和反卷积在CNN中经常被用到,想要彻底搞懂并不是那么容易.本文主要分三个部分来讲解卷积和反卷积,分别包括概念.工作过程.代码示例,其中代码实践部分主结合TensorFlow框架来进行实践.给 ...

  5. CNN中feature map、卷积核、卷积核个数、filter、channel的概念解释,以及CNN 学习过程中卷积核更新的理解

    feature map.卷积核.卷积核个数.filter.channel的概念解释 feather map的理解 在cnn的每个卷积层,数据都是以三维形式存在的.你可以把它看成许多个二维图片叠在一起( ...

  6. cnn池化层输入通道数_(pytorch-深度学习系列)CNN中的池化层-学习笔记

    CNN中的池化层 首先,池化(pooling)层的提出是为了缓解卷积层对位置的过度敏感性. 什么意思? 比如在图像边缘检测问题中,实际图像里,我们的目标物体不会总出现在固定位置,即使我们连续拍摄同一个 ...

  7. (pytorch-深度学习系列)CNN中的池化层-学习笔记

    CNN中的池化层 首先,池化(pooling)层的提出是为了缓解卷积层对位置的过度敏感性. 什么意思? 比如在图像边缘检测问题中,实际图像里,我们的目标物体不会总出现在固定位置,即使我们连续拍摄同一个 ...

  8. CNN中卷积的学习笔记

    1 致谢 感谢赵老师的讲述~ 2 前言 今天在学习CNN~ 记得很久以前,小伙伴曾经问过我一个问题,为什么CNN网络要使用卷积运算作为神经元的输入, 那时候我还没怎么开始学深度学习,觉得这是一个很玄妙 ...

  9. 卷积神经网络(CNN)相关知识以及数学推导

    神经网络概述 神经元模型 以上就是经典的"M-P神经元模型".在这个模型中,神经元接收来自n个其他神经元传递过来的输入信号,这些输入信号通过带权重的连接进行传递,神经元接收到的总输 ...

最新文章

  1. PHP的CI框架学习
  2. 高安全性同态加密算法_坏的同态性教程
  3. 如何用纯 CSS 创作背景色块变换的按钮特效
  4. KM、流程、风险管理的关系分析
  5. C++算法学习(动态规划算法)
  6. CodeProject上的两个简单绘图程序
  7. 智慧水务智慧管网安全检测系统解决方案
  8. 手把手教你封装属于自己的Windows7安装镜像
  9. 数学速算法_孩子数学计算老出错?复习阶段,家长赶紧和孩子一起找准原因!...
  10. Thinking in java 第21章 并发 wait() 与 notifyAll()
  11. 阳谷机器人编程_阳谷实验幼儿园绘本故事《机器人阿泰》
  12. virtualbox与windows共享文件夹
  13. 浅谈一下“敏捷开发”
  14. 传世单机版怎么建立服务端?
  15. 软件研发管理工具Ones横评,对比国内外主流项目管理软件
  16. Word长篇文档排版技巧
  17. 拉普拉斯矩阵(Laplacian matrix)及其变体详解
  18. 极客日报:美团拼多多等平台下架“一分钱秒杀”;全球大量网站集体宕机,一度无法访问;Swift内置对并发的支持
  19. 【洛谷】 P1240 诸侯安置(递推)
  20. 什么是搜索词?有什么用?

热门文章

  1. nginx优化--突破十万并发
  2. 以汉字开头,以某个词结尾的一段文字的正则
  3. 软件持续集成(CI)、持续交付(CD)和持续部署(CD)
  4. 什么是VGA,QVGA,SVGA,XGA?
  5. pytorch图片数据归一化,通常传入transforms.Normalize(mean,std,inplace=False)中的mean和std是如何获取的?
  6. tensorflow2.1学习--熟悉TensorFlow写整个项目即鸢尾花项目
  7. php mysql 设置字符_php mysql字符集设置方法
  8. Spring MVC框架-持久层用hibernate自动化(1)
  9. sql 日期和当前日期时间差_SQL基础进阶16日期处理
  10. 敏感词过滤算法:前缀树算法