深度学习---从入门到放弃简单线性神经网络(代码片段)

佩瑞 佩瑞     2022-12-22     153

关键词:

深度学习—从入门到放弃(二)简单线性神经网络

1.基本结构

就像昨天说的,我们构建深度学习网络一般适用于数据大,处理难度也大的任务,因此对于网络的结构需要有一个非常深入的了解。这里以一个分类猫狗的线性神经网络分类器作为例子:
1.目标函数
想象一下,如果是想要一个能够分类出猫和狗的网络,我们的最终目的是什么?应该是使用最短的时间,最好的方法来完成任务。具象的来说就是在崎岖的山上找一条最优的下山路径。在神经网络中就是指最大限度降低损失函数的路径。


2.学习规则
可以继续联想刚刚的下山路径,我们的目标函数是如何最优下山,而学习规则则是我们该如何下山,换言之也就是我们如何通过不断的学习和迭代获得最优路径,最优模型参数。
3.网络架构
什么是神经网络?就如同它的字面意思,是由一层层神经元构成的网络结构,因此我们如何设计神经元间的连接以及网络层数都会对结果产生影响。我们今天的大标题叫简单线性神经网络,也就是说层和层之间是以线性关系连接。
4.初始化
又回到我们的下山问题,下山的目标(目标函数)和如何下山(学习规则)都找到了,那么还有一个问题,我们该从哪里出发,而这就是初始化。起点决定成败,一个好的起点会让我们节省很多力气。
5.环境
既然是分类问题,那么肯定要给我们的网络一些实例去学习,但对于深度学习网络庞大数据量的需求,我们又该怎么办呢?如果我说有这么一个开放数据集,里面有成千上万的图片数据,且都是预处理好了的,是不是解决了一大难题!在猫狗分类的问题里我们选用了IMAGENET里的图片数据。
有了一个基本的认知之后我们再来引入一个简单线性神经网络,可以看到这个神经网络是多层结构的,每一层都有自己的权重w,而我们之前所说的“下山”便是找到损失函数最小的最优参数w,

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 个隐藏层且每层只有一个神经元的单输入单输出线性网络。网络的输出很容易计算:

如果所有权重的初始值为 w i = 2 wi=2 wi=2, y ( p ) = 2 50 ≈ 1.1256 × 1 0 15 y(p)=2^50≈1.1256×10^15 y(p)=2501.1256×1015,这时候的预测值趋近于无限大,此时这种情况称为梯度爆炸
如果所有权重的初始值为 w i = 0.5 wi=0.5 wi=0.5, y ( p ) = 0. 5 50 ≈ 8.88 × 1 0 − 16 y(p)=0.5^50≈8.88×10^-16 y(p)=0.5508.88×1016,这时候的预测值趋近于无限小,此时这种情况称为梯度消失
因此为了有效的避免这两种情况发生,我们需要了解深度对于网络训练带来的影响:

不难看出,浅层网络的学习是一个循序渐进的过程,而对于深层网络而言它的学习过程更像sigmoid函数,即通过一定时间的学习后突然掌握数据集的某些特征,这两种学习方式是截然不同的。

5.2 学习率

学习率是大多数优化算法的常见超参数。我们可以把学习率想成梯度下降过程中每一步的步长。

1.学习率过小
学习率过小将会导致损失函数收敛过慢,即梯度下降迈步太小,花费很长时间都不能走到损失函数最小的最优参数的位置

2.学习率过大
学习率过大会导致梯度下降时跳过损失函数最小值,造成损失函数的波动

上图为适宜学习率下的神经网络损失随训练时间的变化

5.3 深度,学习率的相互影响

一般来说,深度越深的网络需要的是更小的学习率,可以想象成它的处理过程更为复杂,因而也就更需要小心翼翼的走好每一步。而浅层神经网络则正好相反,它可以承受较大学习率带来的影响。

5.4 初始化


详见之前说到的梯度爆炸和梯度消失。

欢迎大家关注公众号奇趣多多一起交流!

深度学习—从入门到放弃(一)pytorch基础

深度学习---从入门到放弃pytorch基础(代码片段)

深度学习—从入门到放弃(一)pytorchTensor类似于numpy的array,pandas的dataframe;在pytorch里的数据结构是tensor,即张量tensor简单操作1.Flattenandreshape###Originalz:tensor([[0,1],[2,3],[4,5],[6,7],[8,9],[10,11]])Flatte 查看详情

深度学习:从入门到放弃

https://zhuanlan.zhihu.com/p/22976342 首发于深度学习:从入门到放弃写文章登录 FCN学习:SemanticSegmentation余俊1年前感谢@huangh12 @郑途 @麦田守望者对标签图像生成的研究和讨论,这几天研究了一下,补充如下。-------------------... 查看详情

[资源]深度学习从入门到放弃

Relationship:  MachineLearning---->DeepLearning                           ---->DeepReinforcementLearning[LearningRoadMap]              ReinforcementLearningPapers:  DeepLearningPapersReadin 查看详情

入门实战《深度学习技术图像处理入门》+《视觉slam十四讲从理论到实践》

...原理以及简单的实现。 学习理论后做实验,使用卷积神经网络进行端到端学习,构建深度卷积神经网络,使用循环神经网络改进模型,评估模型,测试模型。最关键的是可以将模型运用于实战之中,将深度学习模型导入到工... 查看详情

初识pytorch:从安装到入门,从入门到放弃(代码片段)

...置安装验证PyTorchPyTorch是Facebook团队于2017年1月发布的一个深度学习框架,虽然晚于TensorFlow,也没有TensorFlow火,但目前已经与TensorFlow奇虎相当。而且PyTorch采用了Python语言的接口,可以说它才是Python程序员最容易上... 查看详情

[补档][从入门到放弃]——网络流学习索引

前篇由于某篇博文已经长到我自己看不下去的地步,又不忍心删,所以就有了这篇索引,方便自己找,也方便来访的客人看嘛(真的会有人来看吗啊喂) 最长的博文2017-7-29大佬讲课笔记网络流——从入门到放弃没错,就是它... 查看详情

初识pytorch:从安装到入门,从入门到放弃(代码片段)

...友好的用户界面,支持以快速和灵活的方式构建动态神经网络。还允许在训练的过程中,快速更改代码而不妨碍其性能,支持动态图形等尖端AI模型的能力,是快速实验的理想选择。安装配置安装PyTorch时,需... 查看详情

深度学习入门2022最新版深度学习简介(代码片段)

...器学习是什么深度学习是什么机器学习和深度学习的区别神经网络机器学习实现二分类神经网络实现二分类TensorFlowPyTorch神经网络的原理张量张量最小值(补充)张量最大值(补充)前向传播损失计算反向传播梯度下降案例线性回归公... 查看详情

google深度学习笔记从线性分类器到深度神经网络

转载请注明作者:梦里风林Github工程地址:https://github.com/ahangchen/GDLnotes欢迎star,有问题可以到Issue区讨论官方教程地址视频/字幕下载LimitofLinearModel实际要调整的参数很多如果有N个Class,K个Label,需要调整的参... 查看详情

学习jvm是如何从入门到放弃的?

学习JVM的目的也很简单:能够知道JVM是什么,为我们干了什么,具体是怎么干的。能够理解到一些初学时不懂的东西在面试的时候有谈资能装逼  (图片来源:zhuanlan.zhihu.com/p/25511795,侵删)声明:全文默认指的是HotSpotVM一、... 查看详情

人工智能深度学习入门练习之(33)深度学习–自适应线性单元

深度学习–自适应线性单元如前所述,在20世纪50年代,感知器(Rosenblatt,1956,1958)成为第一个能根据每个类别的输入样本来学习权重的模型。约在同一时期,自适应线性单元(adaptivelinearelement,ADALINE)简单地返回函数f(x)本身的值来... 查看详情

深度学习入门篇,简单的实例讲明白图像分类。(代码片段)

深度学习和Python开始摘要使用Keras训练您的第一个简单神经网络不需要很多代码,但我们将开始缓慢,一步一步地进行,确保您了解如何在自己的自定义数据集中培训网络的过程。我们今天将涵盖的步骤包括:安... 查看详情

python深度学习入门-神经网络(代码片段)

深度学习入门-神经网络博主微信公众号(左)、Python+智能大数据+AI学习交流群(右):欢迎关注和加群,大家一起学习交流,共同进步!目录摘要1、从感知机到神经网络1.1 神经网络的例子1... 查看详情

《深度学习入门》——神经网络(代码片段)

感知机需要人工设定权重,而神经网络可以自动地从数据中学习到合适的权重参数。激活函数(activationfunction)——将输入信号的总和转换为输出信号。激活函数的作用在于决定如何激活输入信号的总和。阶跃函数—&md... 查看详情

春节学习之从入门到放弃学习~~~废材大学几年没学,从头开始系列02(代码片段)

...清楚了。。。于是今天来把前面链表的知识复习一下,要学习链表,就不得不讲一下前面的线性表线性表的定义:线性表是具有相同数据结构n(n>=0)个数据元素的有限序列。其中n为表长,当n=0时,该线性表是一个空表。线性... 查看详情

ai框架核心技术系列来啦!从入门到放弃!

...术】这个系列,主要是跟大家一起探讨和学习人工智能、深度学习的计算机系统设计,而整个系统是围绕着我在工作之余所积累、梳理、构建关于AI框架的一些核心技术内容。【AI框架核心技术】这个系列,主要是跟大家一起探... 查看详情

clickhouse从入门到放弃(代码片段)

...clickhouse做数据分析,我赶紧从docker上下载一个,学习学习。学习成本不大,会mysql就行。clickhouse下载分区基本使用下载下载clickhouse包dockerpullyandex/clickhouse-clientdockerpullyandex/clickhouse-server启动clickhouse-serv 查看详情

clickhouse从入门到放弃(代码片段)

...clickhouse做数据分析,我赶紧从docker上下载一个,学习学习。学习成本不大,会mysql就行。clickhouse下载分区基本使用下载下载clickhouse包dockerpullyandex/clickhouse-clientdockerpullyandex/clickhouse-server启动clickhouse-serv 查看详情