欠拟合和过拟合+交叉检验+减轻过拟合(dropout+regularization泛化+数据增强+early stopping)+动量和学习率衰减+卷积原理+常见卷积神经网络

一、欠拟合和过拟合

1、欠拟合:使用模型的复杂度小于真实模型的复杂度

在这里插入图片描述

体现在:训练集的loss和准确率都不够理想;测试集的loss和准确率也不理想。

2、过拟合:使用模型的复杂度大于真实模型的复杂度

在这里插入图片描述
体现在:train训练的时候loss和准确率都表现得非常好,但是在测试集上变现得特别不好——泛化能力较差(Generalization Performance)
现实生活中,更多的情况是overfitting。数据集有限,包含了噪声会被模型学习到。
下图分别展示了欠拟合,恰好拟合和过拟合的情况
在这里插入图片描述

3、怎样检测过拟合?K-flod cross-validation

交叉检验第一次切分的train set 和 val set可以重新整合之后再次随机切分,长时间来说,每个数据都有可能参与到训练中,防止了模型死记硬背,还能充分利用现有的数据集,这样增加了训练的准确性。

通过测试集中的准确率来检测学习情况,提前终止overfitting的情况,我们往往会选取准确率达到最大值的参数为模型的最佳参数值,用来提供给客户做预测检验
在这里插入图片描述
上述是我们教学过程中的实验,只有两个数据集,traning和test(这里的test也是val set),但是在实际应用中,我们通常有三个数据集,train set用来学习,val set用来挑选最佳参数和模型,最后由用户的test set来进行检验
在这里插入图片描述
通过randomsplit将训练接进行切割,切割成真正的训练集和val set
通过randomsplit将训练接进行切割
最终交付给test set之后是不能反馈准确率的,否则在此基础上再次挑选参数和模型,这个test set的作用和val set就一样了——数据污染,某种程度上讲,是一种作弊。

4、如何减轻过拟合?

Occam’s Razor:
more thing should not be uesd than are necessary 任何不必要的都不需要

(1)提供更多的数据——这是代价做大、也是最困难的方法;

(2)简化模型

shallow模型不需要用太复杂的,尤其是当数据集有限的时候。shallow是一个相对的概念,跟数据集大小和网络的复杂度有关。

(3)Dropout——增加鲁棒性

Dropout——防止过拟合的一种方法

减少了隐藏层之间的神经元的连接量,Learning less to learn more,会使得曲线较为平缓且泛化
在这里插入图片描述
在这里插入图片描述
需要特别说明的是

在torch里面,p代表的是断掉的概率,在tensorflow里面p代表的是保持连接的概率。
在这里插入图片描述
此外,我们约定了在test中,需要全部连接神经,需要手动切断dropout

关键的一句是:net_dropeed.eval( )
在这里插入图片描述
Stochastic Gradient Descent并不是完全随机的,而是符合某一个分布的

从train set里面抽取出来一个batch比如16、32、64、128等,计算其所有在某个x上的梯度求和再平均得到梯度值。优点:节约显存
在这里插入图片描述

(4)Data argumentation——数据增强

神经网络对数据的要求非常饥渴,需要贴有标签的大量数据

当数据量有限的时候:1、要减少神经网络的隐藏层;2、Regularization,迫使一部分权值接近于0,让网络的表现更加稳定;3、数据增强,目前的数据量较少,想办法对数据进行变换——旋转、裁剪加噪声等

Flip——翻转

可以从水平方向和竖直方向进行翻转,这里增加了random属性,代表翻转是具有随机性的,有可能进行水平翻转,也有可能不翻转,有可能垂直翻转,也有可能不翻转
在这里插入图片描述
Rotate——旋转
在这里插入图片描述
Scale——缩放

以中心点为标准进行缩放Resize,传入的是list
在这里插入图片描述
Crop Part

随机得进行裁剪

transform是torchvision里面自带的包, transform.Compose()可以把一系列翻转、旋转、裁剪和缩放操作组合在一起
在这里插入图片描述
Noise——加噪声,用的不多

即使得到了无穷多的数据,由于进行变换后的数据和原本的数据非常接近,所以训练的结果仅仅能得到一个很小的提升

(5)Early Stopping——提前终结

在这里插入图片描述
我们要在过拟合之前停止

1、设置val set

2、监听在各个参数值下的val set的表现

3、在val 表现最好的时候停止——一定程度上需要有经验

(6)regularization——泛化

我们一开始的目标是最小化交叉熵,下面是目标函数:
在这里插入图片描述
但经过训练之后,为了增强模型的表达能力,很可能出现一个7次方的函数式

接下来我们增加一个参数范式,这里的参数有w1,b1,w2,b2等等
在这里插入图片描述
可以是一范数,可以是二范数。

优势1:当我们的总目标是尽可能小化J(Q)时,一范式参数值也会尽可能得小,总体来说会使我们的模型更加平缓和稳定,更加具有总体数据代表性。

优势2:会简化模型,有可能将高次方模型转变为低次方模型,同时还能保持模型的表达性

常用的两种regularization
在这里插入图片描述
pytorch有自带的L2-regularization
在这里插入图片描述
这个wieght_decay是二范数的参数值,传入这个参数就可以以二范数进行泛化了

L1_regularization

现阶段没有参数一范数的现成代码,需要自己敲
在这里插入图片描述

二、动量和学习率衰减

1、动量——惯性

在这里插入图片描述

动量是考虑了之前的运动方向的变量

不考虑动量的情况下,会在局部极小值点停止
在这里插入图片描述
考虑动量的情况下,在局部极小值点处仍然会向前走,比较容易找到全局最优解
在这里插入图片描述
优化器中SGD没有考虑动量,可以自己加momentum参数,Adam里面考虑了动量因素,不需要手动加
在这里插入图片描述

2、学习率衰减——迫使学习率逐渐变为0

这这里我们并不能指明最合适的学习率,但我们可以让学习率递减,好处是可以较快得找到更好的解
不同的学习率表现情况
这这里我们并不能指明最合适的学习率,但我们可以让学习率递减,好处是可以较快得找到更好的解
在这里插入图片描述
方法一:使用ReducelROnPlateau()函数,传入optimizer 和min,前者用来识别学习率的值,后者用来监听loss,当在某一个学习率上在一定的步长范围内,loss都没有很明显的变化,我们的函数将会自动调整学习率;
在这里插入图片描述
方法二:直接规定一个确切步长,确定一个变化率
最开始步长为30变化率为0.1,以0.1的比例进行衰减
在这里插入图片描述

三、卷积神经

1、卷积原理:

在这里插入图片描述
神经网络里的卷积是离散数值,是小窗口的矩阵相乘相加操作
在这里插入图片描述
卷积神经网络中f(x,y)里面的x和y分别是距离坐标原点的距离(偏置)

2、概念:

Input_channels输入的通道(黑白图有1个通道,彩图RGB有三个通道)

Kernel_channels有多少个核(边缘核、模糊核都有就是两个核)

Kernel_size核的大小,2x2,或者是3x3

stride:步长

Padding(打补丁):在两边补空白的数量,2列是2,1行是1

3、 Multi-Kernels

每一个通道上都需要有相同的卷积核,每个通道可以有1个2个甚至更多的卷积核,但是每个通道上的卷积核都必须相同!每个核之间可以不同
在这里插入图片描述

import torch
import torch.nn as nn
import torch.nn.functional as F


x = torch.rand(1, 1, 28, 28)
#输入了一张照片,一个通道,照片大小是28x28
layer = nn.Conv2d(1, 3, kernel_size=3, stride=1, padding=0)
#输入通道有1,卷积核有3个,卷积核的大小是3x3,步长为1,没有打补丁
out = layer(x)
print(out.shape)
#torch.Size([1, 3, 26, 26])
#最终输出的是一张照片,有三个卷积值,因为有三个卷积核,大小为26x26

x = torch.rand(1, 1, 28, 28)
layer = nn.Conv2d(1, 3, kernel_size=3, stride=2, padding=1)
out = layer(x)
print(out.shape)
#torch.Size([1, 3, 14, 14])

print(layer.weight)
'''
tensor([[[[-0.0450, -0.3113,  0.2603],
          [ 0.0272, -0.1302, -0.1772],
          [-0.1471,  0.2183, -0.0578]]],


        [[[-0.0747, -0.3240,  0.2816],
          [ 0.1267, -0.2136,  0.1107],
          [ 0.1754,  0.2550, -0.2917]]],


        [[[ 0.0419, -0.1789,  0.1894],
          [-0.2625,  0.2120, -0.0755],
          [-0.2954, -0.1984,  0.1967]]]], requires_grad=True)
'''

print(layer.weight.shape)
#torch.Size([3, 1, 3, 3])

print(layer.bias.shape)
#torch.Size([3]) bias的数量和卷积核的个数一致


x = torch.randn(1, 3, 28, 28)
w = torch.randn(16, 3, 5, 5)
#卷积核有16个,通道和x输入的通道一致,大小为5x5
b = torch.randn(16)

out = F.conv2d(x, w, b, stride=1, padding=1)
print(out.shape)
#torch.Size([1, 16, 26, 26])

out_1 = F.conv2d(x, w, b, stride=2, padding=2)
print(out_1.shape)
#torch.Size([1, 16, 14, 14])
#卷积核在每个通道上的每一步都会计算一个相乘相加值,此外,对于每一个通道上相同卷积权重得到的值还会相加,所以最终得到的照片有16个通道


4、池化层(pooling)

(1)向下采样:

Max pooling

采集的是窗口内的最大值
在这里插入图片描述
Avg pooling

采集的是窗口数值的均值

#池化层,向下采样
x = torch.randn(1, 16, 28, 28)
layer = nn.MaxPool2d(2, stride=2)
out = layer(x)
print(out.shape)
#torch.Size([1, 16, 14, 14])

out_1 = F.avg_pool2d(x, 2, stride=2)
print(out_1.shape)
#torch.Size([1, 16, 14, 14])

(2)向上取样
取最近距离的值进行简单的复制,增加照片的像素维度

#向上采样
x = torch.randn(1, 16, 7, 7)
out = F.interpolate(x, scale_factor=2, mode='nearest')
print(out.shape)
#torch.Size([1, 16, 14, 14]) 图片放大了两倍

out_1 = F.interpolate(x, scale_factor=3, mode='nearest')
print(out_1.shape)
#torch.Size([1, 16, 21, 21])

x = out
layer = nn.ReLU(inplace=True)
out = layer(x)
print(out.shape)
#torch.Size([1, 16, 14, 14])


out_2 = F.relu(x)
print(out_2.shape)
#torch.Size([1, 16, 14, 14])

5、BatchNorm

将不同维度的值都缩放到一个以0为均值,以某个值为方差的比较均匀的分布上

Feature scaling
在这里插入图片描述
输入R、G、B各通道的均值和方差,normaliazation的具体过程是
在这里插入图片描述
Batch Norm有以下四种,只是以哪个维度为标准的区别
在这里插入图片描述
我们主要学习Batch normalization以通道为基准,计算每个通道上的均值和方差,然后通过减均值除以方法来使这些值均匀得分布在某个范围内
在这里插入图片描述
规范化算法 计算均值和方差、标准化、 缩放
在这里插入图片描述
在测试集上,我们把训练集的runnnig_mean/running_var直接赋值给训练集,test没有backward,所有w和b并不需要更新,不需要梯度更新

#batch normalization
x = torch.rand(100, 16, 784)
#均匀分布
layer = nn.BatchNorm1d(16)
#这里的16是通道的意思
out = layer(x)

print(layer.running_mean)
#print(layer.running_mean)
'''
tensor([0.0503, 0.0500, 0.0502, 0.0500, 0.0499, 0.0500, 0.0500, 0.0498, 0.0500,
        0.0502, 0.0501, 0.0501, 0.0499, 0.0499, 0.0500, 0.0500])
'''
print(layer.running_var)
'''
tensor([0.9083, 0.9084, 0.9084, 0.9083, 0.9083, 0.9083, 0.9083, 0.9083, 0.9083,
        0.9083, 0.9083, 0.9083, 0.9084, 0.9084, 0.9084, 0.9083])
'''

6、现有的卷积神经网络

(1)leNet-5将准确率提升了10%+

在这里插入图片描述

(2)AlexNet使用了下采样层和relu激活函数

在这里插入图片描述

(3)VGG

研究发现卷积核较小的时候不仅可以提高运算量,且对图片表达也没有下降
在这里插入图片描述

(4)GoogLeNet

在每个隐藏层都使用了不同大小的卷积核,从不同的视觉大小更深刻得学习图片
在这里插入图片描述

(5)ResNet

在这里插入图片描述
引入了残差的概念
在这里插入图片描述

import torch
import torch.nn as nn
import torch.nn.functional as F


class ResBlk(nn.Module):
    def __init__(self, ch_in, ch_out):
        self.conv1 = nn.Conv2d(ch_in, ch_out, kernel_size=3, stride=1, padding=1)
        self.bn1 = nn.BatchNorm2d(ch_out)
        self.con2 = nn.Conv2d(ch_out, ch_out, kernel_size=3, stride=1, padding=1)
        self.bn2 = nn.BatchNorm2d(ch_out)

        self.extra = nn.Sequential()
        if ch_out != ch_in:
            self.extra = nn.Sequential(
                nn.Conv2d(ch_in, ch_out, kernel_size=1, stride=1),
                #如果输入维度不等于输出维度,我通过这一步骤来把维调节成相同的
                nn.BatchNorm2d(ch_out)
            )

    def forward(self, x):
        out = F.relu(self.bn1(self.conv1))
        out = self.bn2(self.con2(out))
        out = self.extra(x) + out
        return out

(6)DenseNet

最上面的没有短接的神经网络

第二个是Resnet

最后一个是DenseNet

从图片上可以看出来区别
在这里插入图片描述

四、nn.Module介绍

nn.Module的好处

提供了很多现成的网络层
在这里插入图片描述

1、container——nn.Sequential()

将神经网络内部的结构按照顺序进行编码

net = nn.Sequential()可以直接实现网络前向传播

2、其次,通过net.parameters( )可以返回想要的参数;也可以通过net.parameters( )把参数丢到优化器里

3、modules里面包括了所有的节点;里面包括很多子节点——直系亲属

在这里插入图片描述
整个net有5个节点
在这里插入图片描述

4、save和load

在这里插入图片描述

5、train和test状态切换很方便

在这里插入图片描述

6、implement own layer

由于实际需要定义一个flatten类,我们通过nn.Sequential()来把函数有序排列起来组成我们主要的神经网络结构
在这里插入图片描述

7、通过nn.Parameter( )实现自己的参数定义

在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值