天天看点

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

Part 1: 视频学习

一、卷积神经网络的结构

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答
  1. 卷积层:卷积层也叫特征提取层,使用卷积核来提取图像中的特征。

例如:二维卷积:卷积核(F*F*x)是一个矩阵,以一定步长移动

卷积核:一个卷积核有x个权重矩阵,x=原图像通道数

步长:卷积核每次移动几个格子

感受野:卷积核进行一次卷积时输入图像(N*N*x)所对应的区域

特征图:卷积后输出的结果

特征图大小(N-F)/步长+1

特征图大小(N+pedding*2-F)/步长+1

Depth/channel:特征图的深度/个数(和卷积核的个数保持一致)

pedding:如果原图像在卷积的过程中出现一部分不够一次卷积,则在图像四周都补0

参数量=(F*F+1)*channel

二、池化层

  1. 保留主要特征的同时减少参数和计算量,防止过拟合,提高模型泛化能力
  2. 它一般处于卷积层与卷积层之间,全连接层与全连接层之间
  3. 池化核,步长
  4. 类型:

Max polling:最大值池化——分类任务中更倾向

Average polling:平均池化

池化层用处:

     1.特征不变性2.特征降维(下采样)3.在一定程度上防止过拟合,更方便优化。

     4.实现非线性。5.扩大感受野。

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

三、全连接层:

全连接层,是每一个结点都与上一层的所有结点相连,用来把前边提取到的特征综合起来。由于其全相连的特性,一般全连接层的参数也是最多的。全连接层的目的是将网络学习到的特征映射到样本的标记空间中。全连接层会把卷积输出的二维特征图转化成一个一维的向量。

  1. 两层之间的所有神经元都有权重链接
  2. 通常全连接层在卷积神经网络尾部
  3. 全连接层参数量通常最大
第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

全连接:通常全连接层在卷积神经网络尾部。

小结:

一个典型的卷积网络是由卷积层、池化层、全连接层交叉堆叠而成;

未加padding时输出特征图大小:(N-F)/stride+1;

有padding时输出的特征图大小:(N+padding*2-F)/stride+1;

Pooling的类型:Maxing pooling:最大值池化,Average pooling:平均池化;

全连接:通常全连接层在卷积神经网络尾部。

AlexNet:

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

Alexnet共有8层结构,前5层为卷积层,后三层为全连接层。

AlexNet成功的原因在于:

大数据训练:百万级ImageNet图像数据

非线性激活函数:ReLU

防止过拟合:Dropout, Data augmentation

其他:双GPU实现

ReLU函数:

解决了梯度消失的问题(在正区间)

计算速度特别快,只需要判断输入是否大于0,大于0就不用算了

收敛速度远快于sigmoid

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答
第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

DropOut(随机失活)

训练时随机关闭部分神经元。测试时整合所有神经元

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答
第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

进行每一层的分析:

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答
第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

ZFNet

网络结构与AlexNet相同

将卷积层1中的感受野大小由11*11改为7*7,步长由4改为2

卷积层3,4,5中的滤波器个数由384,384,256改为512,512,1024

2013年ImageNet图像分类竞赛的冠军 ImageNet top 5 error: 16.4% -> 14.8%

VGG

VGG是一个更深网络

8 layers (AlexNet) -> 16 – 19 (VGG),先训练前面的11层,把网络固定住,再训练后面的

ILSVRC top 5 错误率从11.7% -> 7.3%

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

GoogleNet

不止是在深度上加深,在结构上也做了改进,2014年ImageNet图像分类竞赛的冠军,ImageNet top 5 error: 11.7% -> 6.7%

网络总体结构:

网络包含22个带参数的层(如果考虑pooling层就是27层),独立成块的层总共有约有100个;

参数量大概是Alexnet的1/12

没有FC层

Naive Inception

初衷:多卷积核增加特征多样性

在同一层用了三个不同的卷积核,对不同卷积核的输出在深度上进行串联,用padding让输出的前两维大小保持一致

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

channel的个数很大,随着模型的加深,chennel的个数一直不断增多,计算复杂度过高

Inception V2

解决思路:插入1*1卷积核进行降维

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

Inception V3

Inception V3 进一步对v2的参数数量进行降低。用小的卷积核替代大的卷积核,一次5*5卷积和两次3*3卷积对应的卷积核大小一样

降低参数量

增加非线性激活函数:增加非线性激活函数使网络产生更多独立特(disentangled

feature),表征能力更强,训练更快。

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

 GoogleNet

Stem部分(stem network):卷积 – 池化 – 卷积 –卷积 – 池化

中间部分:多个Inception结构堆叠

输出:没有额外的全连接层(除了最后的类别输出层)

辅助分类器:解决由于模型深度过深导致的梯度消失的问题。

ResNet

残差学习网络(deep residuallearning network),2015年ILSVRC竞赛冠军, top 5 错

误率从6.7% -> 3.57%。深度有152层

残差的思想: 传统结构是一个连乘的形式,残差多了加和,不会存在梯度消失的问题。去掉相同的主体部分,从而突出微小的变化。

可以被用来训练非常深的网络

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

 Part 2:代码练习

一、MNIST 数据集分类

1. 加载数据 (MNIST)

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答
第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

显示数据集中的部分图像

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

2. 创建网络

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答
第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答
第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

3. 在小型全连接网络上训练

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

 4. 在卷积神经网络上训练

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

5. 打乱像素顺序再次在两个网络上训练与测试

下面代码展示随机打乱像素顺序后,图像的形态:

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

重新定义训练与测试函数

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答
第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

在全连接网络上训练与测试:

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

在卷积神经网络上训练与测试: 

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

从打乱像素顺序的实验结果来看,全连接网络的性能基本上没有发生变化,但是 卷积神经网络的性能明显下降。

这是因为对于卷积神经网络,会利用像素的局部关系,但是打乱顺序以后,这些像素间的关系将无法得到利用。

二、CIFAR10数据集分类

CIFAR10数据集包含10个类别,图像尺寸为33232,可以使用torchsivion加载,torchvision数据集的输出范围是[0,1]的PILImage,使用前需要先进行归一化操作,转换为[-1,1]的张量。

import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import numpy as np
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

# 使用GPU训练
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

transform = transforms.Compose([transforms.ToTensor(),
              transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))])

# 训练的shuffle是True,打乱顺序增加样本多样性,测试的shuffle是false
trainset = torchvision.datasets.CIFAR10(root='./data',train=True,download=True,transform=transform)
trainloader = torch.utils.data.DataLoader(trainset,batch_size=64,shuffle=True,num_workers=2)

testset = torchvision.datasets.CIFAR10(root='./data',train=False,download=True,transform=transform)
testloader = torch.utils.data.DataLoader(testset,batch_size=8,shuffle=False,num_workers=2)

classes = ('plane','car','bird','cat','deer','dog','frog','horse','ship','truck')

def imshow(img):
plt.figure(figsize=(8,8))
img = img/2+0.5 # 转换为[0,1]
npimg = img.numpy()
plt.imshow(np.transpose(npimg,(1,2,0)))
plt.show()

# 得到一组图像
images,labels = iter(trainloader).next()
# 展示图像
imshow(torchvision.utils.make_grid(images))
# 展示第一行图像的标签
for j in range(8):
print(classes[labels[j]])
           
第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

 接下来定义网络,损失函数和优化器:

class Net(nn.Module):
  def __init__(self):
      super(Net, self).__init__()
      self.conv1 = nn.Conv2d(3, 6, 5)
      self.pool = nn.MaxPool2d(2, 2)
      self.conv2 = nn.Conv2d(6, 16, 5)
      self.fc1 = nn.Linear(16 * 5 * 5, 120)
      self.fc2 = nn.Linear(120, 84)
      self.fc3 = nn.Linear(84, 10)
​
  def forward(self, x):
      x = self.pool(F.relu(self.conv1(x)))
      x = self.pool(F.relu(self.conv2(x)))
      x = x.view(-1, 16 * 5 * 5)
      x = F.relu(self.fc1(x))
      x = F.relu(self.fc2(x))
      x = self.fc3(x)
      return x
​
# 网络放到GPU上
net = Net().to(device)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(net.parameters(), lr=0.001)
           

训练网络:

for epoch in range(10): # 重复多轮训练
  for i, (inputs, labels) in enumerate(trainloader):
      inputs = inputs.to(device)
      labels = labels.to(device)
      # 优化器梯度归零
      optimizer.zero_grad()
      # 正向传播 + 反向传播 + 优化 
      outputs = net(inputs)
      loss = criterion(outputs, labels)
      loss.backward()
      optimizer.step()
      # 输出统计信息
      if i % 100 == 0:   
          print('Epoch: %d Minibatch: %5d loss: %.3f' %(epoch + 1, i + 1, loss.item()))
​
print('Finished Training')
           
第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答
第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答
第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

 现在我们从测试集中取出8张图片:

# 得到一组图像
images, labels = iter(testloader).next()
# 展示图像
imshow(torchvision.utils.make_grid(images))
# 展示图像的标签
for j in range(8):
  print(classes[labels[j]])
           
第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

 我们把图片输入模型,看看CNN把这些图片识别成什么:

outputs = net(images.to(device))
_, predicted = torch.max(outputs, 1)
​
# 展示预测的结果
for j in range(8):
  print(classes[predicted[j]])
           
第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

 可以看到,有几个都识别错了~~~ 让我们看看网络在整个数据集上的表现:

correct = 0
total = 0
​
for data in testloader:
  images, labels = data
  images, labels = images.to(device), labels.to(device)
  outputs = net(images)
  _, predicted = torch.max(outputs.data, 1)
  total += labels.size(0)
  correct += (predicted == labels).sum().item()
​
print('Accuracy of the network on the 10000 test images: %d %%' % (
  100 * correct / total))
           
第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

三、使用 VGG16 对 CIFAR10 分类 

VGG是由Simonyan 和Zisserman在文献《Very Deep Convolutional Networks for Large Scale Image Recognition》中提出卷积神经网络模型,其名称来源于作者所在的牛津大学视觉几何组(Visual Geometry Group)的缩写。

该模型参加2014年的 ImageNet图像分类与定位挑战赛,取得了优异成绩:在分类任务上排名第二,在定位任务上排名第一。

VGG16的网络结构如下图所示:

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

6层网络的结节信息如下:

  • 01:Convolution using 64 filters
  • 02: Convolution using 64 filters + Max pooling
  • 03: Convolution using 128 filters
  • 04: Convolution using 128 filters + Max pooling
  • 05: Convolution using 256 filters
  • 06: Convolution using 256 filters
  • 07: Convolution using 256 filters + Max pooling
  • 08: Convolution using 512 filters
  • 09: Convolution using 512 filters
  • 10: Convolution using 512 filters + Max pooling
  • 11: Convolution using 512 filters
  • 12: Convolution using 512 filters
  • 13: Convolution using 512 filters + Max pooling
  • 14: Fully connected with 4096 nodes
  • 15: Fully connected with 4096 nodes
  • 16: Softmax

1. 定义 dataloader 

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

2. VGG 网络定义

下面定义VGG网络,参数太多,我手动改简单了些~~~

现在的结构基本上是:

64 conv, maxpooling,

128 conv, maxpooling,

256 conv, 256 conv, maxpooling,

512 conv, 512 conv, maxpooling,

512 conv, 512 conv, maxpooling,

softmax

下面是模型的实现代码:

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

 初始化网络,根据实际需要,修改分类层。

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

 3. 网络训练

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答
第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

 注意:两个矩阵的行列相乘需匹配,故将2048改为512

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

 4. 测试验证准确率

第三次作业:卷积神经网络基础Part 1: 视频学习 Part 2:代码练习Part 3:问题解答

 可以看到,使用一个简化版的 VGG 网络,就能够显著地将准确率提升到83.47%

Part 3:问题解答

1. dataloader 里面 shuffle 取不同值有什么区别?

DataLoader中的shuffer=False表示不打乱数据的顺序,然后以batch为单位从头到尾按顺序取用数据。DataLoader中的shuffer=True表示在每一次epoch中都打乱数据顺序,然后以batch为单位从头到尾按顺序取用数据

2、transform 里,取了不同值,这个有什么区别?

transforms.ToTensor()函数的作用是将原始的PILImage格式或者numpy.array格式的数据格式化为可被pytorch快速处理的张量类型。

transforms.Normalize()是数据标准化函数,可以逐channel的对图像进行标准化(均值变为0,标准差变为1),可以加快模型的收敛。

3、epoch 和 batch 的区别?

Batch大小是在更新模型之前处理的多个样本。Epoch数是通过训练数据集的完整传递次数。

当一个完整的数据集通过了神经网络一次并且返回了一次,这个过程称为一次epoch。

将整个训练样本分成若干个部分,并称为Batch。

Epoch由一个或多个Batch组成

4、1x1的卷积和 FC 有什么区别?主要起什么作用?

区别:1*1的卷积核是输入map大小不固定的,而全连接是固定的。卷积层使得网络可以接受任意的输入,因为卷积作用在一个局部的区域,而全连接则对于整个输入而言。

1*1卷积的作用:

  1. 如果当前层与下一层层数均非1,则可以起到跨通道聚合的作用,从而改变维度,进而达到减少参数的作用。
  2. 可以用于调节通道数,对不同的通道上的像素点进行线性组合,然后进行非线性化操作,灵活控制特征图的深度
  3. 改变维度的操作就是通道间信息的线性组合变化,即通道间的信息交互。1*1卷积可以在保持feature map尺度不变的前提下大幅增加非线性特性,把网络做的很深,增加非线性特性。

Fc的作用:

  1. 在整个卷积神经网络中起到”分类器“的作用,即将学到的“分布式特征表示”映射到样本标记空间的作用
  2. FC可在模型表示能力迁移过程中充当“防火墙”的作用。

​​​​​​5. ​residual leanring 为什么能够提升准确率?

通过支路的设计在传递时加上本身,形成了Y=F(x)+x的结构,这样一来,无论经过多少层求导,梯度始终不会小于1,解决了梯度消失的问题,因此能够增加网络深度来提高准确率。

6、代码练习二里,网络和1989年 Lecun 提出的 LeNet 有什么区别?

激活函数不同:LeNet网络使用的是sigmoid激活函数,而AlexNet使用的是ReLU函数。ReLU函数可以有效避免梯度消失的问题

7、代码练习二里,卷积以后feature map 尺寸会变小,如何应用 Residual Learning?

可以利用1x1卷积改变channel个数,从而达成一致

8、有什么方法可以进一步提升准确率?

(1)对于residual leanring,可以增加深度与节点数

(2)增加训练轮数

(3)丰富数据集中的数据

(4)优化网络结构

继续阅读