NNDL作业四

目录

习题4-2 试设计一个前馈神经网络来解决XOR问题,要求该前馈神经网络具有两个隐藏神经元和一个输出神经元,并使用ReLU作为激活函数。

习题4-3 试举例说明“死亡ReLU问题”,并提出解决办法。

习题4-7 为什么神经网络模型的结构化风险函数中不对偏置b进行正则化。

习题4-8 为什么用反向传播算法进行参数学习时要采用随机参数初始化的方法而不是直接令W=0,b=0?

习题4-9 梯度消失问题是否可以通过增加学习率来缓解?


习题4-2 试设计一个前馈神经网络来解决XOR问题,要求该前馈神经网络具有两个隐藏神经元和一个输出神经元,并使用ReLU作为激活函数。

前馈神经网络是一种最简单的神经网络,各神经元分层排列。每个神经元只与前一层的神经元相连。接收前一层的输出,并输出给下一层.各层之间没有反馈。是目前应用最广泛、发展最迅速的人工神经网络之一。

XOR问题

异或是对两个运算元的一种逻辑分析类型,当两两数值相同时为否,而数值不同时为真。异或的真值表见表1-1所示:

 

XOR输入为2个神经元,输出为一个神经元,此题要求隐藏神经元为2个,故只要两层全连接层即可

数据集:输入为两位二进制,共四种情况,输出为一个二进制表示的数,要么为0,要么为1
网络模型:用pytorch搭建两层全连接层神经网络
训练:计算网络输出,计算损失函数,反向传播,参数更新
求权重和偏置

代码实现

import torch.nn as nn


# 异或门模块由两个全连接层构成
class XORModule(nn.Module):
    def __init__(self):
        super(XORModule, self).__init__()
        self.fc1 = nn.Linear(2, 2)
        self.fc2 = nn.Linear(2, 1)
        self.relu = nn.ReLU()

    def forward(self, x):
        x = x.view(-1, 2)
        x = self.relu((self.fc1(x)))
        x = self.fc2(x)
        return x

import torch
import torch.nn as nn
from XORModule import XORModule
import torch.optim as optim

# 输入和输出数据
input_x = torch.Tensor([[0, 0], [0, 1], [1, 0], [1, 1]])
input_x1 = input_x.float()
real_y = torch.Tensor([[0], [1], [1], [0]])
real_y1 = real_y.float()
# 设置损失函数和参数优化函数
net = XORModule()
loss_function = nn.MSELoss(reduction='mean')  # 用交叉熵损失函数会出现维度错误
optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)  # 用Adam优化参数选不好会出现计算值超出0-1的范围

# 进行训练
for epoch in range(10000):
    out_y = net(input_x1)
    loss = loss_function(out_y, real_y1)  # 计算损失函数
    # print('啦啦啦')
    optimizer.zero_grad()  # 对梯度清零,避免造成累加
    loss.backward()  # 反向传播
    optimizer.step()  # 参数更新


# 打印计算的权值和偏置
print('w1 = ', net.fc1.weight.detach().numpy())
print('b1 = ', net.fc1.bias.detach().numpy())
print('w2 = ', net.fc2.weight.detach().numpy())
print('b2 = ', net.fc2.bias.detach().numpy())

input_test = input_x1
out_test = net(input_test)
print('input_x', input_test.detach().numpy())
print('out_y', out_test.detach().numpy())

运行结果

 参考

设计前馈神经网络解决XOR问题_幸运星啦啦啦的博客-CSDN博客

习题4-3 试举例说明“死亡ReLU问题”,并提出解决办法。

但是relu也有自身的缺陷,当学习率过大时会出现某些神经元永久死亡的现象,导致网络后期无法正常更新

原因分析:

 

上式是神经网络权重更新的公式,其中η表示学习率,Δw表示通过求导得到的当前参数的梯度(一般为正值)当学习率过大时,会导致 ηΔw 这一项很大,当 ηΔw 大于w时,更新后的w’就会变为负值;

当权重参数变为负值时,输入网络的正值会和权重相乘后也会变为负值,负值通过relu后就会输出0;如果w在后期有机会被更新为正值也不会出现大问题,但是当relu函数输出值为0时,relu的导数也为0,因此会导致后边Δw一直为0,进而导致w一直不会被更新,因此会导致这个神经元永久性死亡(一直输出0)

解决办法:

1.减小学习率

2.使用PReLU、LeakyRelu等激活函数代替 Relu

参考 

https://blog.csdn.net/lch551218/article/details/118860970

习题4-7 为什么神经网络模型的结构化风险函数中不对偏置b进行正则化。

在神经网络模型的结构化风险函数中加入正则化项,可以避免过拟合,对于偏置b bb进行正则化对于防止过拟合没有什么影响。

对于神经网络正则化,一般只对每一层仿射变换的weights进行正则化惩罚,而不对偏置bias进行正则化。

相比于weight,bias训练准确需要的数据要更少。每个weight指定了两个变量之间的关系。weights训练准确需要在很多种情况下的同时观察两个变量。每个bias只控制一个变量。这意味着不对bias正则化,没有引入很多方差(variance)。同时,对bias进行正则化容易引起欠拟合。

习题4-8 为什么用反向传播算法进行参数学习时要采用随机参数初始化的方法而不是直接令W=0,b=0?

任何优化算法都需要一些初始的参数。到目前为止我们都是初始所有参数为 0,这样的初始方法对于逻辑回归来说是可行的,但是对于神经网络来说是不可行的。如果我们令所有的初始参数都为 0,这将意味着我们第二层的所有激活单元都会有相同的值。同理,如果我们初始所有的参数都为一个非 0 的数,结果也是一样的。

习题4-9 梯度消失问题是否可以通过增加学习率来缓解?

在某些神经网络中,通过隐藏层从后向前看,梯度会变的越来越小。这也意味着,前面层的学习会显著慢于后面层的学习。这就是梯度消失问题。

然而当学习率变大时,很容易使得参数跳过最优值点,然后梯度方向改变,导致参数优化时无法收敛。

有三种方法应对梯度消失问题:

  1. 合理的初始化权重值。初始化权重,使每个神经元尽可能不要取极大或极小值,以躲开梯度消失的区域。
  2. 使用relu代替sigmoid和tanh作为激活函数。
  3. 使用其他结构的RNNs,比如长短时记忆网络(LTSM)和Gated Recurrent Unit(GRU),这是最流行的做法。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值