动手学深度学习

本期Datawhale组队学习呢,是学习李沐老师的动手学深度学习pytorch版本,希望自己能坚持学下去有所收获。

第二章

2.1数据操作

通常,我们需要做两件重要的事:(1)获取数据;(2)将数据读入计算机后对其进行处理。 如果没有某种方法来存储数据,那么获取数据是没有意义的。

首先,我们介绍维数组,也称为张量(tensor)。 使用过Python中NumPy计算包的读者会对本部分很熟悉。 无论使用哪个深度学习框架,它的张量类(在MXNet中为, 在PyTorch和TensorFlow中为)都与Numpy的类似。 但深度学习框架又比Numpy的多一些重要功能: 首先,GPU很好地支持加速计算,而NumPy仅支持CPU计算; 其次,张量类支持自动微分。这些功能使得张量类更适合深度学习。 如果没有特殊说明,本书中所说的张量均指的是张量类的实例。

简单来说,计算机处理的是数据,而张量表示一个由数值组成的数组,这个数组可能有多个维度。 具有一个轴的张量对应数学上的向量(vector); 具有两个轴的张量对应数学上的矩阵(matrix); 具有两个轴以上的张量没有特殊的数学名称。目前来看,张量的存在可以有效帮助计算机将一些复杂的问题变成数字,从而达到一个计算的目的。

这里主要介绍了torch几种函数:

arrang:生成从0开始的整数。

shape:可以通过张量的属性来访问张量(沿每个轴的长度)的形状

size:看这个张量有多大。

reshape:要想改变一个张量的形状而不改变元素数量和元素值,可以调用函数。 例如,可以把张量从形状为(12,)的行向量转换为形状为(3,4)的矩阵。 这个新的张量包含与转换前相同的值,但是它被看成一个3行4列的矩阵。 要重点说明一下,虽然张量的形状发生了改变,但其元素值并没有变。

同样,我们可以创建一个形状为的张量:(2,3,4),这里我是有疑问的,2代表三个维度,然后三行四列吗?这里大家可以参考一下啊

(20条消息) 张量的概念及基本运算_张量运算法则_ChihYuanTSENG的博客-CSDN博客

向量运算,这一块也没啥好说的,这一块要注意张量连接,把它们端对端地叠起来形成一个更大的张量。

上面比较有意思的就是张量的广播机制,在某些情况下,即使形状不同,我们仍然可以通过调用 广播机制(广播机制)来执行按元素操作。 这种机制的工作方式如下:

  1. 通过适当复制元素来扩展一个或两个数组,以便在转换之后,两个张量具有相同的形状;

  1. 对生成的数组执行按元素操作。

就比如上文,一个三行一列的张量经过运算后,变成三行二列。所以说,有的时候少打一个数字,可能让结果产生很大的变化。

这里还要注意一个点:运行一些操作可能会导致为新结果分配内存。 例如,如果我们用,我们将取消引用指向的张量,而是指向新分配的内存处的张量。Y = X + YY

这里为什么会产生两种相反的结果呢,第一个是产生了新内存,第二个则还啊是在原地址上进行操作。

2.2 数据预处理

为了能用深度学习来解决现实世界的问题,我们经常从预处理原始数据开始, 而不是从那些准备好的张量格式数据开始。 在Python中常用的数据分析工具中,我们通常使用pandas软件包。 像庞大的Python生态系统中的许多其他扩展包一样,pandas可以与张量兼容。

我们首先创建一个人工数据集,并存储在CSV(逗号分隔值)文件 ../data/house_tiny.csv中。 以其他格式存储的数据也可以通过类似的方式进行处理。 下面我们将数据集按行写入CSV文件中。

这里有一个小问题,就是需要删除掉一个点才能运行,否则会报错的。

要从创建的CSV文件中加载原始数据集,我们导入pandas包并调用read_csv函数。该数据集有四行三列。其中每行描述了房间数量(“NumRooms”)、巷子类型(“Alley”)和房屋价格(“Price”)。

“NaN”项代表缺失值。 为了处理缺失的数据,典型的方法包括插值法删除法, 其中插值法用一个替代值弥补缺失值,而删除法则直接忽略缺失值。 在这里,我们将考虑插值法。

这里呢我们看到有一些缺失值的出现,这里呢,主要用插值法,把这些缺失值转变成可以处理的数据。

对于inputs中的类别值或离散值,我们将“NaN”视为一个类别。 由于“巷子类型”(“Alley”)列只接受两种类型的类别值“Pave”和“NaN”, pandas可以自动将此列转换为两列“Alley_Pave”和“Alley_nan”。 巷子类型为“Pave”的行会将“Alley_Pave”的值设置为1,“Alley_nan”的值设置为0。 缺少巷子类型的行会将“Alley_Pave”和“Alley_nan”分别设置为0和1。

现在inputs和outputs中的所有条目都是数值类型,它们可以转换为张量格式。

2.3线性代数

这一部分关于标量和向量的解释和我们线性代数讲的相同,不再多余赘述,代码展示一下啊。

加减乘除转置都是类似的。

我们主要说一下张量,张量本质上就是数值,涵括我们上文提到的标量和向量。就像向量是标量的推广,矩阵是向量的推广一样,我们可以构建具有更多轴的数据结构。 张量(本小节中的"张量"指代数对象)是描述具有任意数量轴的维数组的通用方法。 例如,向量是一阶张量,矩阵是二阶张量。

在机器学习,特别是复杂问题处理,比如说图像识别涉及到好几个特征维度是就需要张量加入。沐神解释过,这个张量类似于统计学家的概念,随着时代发展引申到了机器学习上来了而已。我们把它当作多维数组来看就好了。

张量的运算和向量相似。

这里说一下,clone和copy的区别,前者拷贝地址可以认为B是A的一个副本,两者有深层次的练习,copy只是数值相同而已。

默认情况下,调用求和函数会沿所有的轴降低张量的维度,使它变为一个标量。 我们还可以指定张量沿哪一个轴来通过求和降低维度。 以矩阵为例,为了通过求和所有行的元素来降维(轴0),可以在调用函数时指定。 由于输入矩阵沿0轴降维以生成输出向量,因此输入轴0的维数在输出形状中消失。

这里理解起来有些抽象,通过代码展示一下。简单来说,安装哪一维求和(axis),哪一维就会变为0,启示是维度变化,比如五行三列的矩阵,axis=0,变为4的一个列向量,但是这里张量是不区分行列的。所以这里有一个降维的影响在里面。

但是,有时在调用函数来计算总和或均值时保持轴数不变会很有用。例如,由于在对每行进行求和后仍保持两个轴,我们可以通过广播将除以。sum_AAsum_A。

2.4微积分

在深度学习中,我们"训练"模型,不断更新它们,使它们在看到越来越多的数据时变得越来越好。 通常情况下,变得更好意味着最小化一个损失函数(loss function), 即一个衡量"模型有多糟糕"这个问题的分数。 最终,我们真正关心的是生成一个模型,它能够在从未见过的数据上表现良好。 但"训练"模型只能将模型与我们实际能看到的数据相拟合。 因此,我们可以将拟合模型的任务分解为两个关键问题:

  • 优化(optimization):用模型拟合观测数据的过程;

  • 泛化(generalization):数学原理和实践者的智慧,能够指导我们生成出有效性超出用于训练的数据集本身的模型。、

这里需要大家掌握一些常见的函数的求导法则,还有链式法则、梯度等等。

矩阵微分建议大家用到哪个直接去查公式。

下面是一些例子。

深度学习框架通过自动计算导数,即自动微分(auto differentiation)来加快求导。 实际中,根据设计好的模型,系统会构建一个计算图(computational graph), 来跟踪计算是哪些数据通过哪些操作组合起来产生输出。 自动微分使系统能够随后反向传播梯度。 这里,反向传播(backpropagate)意味着跟踪整个计算图,填充关于每个参数的偏导数。

这里可以调用backward函数求导数,还有grad函数求微分

深度学习框架可以自动计算导数:我们首先将梯度附加到想要对其计算偏导数的变量上,然后记录目标值的计算,执行它的反向传播函数,并访问得到的梯度。

第三章

3.1线性回归

线性回归(linear regression)可以追溯到19世纪初, 它在回归的各种标准工具中最简单而且最流行。 线性回归基于几个简单的假设: 首先,假设自变量和因变量之间的关系是线性的, 即因变量可以表示为自变量中元素的加权和,这里通常允许包含观测值的一些噪声; 其次,我们假设任何噪声都比较正常,如噪声遵循正态分布。基本形式如下:

对于连续的值的预测我们叫做回归,离散值的预测叫分类,线性回归算法是回归算法最基础的算法。

这里我们主要介绍机器学习的常用模型之一:线性模型的学习。众所周知,机器学习主要分为三个步骤:模型、策略、算法。我们根据具体问题确定假设空间,然后根据评价标准,选取最优模型的策略(此时通常会产生一个损失函数),然后我们通过算法模型求解损失函数,确定最优化模型。本次我们主要从线性模型展开学习。

这里我们再着重介绍几个概念:

损失函数(loss function)能够量化目标的实际值与预测值之间的差距。 通常我们会选择非负数作为损失,且数值越小表示损失越小,完美预测时的损失为0。 回归问题中最常用的损失函数是平方误差函数。

梯度下降gradient descent)的方法, 这种方法几乎可以优化所有深度学习模型。 它通过不断地在损失函数递减的方向上更新参数来降低误差。

梯度下降最简单的用法是计算损失函数(数据集中所有样本的损失均值) 关于模型参数的导数(在这里也可以称为梯度)。 但实际中的执行可能会非常慢:因为在每一次更新参数之前,我们必须遍历整个数据集。 因此,我们通常会在每次需要计算更新的时候随机抽取一小批样本, 这种变体叫做小批量随机梯度下降(minibatch stochastic gradient descent)。

在每次迭代中,我们首先随机抽样一个小批量样本, 它是由固定数量的训练样本组成的。 然后,我们计算小批量的平均损失关于模型参数的导数(也可以称为梯度)。 最后,我们将梯度乘以一个预先确定的正数β,并从当前参数的值中减掉。

调参(hyperparameter tuning)是选择超参数的过程。 超参数通常是我们根据训练迭代结果来调整的, 而训练迭代结果是在独立的验证数据集(validation dataset)上评估得到的。

需要注意的是,即使我们的函数确实是线性的且无噪声,这些估计值也不会使损失函数真正地达到最小值。 因为算法会使得损失向最小值缓慢收敛,但却不能在有限的步数内非常精确地达到最小值。

总的来说,线性回归就是一个数学模型,通过不同的权重和偏置来预测我们不同的结果,其中去求解合适偏置和权重的方法有梯度下降和海塞公式,这个我前面笔记有所介绍,这里不展开叙述。

3.2线性回归的从零开始

这里一块主要是代码实现,建议大家动手操作,这里我们截屏演示。

读取数据集:

接下来,我们必须定义模型,将模型的输入和参数同模型的输出关联起来。 回想一下,要计算线性模型的输出, 我们只需计算输入特征和模型权重的矩阵-向量乘法后加上偏置。

这里损失函数我们使用的是均方误差,

每一步中,使用从数据集中随机抽取的一个小批量,然后根据参数计算损失的梯度。 接下来,朝着减少损失的方向更新我们的参数。 下面的函数实现小批量随机梯度下降更新。 该函数接受模型参数集合、学习速率和批量大小作为输入。每 一步更新的大小由学习速率决定。 因为我们计算的损失是一个批量样本的总和,所以我们用批量大小() 来规范化步长,这样步长大小就不会取决于我们对批量大小的选择。lrbatch_size。

现在我们已经准备好了模型训练所有需要的要素,可以实现主要的训练过程部分了。 理解这段代码至关重要,因为从事深度学习后, 相同的训练过程几乎一遍又一遍地出现。 在每次迭代中,我们读取一小批量训练样本,并通过我们的模型来获得一组预测。 计算完损失后,我们开始反向传播,存储每个参数的梯度。 最后,我们调用优化算法来更新模型参数。

结果如下:

这里可以看出我们经过三遍学习后错误率已经很低了。但是,当我们学习率降低后会发生什么呢?

可以看出我们的错误率很高,所以学习率不能太大也不能太小要适中。

3.3线性的简单实现

在过去的几年里,出于对深度学习强烈的兴趣, 许多公司、学者和业余爱好者开发了各种成熟的开源框架。 这些框架可以自动化基于梯度的学习算法中重复性的工作。我们只运用了: (1)通过张量来进行数据存储和线性代数; (2)通过自动微分来计算梯度。 实际上,由于数据迭代器、损失函数、优化器和神经网络层很常用, 现代深度学习库也为我们实现了这些组件。这里我们就不再进行演示了。

3.4softmax回归

回归可以用于预测多少的问题。 比如预测房屋被售出价格,或者棒球队可能获得的胜场数,又或者患者住院的天数。

事实上,我们也对分类问题感兴趣:不是问"多少",而是问"哪一个":

  • 某个电子邮件是否属于垃圾邮件文件夹?

  • 某个用户可能注册或不注册订阅服务?

  • 某个图像描绘的是驴、狗、猫、还是鸡?

  • 某人接下来最有可能看哪部电影?

通常,机器学习实践者用分类这个词来描述两个有微妙差别的问题: 1. 我们只对样本的"硬性"类别感兴趣,即属于哪个类别; 2. 我们希望得到"软性"类别,即得到属于每个类别的概率。 这两者的界限往往很模糊。其中的一个原因是:即使我们只关心硬类别,我们仍然使用软类别的模型。

本质是是一个分类问题。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值