试设计一个前馈神经网络来解决XOR问题,要求该前馈神经网络具有两个隐藏神经元和一个输出神经元,并使用ReLU作为激活函数。
XOR就是逻辑运算中的异或问题,异或是对两个运算元的一种逻辑分析类型,当两两数值相同时为否,而数值不同时为真。下面是异或运算表:
输入 | 输出 | |
A | B |
A XOR |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
代码:
import torch
from torch.nn.init import constant_, normal_
import torch.nn as nn
import torch.optim as optim
import numpy as np
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
# 输入和输出数据
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() # 用交叉熵损失函数会出现维度错误
optimizer = optim.SGD(net.parameters(), lr=0.01) # 用Adam优化参数选不好会出现计算值超出0-1的范围
# 进行训练
for epoch in range(1000):
out_y = net(input_x1)
loss = loss_function(out_y, real_y1) # 计算损失函数
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:\n', input_test.detach().numpy())
print('out_y:\n', np.around(out_test.detach().numpy()))
结果:
试举例说明“死亡ReLU问题”,并提出解决方法。
ReLU激活函数可以一定程度上改善梯度消失问题,但是ReLU函数在某些情况下容易出现死亡 ReLU问题,使得网络难以训练。这是由于当<0x<0时,ReLU函数的输出恒为0。在训练过程中,如果参数在一次不恰当的更新后,某个ReLU神经元在所有训练数据上都不能被激活(即输出为0),那么这个神经元自身参数的梯度永远都会是0,在以后的训练过程中永远都不能被激活。
解决方法:
将激活函数更换为Leaky Relu、ELU等Relu变种。
为什么在神经网络模型的结构化风险函数中不对偏置进行正则化?
正则化主要是为了防止过拟合,而过拟合一般表现为模型对于输入的微小改变产生了输出的较大差异,这主要是由于有些参数w过大的关系,通过对||w||进行惩罚,可以缓解这种问题。而如果对||b||进行惩罚,其实是没有作用的,因为在对输出结果的贡献中,参数b对于输入的改变是不敏感的,不管输入改变是大还是小,参数b的贡献就只是加个偏置而已。
或者说,模型对于输入的微小改变产生了输出的较大差异,这是因为模型的“曲率”太大,而模型的曲率是由w决定的, b不贡献曲率(对输入进行求导,b 是直接约掉的)。
为什么在用反向传播算法进行参数学习时要采用随机参数初始化的方式而不是直接令 w = 0 , b = 0?
反向传播算法主要由两个环节(激励传播、权重更新)反复循环迭代,直到网络的对输入的响应达到预定的目标范围为止。
如果参数都设为0,在第一遍前向计算的过程中所有的隐藏层神经元的激活值都相同。在反向传播时,所有权重更新也都相同,这样会导致隐藏层神经元没有区分性。这种现象称为对称权重现象。
梯度消失问题是否可以通过增加学习率来缓解?
梯度更新公式:
不行。梯度消失问题是由于激活函数为类似于sigmoid与tanh,其值太大或太小时导数都趋于0;并且在深层神经网络中,误差反向传播时,传播到前几层时梯度信息也会很小。增大学习率只能在一定程度上减缓梯度消失这一问题,但是增大学习率带来的缺陷会比梯度消失问题更加严重,学习率变大时,很容易使得参数跳过最优值点,然后梯度方向改变,导致参数优化时无法收敛。
具体解决方案请移步梯度消失与梯度爆炸解决方法
没听懂第一题咋改,,,,静等宿舍大佬写完教懂我,懂了后更新。
为什么一般不对偏置b进行正则化
梯度消失与梯度爆炸解决方法
胖头鱼