深度学习实验四:经典全连接神经网络和卷积神经网络

实验实例为:https://aistudio.baidu.com/projectdetail/4822979

一、实验目的

  1. 比较经典全连接神经网络和卷积神经网络
  2. 基础:修改模型输入、增加调用训练全连接模型代码、输出Loss值进行比对
  3. 拓展:微调超参数,比较结果、增加全连接层层数,比较运行时间和效果

二、实验环境

AI Studio 2.3.2、Python 3

三、实验内容

1.分别训练“全连接网络模型”和“卷积神经网络模型”,比较经典全连接神经网络和卷积神经网络的损失变化

(1)对数据集进行加载并区分,定义相关参数

  # 加载数据
    datafile = './work/mnist.json.gz'
    print('loading mnist dataset from {} ......'.format(datafile))
    data = json.load(gzip.open(datafile))
    print('mnist dataset load done')
    # 读取到的数据区分训练集,验证集,测试集
    train_set, val_set, eval_set = data
    # 数据集相关参数,图片高度IMG_ROWS, 图片宽度IMG_COLS
    IMG_ROWS = 28
    IMG_COLS = 28

    if mode == 'train':
        # 获得训练数据集
        imgs, labels = train_set[0], train_set[1]
    elif mode == 'valid':
        # 获得验证数据集
        imgs, labels = val_set[0], val_set[1]
    elif mode == 'eval':
        # 获得测试数据集
        imgs, labels = eval_set[0], eval_set[1]
    else:
        raise Exception("mode can only be one of ['train', 'valid', 'eval']")

(2)校验数据,定义数据生成器

   #校验数据
    imgs_length = len(imgs)
    assert len(imgs) == len(labels), \
          "length of train_imgs({}) should be the same as train_labels({})".format(
                  len(imgs), len(labels))
    # 定义数据集每个数据的序号, 根据序号读取数据
    index_list = list(range(imgs_length))
    # 读入数据时用到的batchsize
    BATCHSIZE = 100

注意以下这部分的代码,因为现在先训练“全连接网络模型”,所以要注释掉。

#img = np.reshape(imgs[i], [1, IMG_ROWS, IMG_COLS]).astype('float32')
#label = np.reshape(labels[i], [1]).astype('float32')

需要注释的原因:全连接神经网络输入的是28*28的像素值,而卷积模型直接在导入的图片上进行处理,所以后续使用卷积神经网络结构时不用注释这两行代码。

(3)区别两种模型结构

①全连接神经网络结构
在这里插入图片描述

# 定义多层全连接神经网络
class MNIST(paddle.nn.Layer):
    def __init__(self):
        super(MNIST, self).__init__()
        # 定义两层全连接隐含层,输出维度是10,当前设定隐含节点数为10,可根据任务调整
        self.fc1 = Linear(in_features=784, out_features=10)
        self.fc2 = Linear(in_features=10, out_features=10)
        # 定义一层全连接输出层,输出维度是1
        self.fc3 = Linear(in_features=10, out_features=1)
    
    # 定义网络的前向计算,隐含层激活函数为sigmoid,输出层不使用激活函数
    def forward(self, inputs):
        # inputs = paddle.reshape(inputs, [inputs.shape[0], 784])
        
        outputs1 = self.fc1(inputs)
        outputs1 = F.sigmoid(outputs1)
        outputs2 = self.fc2(outputs1)
        outputs2 = F.sigmoid(outputs2)
        outputs_final = self.fc3(outputs2)
        return outputs_final

②卷积神经网络结构
在这里插入图片描述

 # 定义卷积层,输出特征通道out_channels设置为20,卷积核的大小kernel_size为5,卷积步长stride=1,padding=2
         self.conv1 = Conv2D(in_channels=1, out_channels=20, kernel_size=5, stride=1, padding=2)
         # 定义池化层,池化核的大小kernel_size为2,池化步长为2
         self.max_pool1 = MaxPool2D(kernel_size=2, stride=2)
         # 定义卷积层,输出特征通道out_channels设置为20,卷积核的大小kernel_size为5,卷积步长stride=1,padding=2
         self.conv2 = Conv2D(in_channels=20, out_channels=20, kernel_size=5, stride=1, padding=2)
         # 定义池化层,池化核的大小kernel_size为2,池化步长为2
         self.max_pool2 = MaxPool2D(kernel_size=2, stride=2)
         # 定义一层全连接层,输出维度是1
         self.fc = Linear(in_features=980, out_features=1)
         
    # 定义网络前向计算过程,卷积后紧接着使用池化层,最后使用全连接层计算最终输出
    # 卷积层激活函数使用Relu,全连接层不使用激活函数
     def forward(self, inputs):
         x = self.conv1(inputs)
         x = F.relu(x)
         x = self.max_pool1(x)
         x = self.conv2(x)
         x = F.relu(x)
         x = self.max_pool2(x)
         x = paddle.reshape(x, [x.shape[0], -1])
         x = self.fc(x)
         return x

(4)激活函数
Sigmoid是早期神经网络模型中常见的非线性变换函数,通过如下代码,绘制出Sigmoid的函数曲线。

def sigmoid(x):
    # 直接返回sigmoid函数
    return 1. / (1. + np.exp(-x))
 
# param:起点,终点,间距
x = np.arange(-8, 8, 0.2)
y = sigmoid(x)
plt.plot(x, y)
plt.show()

在这里插入图片描述
(5)训练模型
(这里不附完整代码了,直接展示运行结果。想学习完整代码可以点进文章开头的链接亲自动手运行一下项目)
①全连接神经网络运行效果
在这里插入图片描述
在这里插入图片描述
直观图:
在这里插入图片描述

在这里插入图片描述
直观图:
在这里插入图片描述
(6)输出Loss值进行对比
通过(5)的结果对比可知,卷积神经网络的训练时间要远大于全连接神经网络,但卷积神经网络的损失值下降更快,且最终的损失值更小。

2. 微调超参数,比较运行时间和效果

以卷积神经网络结构为例:
①将训练批次由200调整为150
在这里插入图片描述
运行结果:
在这里插入图片描述
每个批次训练数量减少后,运行时间略微减少,但损失率有所升高。
直观图:
在这里插入图片描述
②将学习率由0.01调整为0.05
在这里插入图片描述
运行结果:
在这里插入图片描述
将学习率改为0.05后,运行时间基本没变,但损失率大大增加,可见该学习率较为低效。
直观图:
在这里插入图片描述

四、实验小结

关于超参数的认识:
超参数通常分为三类:网格参数、优化参数、正则化参数

网格参数:网络中层与层之间的交互方式、卷积核数量、卷积核尺寸、网络层数和激活函数等。
优化参数:学习率、批样本数量、不同优化器以及损失函数
正则化:权重衰减系数、丢弃比率
调整这些参数主要是寻找最优解和正则化之间的关系。网格模型优化调整的目的为了找到全局最优解,而正则项又希望尽量拟合到最优。两者通常情况下,存在一定的对立,但是二者目标一致,即最小化期望风险。最优解用来增加模型复杂度,正则项用来约束模型复杂度。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Moonee_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值