OUC软件工程第三次博客作业

卷积神经网络(Convolutional Neural Network)

绪论
1.卷积神经网络应用
  1. 分类
  2. 检索
    • 人脸识别
    • 表情识别
  3. 检测
    • 人脸验证
  4. 分割(有点像抠图)
  5. 自动驾驶
2.传统神经网络vs卷积神经网络

深度学习三部曲
step1. 搭建神经网络结构
step2. 找到一个合适的损失函数
损失函数是衡量吻合度的,可以调整参数/权重W,使得映射的结果和实际类别吻合
传统神经网络也可以应用到计算机视觉,但是会有如下问题:参数太多,会造成过拟合(泛化性能差)
卷积神经网络:局部关联,参数共享
step3. 找到一个合适的优化函数,更新参数
相同之处:分层:卷积层,激活层,池化层,全连接层

基本组成结构

卷积:卷积是对两个实变函数的一种数学操作 实变函数:以实数为自变量的函数
二维卷积
一维卷积:常用在信号处理中,用于计算信号的延迟累计
滤波器(filter)
卷积核:信息的衰减率
基本概念:

  • 输入
  • 卷积核/滤波器
  • 权重
  • 感受野(receptive field)
  • 特征图(feature map)
  • padding(输入的两边补0)
  • 深度(channel)
  • 输出(output)
  • 步长(stride)

池化:(pooling layer):保留了主要特征的同时减少参数和计算量,防止过拟合,提高模型泛化的能力。它一般处于卷积层与卷积层之间,全连接层与全连接层之间。

  1. 最大值池化
  2. 平均值池化

全连接:(FC layer)两层之间的所有神经元都有权重链接,通常全连接层在卷积神经网络的尾部,全连接层参数量通常最大

小结:
  • 一个典型的卷积神经网络是由卷积层、池化层交叉堆叠而成,最后一层是全连接层
卷积神经网络典型结构
AlexNet

非线性激活函数:ReLU函数:优点

  • 解决了梯度消失问题
  • 计算速度特别快,只需要判断输入是否大于0
  • 收敛速度远快于sigmoid
    AlexNet分层解析
ZFNet

网络结构与AlexNet相同

VGG

VGG是一个更深网络 8->16

GoogleNet
  • 网络包含22个带参数的层,独立成块的层总共有100个
  • 参数量大概是Alexnet的1/12
  • 没有FC层
    inception模块 用小的卷积核替代大的卷积核
ResNet(残差学习网络)

代码练习

MNIST 数据集分类
  1. 加载数据(MINIST)

  2. 创建网络

  3. 在小型全连接网络上训练(Fully-connected network)

  1. 在卷积神经网络上训练
# Training settings 
n_features = 6 # number of feature maps

model_cnn = CNN(input_size, n_features, output_size)
model_cnn.to(device)
optimizer = optim.SGD(model_cnn.parameters(), lr=0.01, momentum=0.5)
print('Number of parameters: {}'.format(get_n_params(model_cnn)))

train(model_cnn)
test(model_cnn)

在这里插入图片描述
通过上面的测试结果,可以发现,含有相同参数的 CNN 效果要明显优于 简单的全连接网络,是因为 CNN 能够更好的挖掘图像中的信息,主要通过两个手段:

  • 卷积:Locality and stationarity in images
  • 池化:Builds in some translation invariance
  1. 打乱像素顺序再次在两个网络上训练与测试

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

      Number of parameters: 6442
      Train: [0/60000 (0%)]	Loss: 2.264858
      Train: [6400/60000 (11%)]	Loss: 2.041490
      Train: [12800/60000 (21%)]	Loss: 1.552290
      Train: [19200/60000 (32%)]	Loss: 1.093537
      Train: [25600/60000 (43%)]	Loss: 0.799383
      Train: [32000/60000 (53%)]	Loss: 0.847221
      Train: [38400/60000 (64%)]	Loss: 0.756004
      Train: [44800/60000 (75%)]	Loss: 0.723714
      Train: [51200/60000 (85%)]	Loss: 0.438829
      Train: [57600/60000 (96%)]	Loss: 0.474032
      
      Test set: Average loss: 0.5751, Accuracy: 8348/10000 (83%)
      
    • 在卷积神经网络上训练与测试:

      Number of parameters: 6422
      Train: [0/60000 (0%)]	Loss: 2.300903
      Train: [6400/60000 (11%)]	Loss: 2.282535
      Train: [12800/60000 (21%)]	Loss: 2.261807
      Train: [19200/60000 (32%)]	Loss: 2.111837
      Train: [25600/60000 (43%)]	Loss: 1.717916
      Train: [32000/60000 (53%)]	Loss: 1.320999
      Train: [38400/60000 (64%)]	Loss: 0.960259
      Train: [44800/60000 (75%)]	Loss: 0.961738
      Train: [51200/60000 (85%)]	Loss: 0.636504
      Train: [57600/60000 (96%)]	Loss: 0.507474
      
      Test set: Average loss: 0.6227, Accuracy: 8003/10000 (80%)
      

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

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

CIFAR10 数据集分类

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

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')

网络在整个数据集上的表现:

Accuracy of the network on the 10000 test images: 62 %

使用 VGG16 对 CIFAR10 分类,链接:

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

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

VGG16的网络结构如下图所示:
在这里插入图片描述

  1. 定义dataloader

    需要注意的是,这里的 transform,dataloader 和之前定义的有所不同

  2. 定义VGG网络

  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: %.2f %%' % (
        100 * correct / total))
    

    Accuracy of the network on the 10000 test images: 84.92 %

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

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

    Dataloader中设置了shuffle是True,所以每次加载的数据都是随机的。

    洗牌。默认设置为False。在每次迭代训练时是否将数据洗牌,默认设置是False。将输入数据的顺序打乱,是为了使数据更有独立 性,但如果数据是有序列特征的,就不要设置成True了

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

    transform的作用:对图像进行一定的预处理,相当于扩展数据集。

    transform的处理方法

    1 裁剪-Crop

    2 翻转和旋转——Flip and Rotation

    3 图像变换

    4 对transforms操作,使数据增强更灵活

  3. epoch 和 batch 的区别?

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

    batch:当数据集很大的时候,对于每个epoch,很难将所有的数据集一次读入到内存中,这是需要将数据集分为几次读入,每次称为一个batch。

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

    1*1的卷积:

    1. 添加非线性特性

    即保持特征图尺寸不发生变化且维持上一层的通道数,在增加网络的深度的同时令网络能够学习更为复杂的函数(特征信息)。

    1. 对通道数实现升维降维:一般用降维来减少计算量

    FC(全连接层):起到分类器的作用。对前层的特征进行一个加权和,(卷积层是将数据输入映射到隐层特征空间)将特征空间通过线性变换映射到样本标记空间(也就是label)

    区别:

    全连接是把特征图拆开组成一个一维向量,再乘以一个权重向量,这两个向量中的元素一一对应所以输出结果是一个值。

    11的卷积核那就是表明只由一个权重组成,如果特征图尺寸也是11的话,那输出就是一个值,此时与全连接完全一样。但是如果特征图尺寸不是11,而是wh的话,那么11的卷积输出就不是一个值而是wh的一个矩阵。

    用11卷积代替全连接应该是基于输入尺寸的考虑,全连接的输入是特征图所有元素乘以权重再求和,但是这个权重向量是在设计网络的时候就需要固定的,所以全连接没办法适应输入尺寸的变化只能固定。但是11卷积的输出与输入尺寸是一样大的,输出尺寸可以随着输入尺寸的变化而变化,所以1*1卷积无需固定输出尺寸。

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

    残差的思想都是去掉相同的主体部分,从而突出微小的变化,引入残差后的映射对输出的变化更敏感。很明显,在残差网络中输出的变化对权重的调整影响更大,也就是说反向传播的梯度值更大,训练就更加容易。

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

    • LeNet :最早用于手写数字识别的CNN网络
  7. 有什么方法可以进一步提升准确率?

    1. 增加更多数据

    2. 2.处理缺失值和异常值

    3. 特征工程学:这一步骤有助于从现有数据中提取更多信息。新信息作为新特征被提取出来。这些特征可能会更好地解释训练集中的差异变化。因此能改善模型的准确率。

    4. 特征选择:特征选择是寻找众多属性的哪个子集合,能够最好的解释目标变量与各个自变量的关系的过程。

      你可以根据多种标准选取有用的特征

    5. 使用多种算法

    6. 交叉验证:如果想解决这个问题,我们必须使用交叉验证技术(cross validation)。交叉验证是数据建模领域最重要的概念之一。它是指,保留一部分数据样本不用来训练模型,而是在完成模型前用来验证。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值