Pytorch_study_Task_5:PyTorch实现L1,L2正则化以及Dropout
1.了解知道Dropout原理
- Dropout是一种在学习的过程中随机删除神经元的方法。训练时,随机选出隐藏层的神经元,然后将其删除。被删除的神经元不再进行信号的传递,如下图a所示。训练时,每传递一次数据,就会随机选择要删除的神经元。然后,测试时,虽然会传递所有的神经元信号,但是对于各个神经元的输出,要乘上训练时的删除比例后再输出。训练时如果进行恰当的计算的话,正向传播时单纯地传递数据就可以了(不用乘以删除比例)。
图1 Dropout的概念图:左边是一般的神经网络,右边是应用了Dropout的网络。Dropout通过随机选择并删除神经元,停止向前传递信号。
2.用代码实现正则化(L1、L2、Dropout)
假设有权重W = (w 1 , w 2 , … , w n )。
L1 正则化的表达是把所有神经层的所有权值做绝对值的和,即相当于
|w 1 | + |w 2 | + … + |w n |。
L2 正则化的表达是把所有神经层的所有权值做平方和,相当于
√ ̄( w 1 2 + w 2 2 + … + w n 2 )
正则化运用在求权重梯度的计算中,为之前的误差反向传播法的结果加上正则化项的导数。
举个例子,先建立两个神经层:
l1 = Layer(x, 13, 50, T.tanh)
l2 = Layer(l1.outputs, 50, 1, None)
再计算 cost:
- 没有正则化的表达式:
cost = T.mean(T.square(l2.outputs - y))
- 运用L1 正则化的表达式:
cost = T.mean(T.square(l2.outputs - y)) + 0.1 * (abs(l1.W).sum() + abs(l2.W).sum())
- 运用L2 正则化的表达式:
cost = T.mean(T.square(l2.outputs - y)) + 0.1 * ((l1.W ** 2).sum() + (l2.W ** 2).sum())
3.Dropout的numpy实现
class Dropout:
def __init__(self, dropout_ratio=0.5):
self.dropout_ratio = dropout_ratio
self.mask = None
def forward(self, x, train_flg=True):
if train_flg:
self.mask = np.random.rand(*x.shape) > self.dropout_ratio
return x * self.mask
else:
return x * (1.0 - self.dropout_ratio)
def backward(self, dout):
return dout * self.mask
4.PyTorch中实现dropout
- 建立数据:
import torch
torch.manual_seed(1) # reproducible
N_SAMPLES = 20
N_HIDDEN = 300
# training data
x = torch.unsqueeze(torch.linspace(-1, 1, N_SAMPLES), 1)
y = x + 0.3*torch.normal(torch.zeros(N_SAMPLES, 1), torch.ones(N_SAMPLES, 1))
# test data
test_x = torch.unsqueeze(torch.linspace(-1, 1, N_SAMPLES), 1)
test_y = test_x + 0.3*torch.normal(torch.zeros(N_SAMPLES, 1), torch.ones(N_SAMPLES, 1))
- 建立神经网络 :
net_dropped = torch.nn.Sequential(
torch.nn.Linear(1, N_HIDDEN),
torch.nn.Dropout(0.5), # drop 50% of the neuron
torch.nn.ReLU(),
torch.nn.Linear(N_HIDDEN, N_HIDDEN),
torch.nn.Dropout(0.5), # drop 50% of the neuron
torch.nn.ReLU(),
torch.nn.Linear(N_HIDDEN, 1),
)
- 训练网络:
optimizer_drop = torch.optim.Adam(net_dropped.parameters(), lr=0.01)
loss_func = torch.nn.MSELoss()
for t in range(500):
pred_drop = net_dropped(x)
loss_drop = loss_func(pred_drop, y)
optimizer_drop.zero_grad()
loss_drop.backward()
optimizer_drop.step()
注:
- 代码参考莫烦PYTHON:
https://morvanzhou.github.io/tutorials/machine-learning/theano/3-5-regularization/
https://morvanzhou.github.io/tutorials/machine-learning/torch/5-03-dropout/