赞
踩
最大值池化,是取当前池化视野中所有元素的最大值,输出到下一层特征图中。
平均值池化,是取当前池化视野中所有元素的平均值,输出到下一层特征图中。
池化作用:
平移不变性说明:
虽然池化之前两幅图片的眼睛特征不在一个位置,但是经过池化之后,眼睛特征的位置都是相同的
层与层之间会有若干个卷积核(kernel)(也称为过滤器),卷积核深度与初始图片的通道数一致。
上一层所有feature map 对应的 跟某个卷积核的所有层做卷积,结果相加(或者再加上偏置),都会产生下一层的一个feature map,有N个卷积核,下层就会产生N个feather map。即:输入图片不论通道数是1(灰色)还是3(彩色)or其他值,经过卷积核处理后,都会统一拍平成深度为1的feature map。有几个卷积核就生成几个feature map,与输入图片的通道数无关。
多个feature map作用:我们希望构造一组基,这组基能够形成对于一个事物完备的描述,例如描述一个人时我们通过描述身高/体重/相貌等,在卷积网中也是如此。在同一层,我们希望得到对于一张图片多种角度的描述,具体来讲就是用多种不同的卷积核对图像进行卷,得到不同核(这里的核可以理解为描述)上的响应,作为图像的特征。他们的联系在于形成图像在同一层次不同基上的描述。
(a) 全连接式
(b)自己对自己
RNN关注隐层每个神经元在时间维度上的不断成长与进步,变换一下3D的视角,网络结构不变,没有添加新的神经元,但是沿着时间轴recurrent,也就是重复,建立时序上的关联,这里的层级扩展并非神经元数量的真实增加,而是表示隐层在不同时刻的状态。RNN本质上是用一种看似是级联,但实际上却是沿着时序,反复迭代的网络结构,实现了对序列数据的学习。
假如用来表示层级间的权重矩阵,RNN通常会假定不同的层,其实也就是不同的时刻共享一个,这样可以有效地减少训练参数。
在CNN中,卷积层用于学习图像的局部特征,然后这些特征被传递到全连接层,以进行分类或其他任务。具体来说,CNN的算法步骤如下:
整体过程
提取人眼睛特征过程
RNN的算法原理是基于循环连接的。在RNN中,每个隐藏单元都有一个状态,这个状态在每个时间步被更新。这使得RNN能够捕捉到序列中的长期依赖关系。具体来说,RNN的算法步骤如下:
- import torch # 需要的各种包
- import torch.nn as nn
- from torch.autograd import Variable
- import torch.utils.data as data
- import matplotlib.pyplot as plt
- import torchvision # 数据库模块
-
-
- # 数据预处理
- # 将training data转化成torch能够使用的DataLoader,这样可以方便使用batch进行训练
- torch.manual_seed(1) # reproducible 将随机数生成器的种子设置为固定值,这样,当调用时torch.rand(x),结果将可重现
-
- # Hyper Parameters
- EPOCH = 1 # 训练迭代次数
- BATCH_SIZE = 50 # 分块送入训练器
- LR = 0.001 # 学习率 learning rate
-
- train_data = torchvision.datasets.MNIST(
- root='./mnist/', # 保存位置 若没有就新建
- train=True, # training set
- transform=torchvision.transforms.ToTensor(), #
- # converts a PIL.Image or numpy.ndarray to torch.FloatTensor(C*H*W) in range(0.0,1.0)
- download=True
- )
-
- test_data = torchvision.datasets.MNIST(root='./MNIST/')
-
- # 如果是普通的Tensor数据,想使用 torch_dataset = data.TensorDataset(data_tensor=x, target_tensor=y)
- # 将Tensor转换成torch能识别的dataset
- # 批训练, 50 samples, 1 channel, 28*28, (50, 1, 28 ,28)
- train_loader = data.DataLoader(dataset=train_data, batch_size=BATCH_SIZE, shuffle=True)
-
- test_x = Variable(torch.unsqueeze(test_data.test_data, dim=1), volatile=True).type(torch.FloatTensor)[:2000]/255.
- # torch.unsqueeze 返回一个新的张量,对输入的既定位置插入维度 1
-
- test_y = test_data.test_lables[:2000]
- # 数据预处理
-
-
- # 定义网络结构
- # 1)class CNN需要·继承·Module
- # 2)需要·调用·父类的构造方法:super(CNN, self).__init__()
- # 3)在Pytorch中激活函数Relu也算是一层layer
- # 4)需要·实现·forward()方法,用于网络的前向传播,而反向传播只需要·调用·Variable.backward()即可。
- # 输入的四维张量[N, C, H, W]
- class CNN(nn.Module):
- def __init__(self):
- super(CNN, self).__init__()
- # nn.Sequential一个有序的容器,神经网络模块将按照在传入构造器的顺序依次被添加到计算图中执行,
- # 同时以神经网络模块为元素的有序字典也可以作为传入参数
- # nn.Conv2d 二维卷积 先实例化再使用 在Pytorch的nn模块中,它是不需要你手动定义网络层的权重和偏置的
- self.conv1 = nn.Sequential( #input shape (1,28,28)
- nn.Conv2d(in_channels=1, #input height 必须手动提供 输入张量的channels数
- out_channels=16, #n_filter 必须手动提供 输出张量的channels数
- kernel_size=5, #filter size 必须手动提供 卷积核的大小
- # 如果左右两个数不同,比如3x5的卷积核,那么写作kernel_size = (3, 5),注意需要写一个tuple,而不能写一个列表(list)
- stride=1, #filter step 卷积核在图像窗口上每次平移的间隔,即所谓的步长
- padding=2 #con2d出来的图片大小不变 Pytorch与Tensorflow在卷积层实现上最大的差别就在于padding上
- ), # output shape (16,28,28) 输出图像尺寸计算公式是唯一的 # O = (I - K + 2P)/ S +1
- nn.ReLU(), # 分段线性函数,把所有的负值都变为0,而正值不变,即单侧抑制
- nn.MaxPool2d(kernel_size=2) #2x2采样,28/2=14,output shape (16,14,14) maxpooling有局部不变性而且可以提取显著特征的同时降低模型的参数,从而降低模型的过拟合
- )
- self.conv2 = nn.Sequential(nn.Conv2d(16, 32, 5, 1, 2), #output shape (32,7,7)
- nn.ReLU(),
- nn.MaxPool2d(2))
- # 因上述几层网络处理后的output为[32,7,7]的tensor,展开即为7*7*32的一维向量,接上一层全连接层,最终output_size应为10,即识别出来的数字总类别数
- # 在二维图像处理的任务中,全连接层的输入与输出一般都设置为二维张量,形状通常为[batch_size, size]
- self.out = nn.Linear(32*7*7, 10) # 全连接层 7*7*32, num_classes
-
- def forward(self, x):
- x = self.conv1(x) # 卷一次
- x = self.conv2(x) # 卷两次
- x = x.view(x.size(0), -1) #flat (batch_size, 32*7*7)
- # 将前面多维度的tensor展平成一维 x.size(0)指batchsize的值
- # view()函数的功能根reshape类似,用来转换size大小
- output = self.out(x) # fc out全连接层 分类器
- return output
- # 定义网络结构
-
-
- # 查看网络结构
- cnn = CNN()
- print(cnn) # 使用print(cnn)可以看到网络的结构详细信息,可以看到ReLU()也是一层layer
- # 查看网络结构
-
-
- # 训练 需要特别指出的是记得每次反向传播前都要清空上一次的梯度,optimizer.zero_grad()
- # optimizer 可以指定程序优化特定的选项,例如学习速率,权重衰减等
- optimizer = torch.optim.Adam(cnn.parameters(), lr=LR) # torch.optim是一个实现了多种优化算法的包
-
- # loss_fun CrossEntropyLoss 交叉熵损失
- # 信息量:它是用来衡量一个事件的不确定性的;一个事件发生的概率越大,不确定性越小,则它所携带的信息量就越小。
- # 熵:它是用来衡量一个系统的混乱程度的,代表一个系统中信息量的总和;信息量总和越大,表明这个系统不确定性就越大。
- # 交叉熵:它主要刻画的是实际输出(概率)与期望输出(概率)的距离,也就是交叉熵的值越小,两个概率分布就越接近
- loss_func = nn.CrossEntropyLoss() # 该损失函数结合了nn.LogSoftmax()和nn.NLLLoss()两个函数 适用于分类
-
- # training loop
- for epoch in range(EPOCH):
- for i, (x, y) in enumerate(train_loader):
- batch_x = Variable(x)
- batch_y = Variable(y)
- output = cnn(batch_x) # 输入训练数据
- loss = loss_func(output, batch_y) # 计算误差 # 实际输出, 期望输出
- optimizer.zero_grad() # 清空上一次梯度
- loss.backward() # 误差反向传递 只需要调用.backward()即可
- optimizer.step() # cnn的优化器参数更新
- # 训练
-
-
- # 预测结果
- # cnn.eval()
- test_output = cnn(test_x[:10])
- pred_y = torch.max(test_output, 1)[1].data.numpy().squeeze()
- # torch.max(input, dim)函数
- # torch.max(test_output, 1)[1] 取出来indices 每行最大值的索引
- # 输入 input是softmax函数输出的一个tensor
- # 输入 dim是max函数索引的维度0/1,0是每列的最大值,1是每行的最大值
- # 输出 函数会返回两个tensor,第一个tensor是每行的最大值;第二个tensor是每行最大值的索引。
- # squeeze()函数的功能是:从矩阵shape中,去掉维度为1的。例如一个矩阵是的shape是(5, 1),使用过这个函数后,结果为(5,)。
- print(pred_y, 'prediction number')
- print(test_y[:10], 'real number')
- # 预测结果
- #pytorch调用RNN代码
- class RNN(nn.Module):
- def __init__(self, input_size, output_size, hidden_dim, n_layers):
- super(RNN, self).__init__()
- #隐藏层特征数量
- self.hidden_dim=hidden_dim
- '''
- input_size – 输入x中预期特征的数量
- hidden_size – 隐藏状态h的特征数量
- num_layers - 循环层数。例如,设置 num_layers=2意味着将两个RNN 堆叠在一起形成一个堆叠的RNN,第二个RNN接收 第一个RNN的输出并计算最终结果。默认值:1
- nonlinearity — 隐藏层函数,可以是“tanh”或“relu”。默认值:'tanh'
- bias - 如果为 False,则该层不使用偏差权重。默认值:真
- batch_first - 输入特征是不是批量输入。默认值False
- dropout - 是否要引入Dropout层,dropout概率等于dropout。默认值:0
- bidirectional —如果为真,则成为双向 RNN。默认值:假
- '''
- self.rnn = nn.RNN(input_size, hidden_dim, n_layers, batch_first=True)
- #全连接层
- self.fc = nn.Linear(hidden_dim, output_size)
-
- def forward(self, x, hidden):
- #批量输入大小
- batch_size = x.size(0)
- #批量输入input,隐藏层参数
- r_out, hidden = self.rnn(x, hidden)
- #维度转化
- r_out = r_out.view(-1, self.hidden_dim)
- #全连接
- output = self.fc(r_out)
- return output, hidden
【参考资料】
RNN vs. CNN vs. 深度神经网络:比较与应用 - 知乎 (zhihu.com)
深度学习 --- 卷积神经网络CNN(LeNet-5网络详解)_zsffuture-百度飞桨星河社区 (csdn.net)
卷积神经网络(CNN)详细介绍及其原理详解 (qq.com) 【重点】
视频:【【循环神经网络】5分钟搞懂RNN,3D动画深入浅出】https://www.bilibili.com/video/BV1z5411f7Bm?vd_source=1eaeed589239e54203e51aff11bb3d44
RNN 的基本原理+pytorch代码_rnn pytorch-CSDN博客https://www.cnblogs.com/yh-blog/p/10052915.htmlRNN 的基本原理+pytorch代码_rnn pytorch-CSDN博客
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。