深度学习—从入门到放弃(二)简单线性神经网络
1.基本结构
就像昨日说的,咱们构建深度学习网络一般适用于数据大,处理难度也大的任务,因而关于网络的结构需要有一个非常深入的了解。这儿以一个分类猫狗的线性神经网络分类器作为比如: 1.方针函数 幻想一下,假如是想要一个能够分类出猫和狗的网络,咱们的终究目的是什么?应该是使用最短的时刻,最好的办法来完成任务。具象的来说就是在崎岖的山上找一条最优的下山途径。在神经网络中就是指最大极限降低丢失函数的途径。
2.梯度下降
因为大多数学习算法的方针是最小化风险(也称为本钱或丢失)函数,因而优化通常是大多数机器学习算法的核心!梯度下降算法及其变体(例如随机梯度下降)是用于深度学习的最强大和最盛行的优化办法之一。
2.1梯度向量
2.2梯度下降算法
2.3核算图和反向传达
关于梯度下降算法的结构分析后咱们不难发现:随着变量和嵌套函数数量的增加,梯度的推导将变得十分困难(梯度向量的核算需要对函数微分),这违反了咱们设置梯度下降的初衷—不只没有找到最优参数还会加大核算担负。
这儿咱们以一个嵌套函数为例:
3.PyTorch 梯度下降
AutoGrad 是 PyTorch 的自动微分引擎。在Pytorch里梯度下降也是从前向传达开端的,当咱们声明变量和操作时,PyTorch 会跟踪一切指令,并在咱们调用.backward(),即反向传达时构建核算图。PyTorch 每次迭代或更改图时都会重建核算图。 总结来说Pytorch梯度下降分为以下几个步骤:
1.重置梯度 2.核算图前向传达 3.核算丢失函数 4.核算图反向传达,核算丢失函数相关于可学习参数(即权重)的梯度 5.梯度下降
# Reset all gradients to zero
sgd_optimizer.zero_grad()
# Forward pass (Compute the output of the model on the features (inputs))
prediction = wide_net(inputs)
# Compute the loss
loss = loss_function(prediction, targets)
print(f'Loss: {loss.item()}')
# Perform backpropagation to build the graph and compute the gradients
loss.backward()
# Optimizer takes a tiny step in the steepest direction (negative of gradient)
# and "updates" the weights and biases of the network
sgd_optimizer.step()
4.nn.Moudle
PyTorch 为咱们供给了现成的神经网络构建块,例如层(例如线性、循环等)、不同的激活和丢失函数等等,都打包在torch.nn模块中. 关于练习,咱们需要知道三点: 1.模型参数 模型参数是指模型的一切可学习参数,可经过调用.parameters()模型访问。 2.丢失函数 梯度下降的优化目标 3.优化器 PyTorch 为咱们供给了许多优化办法(不同版本的梯度下降)。优化器保存模型的当前状况,并经过调用该step()办法,将根据核算出的梯度更新参数
4.1 界说一个简单的神经网络
## A Wide neural network with a single hidden layer
class WideNet(nn.Module):
def __init__(self):
"""Initializing the WideNet"""
n_cells = 512
super().__init__()
self.layers = nn.Sequential(
nn.Linear(1, n_cells),
nn.Tanh(),
nn.Linear(n_cells, 1),
)
def forward(self, x):
"""Forward pass
Args:
x (torch.Tensor): 2D tensor of features
Returns:
torch.Tensor: model predictions
"""
return self.layers(x)
# Create a mse loss function
loss_function = nn.MSELoss()
# Stochstic Gradient Descent optimizer (you will learn about momentum soon)
lr = 0.003 # learning rate
#这儿使用了随机梯度下降中的momentum办法
sgd_optimizer = torch.optim.SGD(wide_net.parameters(), lr=lr, momentum=0.9)
网络结构为:
WideNet( (layers): Sequential( (0): Linear(in_features=1, out_features=512, bias=True) (1): Tanh() (2): Linear(in_features=512, out_features=1, bias=True) ) )
4.2 练习网络
def train(features, labels, model, loss_fun, optimizer, n_epochs):
"""Training function
Args:
features (torch.Tensor): features (input) with shape torch.Size([n_samples, 1])
labels (torch.Tensor): labels (targets) with shape torch.Size([n_samples, 1])
model (torch nn.Module): the neural network
loss_fun (function): loss function
optimizer(function): optimizer
n_epochs (int): number of training iterations
Returns:
list: record (evolution) of training losses
"""
loss_record = [] # keeping recods of loss
### 梯度下降
for i in range(n_epochs):
optimizer.zero_grad() # set gradients to 0
predictions = model(features) # Compute model prediction (output)
loss = loss_fun(predictions, labels) # Compute the loss
loss.backward() # Compute gradients (backward pass)
optimizer.step() # update parameters (optimizer takes a step)
loss_record.append(loss.item())
return loss_record
set_seed(seed=2021)
epochs = 1847 # Cauchy, Exercices d'analyse et de physique mathematique (1847)
losses = train(inputs, targets, wide_net, loss_function, sgd_optimizer, epochs)
with plt.xkcd():
ex3_plot(wide_net, inputs, targets, epochs, losses)
对应一开端深度学习网络的五大成分,咱们能够这么了解:
1.方针函数–MSE丢失 loss_function = nn.MSELoss() 2.学习规矩–随机梯度下降和momentum办法 sgd_optimizer = torch.optim.SGD(wide_net.parameters(), lr=lr, momentum=0.9) 3.网络结构–512个神经元,1个躲藏层,1个Tanh激活层 def init(self): n_cells = 512 super().init() self.layers = nn.Sequential( nn.Linear(1, n_cells), nn.Tanh(), nn.Linear(n_cells, 1), ) 4.初始化–随机 5.环境
5.超参数
5.1 网络深度
那么让咱们来看看深度在练习神经网络时带来的应战。幻想一个具有 50 个躲藏层且每层只有一个神经元的单输入单输出线性网络。网络的输出很简单核算:
5.2 学习率
学习率是大多数优化算法的常见超参数。咱们能够把学习率想成梯度下降进程中每一步的步长。
5.3 深度,学习率的相互影响
一般来说,深度越深的网络需要的是更小的学习率,能够幻想成它的处理进程更为复杂,因而也就更需要小心翼翼的走好每一步。而浅层神经网络则正好相反,它能够承受较大学习率带来的影响。