粉丝51获赞320
下面我们计算张亮的相关计算内容。我们首先是比较大小, 我们生成两个张亮, aa 为十,十, b 为十点一。如果比较两个数是否接近,我们可以使用它取 all close 函数, 而 close 函数可以通过 r t o l 和 a t o l 两个参数。如我们使用不同的参数,针对 a 和 b 两个数可以分别判断为不接近和接近, 因为 r t o l 和 a t l 可以定义比较两个数是否接近时的 的度量长度。可以发现十和十点一在不同的参数条件下会给出是否接近的不同结果。 如果 e q n a 等于处,那么缺失值将会判断为接近。计算两个元素是否相等,可以使用 touch e q touch q 函数。如我们针对张亮 a, 张亮 b 和张亮 c, 我们比较 a 和 b, 可以发现其是相等的, a 和 c 其也是相等的。而判断两两个张亮是否具有相同的尺寸 和元素,则可以踏取点 eq 函数,如 a 和 b 且是相等的, b 级不仅尺寸一样,而且每个元素也是一样的, 而踏举已扣 a 和 c 可以发现他们的元素是以相等的,但是他们的尺寸不相等,所以说输出为 fails。 足元数比较是否大于等于可以使用 touch g e 函数。 如果比较大于,可以使用 touch g t 函数,小于等于可以使用 touch l e 函数。 小于可以使用 touch l t 函数。比较不等于可以使用 touch 点 n 一函数。 判断是否为缺失值,可以使用 touch is n a 函数。下面我们介绍张亮的基本运算。 张亮的基本运算方式一种为足元素之间的运算,如加减乘除、四折运算、次方平方根对数数据裁减等。 另一种为矩阵之间的预算,如矩阵的相乘、矩阵的转制计算,矩阵的计等。我们先介绍竹元素呃之间的预算,如竹元素相乘, 直接使用乘法即可逐元素删除,使用除号即可写 a 和 b。 这里我们要求 a 和 b 的形状是一样的。 竹元素相加和竹元素相减及竹元素整除可以使用两个除化符号即可获取整除的内容。请输出结果如下, 而 me 四方可以使用 touch 点 power 函数,也可以使用 a 两个乘法符号来表示。 me 四命运算,指数运算可以使用 touch a s p 函数。对数运算可以使用 touch log 函数。 平方跟预算也可以使用 touch 点 square 函数。 touch 点 a square 则表示进行平方 方根运算后并计算其倒数数据的裁剪。可以有,如 touch 点 climp max a 四 表示我们的矩阵中只保留最大值为四的元素,如果元素的曲子大于四,则将其转化为四,而 climb mean 函数 a 三则表示在 张亮 a 中,我们最小值保留为三,而小于三的值均设置为三。 我们也可以指定我们的最大值和最小值。使用 touch 点 climp a 二点五四表示我们将小于二点五的元素设置为二点五,大于四的元素设置为四。 矩阵的转制可以使用 touch 点 t 函数,如我们的 a 是一个两行三列的矩阵,将其转制后可得到一个三行两列的矩阵。在矩阵运算中,矩阵相乘 要求矩阵 a 的函数要等于 c 的列数,可以使用 a 点 menu c 表示矩阵 a 乘以矩阵 c。 注意这里矩阵的乘法是线性代数中所学习使用的矩阵乘法。 我们生成两个张量, a 和 b, 分别为 a 二乘二乘三,即三围的张量。其进行张量运算时, a 和 b 进行相乘后,我们可以发现 其得到一个二乘二乘二的张量。其中第一个维度中的第一个元数是一个二乘二的张量,其得到的结果是 a 中的第零个元素和 b 中的第零个元素中的相乘。 我们通过以 q 函数可以发现矩阵相从只计算最后两个维度的乘法。 矩阵的逆可以使用 i, n, v, r, s, e 函数,如我们生成水激素张亮 c, 并使用踏起点 i, n, v, r, s, c 来计算矩阵的逆 d 矩阵的逆乘。以矩阵它,其结果会为单位矩阵,我们使用它的点 m m 将矩阵 c 和矩阵 d 进行矩阵相乘,可得到一个单位矩阵。 单位矩阵对角线元素为一,其余元素为零。非对角线元素是一个非常接近于零的元素,它取点 trace 可以计算矩阵的计,矩阵的计即为对角线元素的和。 下面介绍统计相关的相关计算,如获取张亮中的均值标准差、最大值、最小值等以及他们的位置。我们生成一个张亮, a 是一个一维的张亮, 然后我们获取其最大值及最大值的位置。我们可以使用 a 点 max 获取其最大值,最大值的位置为 a 点 a, r, g max 即获取最大值的位置。最小值可以使用 a 点 main 获取其最小值,而最小值的位置 可以使用 a 点 aig main 获取其位置。针对我们将张亮 a 转化为一个二维的三乘四的张量,三乘四的二维张量,我们输出的 b 内容如,我们的张量啊 b 是一个三行四列的矩阵, 我们可以使用必点 max, d, i, m 等于一格值获取每行的最大值, 即每一行的最大值,并且输出可以使用 a, r, g 点 max, d, m 等于获取其每行的最大值的位置, 获取必点命 d, m 等于零,可以获取且每列的最小值,并 并且使用必点 a, r, g, main d, m 等于零获取每列最小值的位置。当量的排序可以使用 touch 点 salt a 函数将分别输出从小到大的排序的结果,并且和相应的元素在元素在 其位置在原始张亮中的位置所引。嗯,第一个输出为排序后的,第二个为其在原始位置中的所引。 踏取点 solt a 指定参数 descending 等于处表示按降序排列 出色。第一个结果为其降序排列后的张亮,第二个则是且锁印。我们也可以分别获取 获取其排序后的张亮和张亮的所以,嗯, touch sort b, 因为 b 排序后,我们分别输出其排序后的内容为 sort 为如下,而排序后的,所以 如下。而也可以使用它去点 a, r, g shot 直接只获得排序后的缩影, 即缩影如下, touch top k 或 a 获取张亮前几大的数值,如, touch top a 四四,我们获取 a 中前四个大的数值,并且会输出其在全是张亮中的缩影。 我们也可以使用 d m 来指定其纬度。我们获取前二大的值, 并且其获取其位置的缩影,并且指定维度 d, m。 在第零尾,我们输出的结果如下, 以输出的结果中输出了每列中的前两个大的值,它取点 k, t, h volume 值可以找到张亮中 d, k 小的值。 由 touch a touch, 我们找到 a 中第三小的指和位置,其为二十三,位置为在第四个。 我们也可以指定 d, i, m 来指定其所引的纬度。我们找到了输出的结果如下, 我们也可以指定 keep d m 等于处参数表示输出时保持其原始的形状。我们输出了一个三行的元素 touch 点面值计算君子,并且可以使用 d m 指定题计算的维度。 keep i m 来表示速度的结果是否为保持原始形状。 解,每一行的君子如下,解必中每一列的君子如下, touch 点 sum 则是求和。 touch 点 sum 则是求和者每一行的和和。 b 中每一列的和应该如下, touch 点 see u m, s, m 则是计算累加和输出结果如下所示,它取点 media 则是计算中位数,它取点 p, r, o, d 则是计算 累加的成绩。其中每行的累加成绩如下,每列的累加成绩如下,踏举点 cumprod 指示计算累加的成绩。踏举点 c 的表示计算标准差。
视频呢,我将通过实现一个简单的歌词生成 ai, 带大家快速了解深度学习的基本流程,以及拍 touch 这款必备的深度学习框架。首先我们要知道,深度学习或者说神经网络的本质其实是一个数学问题。 我们可以通过训练让一个神经网络学习输入到输出之间的数据映射关系。例如,当神经网络看到这张图片时,他应当知道输出一条狗。 在拍拓器中,构建神经网络的核心数据结构是一个叫做 tensor 的东西,它和我们之前讲到的 number 数组非常类似。不过 tensor 的运算可以被放在 gpu 上执行, 利用 gpu 的并行运算来加速整个计算过程。在吞色之上呢,我们可以构建各种复杂的数学模型,拍 torch 也同时提供了梯度的自动计算。 那为什么需要梯度这个东西呢?梯度你可以简单理解成导数在高维度上的推广。这是因为对于神经网络的训练,或者说一般的最优化问题,大家都会用到一个核心算法梯度下降, 而拍 touch 将偏导数的计算链式、法则这些细节全部都隐藏在了框架中,因此我们可以更加关注与解决实际问题,而不是这些繁琐的计算细节。除了这些基本的计算功能以外,拍 touch 对神经网络还有各种模块化的封装, 比常见的卷基层、线形层、 pulling pying, 各种激活函数、 c, n, r, n, transformer 模型等等等等。以上呢,是对拍拓去的一个非常粗略的介绍。拍拓去单装还是比较容易的,我们可以在这里选择对应的操作系统扩大版本 的康大其实不是必须的。最后复制下面的命令到控制台安装即可。 训练的第一步呢,是准备我们需要的原始数据。数据级通常很容易被我们忽视,但是深度学习中相当重要的一环。有时候即使你的模型再好,但是训练的数据很差,最后也很难得到一个好的结果。这里我使用的呢,是这个中文歌词与辽阔。 在下载的原始数据中,我们可以看到很多非中文歌曲。有些歌词中的格式不工整,有些歌词的前面包含了不需要的信息。因此我们需要对这些原始数据做一些预处理,并将数据转换成我们需要的格式。 这里呢,我写了一个很简单的脚本,过滤掉不需要的歌词,去除多余的文字,并以斜杠来分隔歌词的每一句每一行呢是一首 首歌的歌词,最后存放在一个纯文本中。接下来呢,我们可以利用拍 touch 提供的 data set 和 data loader 来读取这个歌词文件。这两个类封装了基本的数据操作,比如切分训练数据,随机打乱数据,或者对数据进行简单变换等等。 这样我们就不用自己去造轮子了。我们可以通过继承 data 类来定义我们的歌词数据集。接下来,我们可以在一列弹数中加载之前的这个歌词文件,并将所有的文字转化成一个个缩影。 这里我们定义两个 dict, 用来保存缩影到文字,以及文字到缩影的映射。接下来我们需要实现两个函数,第一个函数 lens。 我们需要返回样本的总数。这里我们将所有的歌词文本拆分成一个个长度为四十八的序列, 所以样本总数等于文字的总数除以序列长度四十八,这里为什么减一?我们马上讲到第二个函数 get them, 我们可以根据指定的下标返回对应的文字序列。 这里返回的数据呢,可以被分成两部分,一部分代表网络的输入,另部分代表网络的输出。输入和输出刚好相差一个字,因为输出的文字刚好是对下一个字的预测。 定完毕之后,我们对刚刚代码进行一下简单测试。这里我们可以创建一个数据级对象,然后根据下标随便获取其中的一个样本。 可以看到这里返回的一个整数序列长度为四十八,其中的每个数字代表一个文字的缩影。我们当然也可以根据之前创建的映射将他们再还原成一个个字符。这部检查 打灯确实很有必要的,不然一步错,步步错。在定义了 data set 之后呢,我们需要再创建一个 data loader 来访问其中的数据,主要是因为 data loader 允许我们随机打乱数据或者按批次读取数据。 但这里我还进一步将数据分成了两部分,一部分用来做训练,另一部分用来做测试。原因我们在之后训练的时候讲到。 接下来呢,我们来定义我们用到的这个神经网络结构。在拍拖器中,我们可以通过继承 n n 中的猫九雷来定一个神经网络。这里最关键的是这个 forward 弹数, 他定义了我们网络从输入到输出的整个计算过程,比如数据会经过哪些层,层与层之间有应当如何连接等等。大家在定义模型的时候有一点非常 重要,不管我们要解决的问题有多么复杂,最好都先从构建一个最基本的模型开始,这样会大大降低训练和调试的难度。并且我们在增加模型复杂度之后,可以以这个最简单的模型做参照,确保复杂的模型是否真的表现的更好。 其实对于文本生成问题,使用当下最流行的 transformer 架构应该是更好的选择。不过这里呢,我们先用一个更加简单基本的 rnn 模型来做演示。 首先,我们会将这里输入的文字经过一个 embedding 层转换成一个像量,因为高维的像量能够更好地表示不同文字间的语意关联。接着我们将这个像量传入一个 l、 s, t、 m 单元, 最后通过一个线性层转换成输出的文字。和所有的分类问题一样,这里的文字是使用弯号的像量来 编码的。另外, lstm 单元同时有个隐藏状态的输入和一个隐藏状态的输出。正是因为有这个隐藏状态,才使得我们的神经网络具有记忆的能力,因为我们不希望深沉的歌词前言不搭后语,我们需要让魔性记住文字前后的关系。 如果大家对这里的 inbeding 或者 lstm 不是那么熟悉,也没有关系,大家可以先将重心放在数据的流向输入还有输出上。 比如这里你输入一个字,网络会帮你预测下一个字,然后我们将输出的文字连带隐藏的状态再次传递给神经网络,这样循环往复下去,就得到一整串的句子。 接下来我们来讲一下模型的训练。在训练的过程中,我们会每次抽取数据的一小部分,我们称之为一个 batch, 然后我们会一个 batch 接着一个 batch 的训练。当所有的数据都被训练过一遍之后,我们称之为一个 epoch。 通常我们也会对模型训练若干个 epoch, 让他更好地去拟合训练数据, 我们可以在循环中实现整个训练的过程。对于每一个 app, 我们会一个 batch 接着一个 batch 的训练。这里这项代码呢,单纯代表将训练数据上传至 gpu, 这一步呢是必要的, 因为我们使用 gpu 来加速训练的过程。接下来我们将数据传入之前创建的模型,让模型预测一个输出, 然后我们会去计算这个输出与标准答案之间的差异。这里我们会用到经常听到的损失函数 last function。 但对于不同的问题,我们会用到不同的损失函数。比如对于纯数 数值类型的输出,像温度,房价,这个 los 可以简单是输出与标准答案的绝对值或者是平方差。而对于我们这种情况,由于我们输出的是弯号编码的文字,因此我们会用到交叉箱 cross entry。 但大家可以简单的将这个 los 理解为输出与标准答案之间的差异。通常我们希望这个 los 越小越好,这样代表预测的结果与标准答案更接近。 而我们训练神经网络的目标呢,就是通过缓慢调节网络中的各种权重来降低这个 los。 用到的算法就是我们之前讲到的梯度下降。关于梯度的计算,我们可以轻松的通过调用一句 backward 完成。 然后我们可以调用 optimizer 的 step 函数,通过计算得到的梯度自动修改网络的权重。 这里第一行的 zero grad 也非常重要,他会在计算之前先将梯度清零,避免我们得到一个累加的梯度值。刚刚我们提到的 optimizer 是优化器,它可以通过计算得到的梯度自动更新网络的权重。 adam 和 sgd 是两个非常常用的优化器, 可以看到这里我使用的呢是 adam。 另外优化器还有一个额外的参数,学习速率,他会影响每次权重变化的大小。学习率越大,神经网络权重的变化量就越大。 但学习率绝不是越大越好,过大的学习率会让 los 无法收敛,甚至可能出现随着训练还增大的情况。学习率设置的过小会降低训练的速度,甚至可能让你的神经网络学不到任何东西。当然也有人尝试使用动态的学习率, 比如随着训练的推进逐渐降低学习率。关于学习率和优化器的选择又是一个很宽泛的话题,这里我们就不讲该讨论了。另外,在训练的过程中,我们可以将 los 打印出来,以方便我们跟踪模型的训练进度。 这里我们还可以用到 tensor board 这个库,我们可以调用 at scaler 来绘制像 loss 精确度这样标量的数据。虽然这一步不是必须的,但是图表呈现的信息往往比数字要直观很多。 除了训练之外呢,通常我们还会加入一个模型评估的环节。还记得我们在视频的开头将数据分成了训练和测试两部分吗?通常我们会预留少量的数据做评估,这部分数据并不会拿来做训练。评估的代码和训练非常类似,除了我们不会计算梯度来 更新网络的权重,我们同样会输出一个 los, 然后观察这个 los 下降的情况。因为单纯训练 los 的降低并不能代表模型表现的很好,模型也有可能过度拟合了我们的训练数据。 也就是说,我们的模型对于训练数据表现的很好,但是对于从来没有见过的数据却表现的很差。为了避免这种情况呢,我们会同时关注训练和评估时候的老师以及精确度这些指标。 在真正训练之前,我们最好对之前的代码做一个最最基本的验证。因为训练一个模型通常会花很多时间,有时候一两天都有可能。 如果等你训练完了以后才发现模型根本不工作,那么尼玛当场去世。那么具体我们应该怎么验证呢?比如我们可以修改这里的 data loader, 让我们暂时只使用第一个 batch 的数据,而且我们只用 batch 中的前两个样本来做训练。如果在这种情况下, lost 都不会降低。也就是说我们的模型都不能过度拟合,那我们的代码肯定哪里有问题,需要进行调试。 可以看到这里在训练了几十个 app 之后, los 一直在持续下降,并且预测的精确度呢,也达到了百分之百。到这一步呢,至少可以说我们的代码没有出现明显的错误。 接下来我们可以开始真正的训练。在训练的过程中,我们还可以每间隔一段时间让目前的模型生成一段输出。 这里的 january 弹数我们马上讲到,它会让模型生成一段歌词,并且每一句以深度学习。开始这一步主要是为了实时观测模型的预测结果。可以看到从一开 是几乎不能预测任何内容,到后面生成相对完整的句子。我们模型的输出随着训练有显著的提升。 这里我还做了一些改进,比如我们使用两层的 lstm 单元,并在输出之前额外增加了个线性层。与之前的模型相比较,新的模型进一步降低了 last, 并提高了预测的准确度。 虽然不是每一个修改都能保证模型效果的提升,不过模型优化确实需要我们不断的进行尝试。通常我们在 los 不再降低的时候就可以停止训练了。我这里手动将 apple 设置成了十五个。最后,等模型训练完成之后,我们让他来进行一段作词。 无法忘记你的美,可以让你不再流泪,深深的爱上你度过了多少个 春秋,学会珍惜,习惯了你的温柔,我的心在等待着你回来,是否我已经不再啰嗦,不再来私底里的等待。不错, 一个人的时候,键盘敲着时间的钟,三十年的时光连着我和你。 嗯,不错,狗屁不通。这里生成歌词的间内位弹数稍微有一点点长,不过总体来说,他会将我们规定的首字符先传递给神经网络,然后让神经网络自由创作,直到这一句结束,也就是遇到了斜杠分割符为止, 这里的 next word 函数会将当前字符传入神经网络,然后返回预测的下一个字,中间也会维护一个隐藏状态黑灯。这里的这几句呢,其实只是在对数据格式做变换而已。
大家好,欢迎来到日光滑的 pi touch 深度学习课程,这节课我们继续来看我们的入门实力,也就是说我们的收旧与年限与收入之间的一个模型。那通过上一节课的分析呢,我们知道我们要创建一个简单的一个先进回归模型,这个模型呢,实际上就是一个 w 乘以,用公式来表示的话,就是 w 乘以 x 加 b 啊, w 乘以输入再加 b, 那这个模型我们用 p to touch 应该如何去创建它呢?以及如何来创建我们的损失函数,或者叫成本函数,以及如何来优化。 那在代码中如何实现?那这节课呢?我们就在代码中为大家做演示,那么这里呢,大家因为我们首先进入我们的,嗯, book book 这里呢,我们导入 touch 导入盘 的尔斯导入囊牌以及 mate pro liber。 那这些库呢,在我们安装的过程中都已经安装过了,我们今天使用的版本呢是,嗯,叫做一点九点零这个版本,陶瓷点莴笋, 这与我们的教材呢是一个版本啊,同样版本,那我们的数据集在我们的当前末路线,当前末路线有一个啊,这个 sex 里面叫做 income essv, 我们读取这个数据集啊,那就是 data 等于 data, 等于 pd dairy 的 csv penders 呢,它有个 rate csv 方法来读取数据,这种 csv 文件是非常的方便的,所以我们经常使用它来读取,在它的当前目录下 des sex 里面啊, income income income e 点 c s v c s v, 那我们来读取这个数据,然后我们看一下这个数据长什么样子,比如说对特对嗨的, 这就是这个数据集,这个数据集呢,它包含了两列,分别是 education 以及 income, education 和 income 啊,这两列呢都是是类数据类型啊,都是这种数值性的,我们可以看一下, 查看数据机的一个整体情况,那这个数据机呢,包含了三十列,是一个非常非常小的数据机,那并且呢它包括这两列,三十行啊,三十行总号包含两个这种列,分别是 education 和 income, education 和 income, 那么 education income 都是 float 六十四类型, flow 类型啊,其实可以直接作为运算,如果是自付穿类型,那就需要我们去做这种,呃,做更改了,那我们通过我们可以绘图来查看 啊,这两列之间的一个这种特点,这两列之间的特点,绘图呢,我们使用迈特普罗里边的绘图,上面已经导入了,就是 plt 绘制一个这种三点图吧, plt 的 skat, skat, 然后我们的 x 轴是什么? x 轴就是 data 的 at ok, 神啊,比如说就是树胶年限, 外主呢,就是带刺点,叫做 income 收入,我们的收入,然后我们可以在这里面去添加我们的标签啊,添加标签,比如说,呃, x 列表, plt 点 啊, x 列表,添加横坐标标签,横坐标标签,那横坐标标签是什么?是 i do k 神,纵坐标呢?纵坐标就是 income 了,所以就是 plt 的 y liber viewer 选择是 income, 我这边是 income。 我们来看一下,这就是我们的一个绘图的一个结果啊,我们看到这横坐中坐标,横坐标,这是他们之间的一个绘图,那我们看到它是一种线性关系,所以我们想到了我们可以创建一个线性模型, 那在创建信息之前,魔性之前,我们要呃,在创建之前呢?我们要对这个输入做一个呃,做一个这种修改啊,做一个这种修改,那我们的数据输入是一个 输入的是 x, 是 data 的 x 是什么?我们的目标是什么?是 income, 所以我们的 x 是什么?输入的 x, 大写吧, x 等于什么呢?就等于 data 的 x, data 的艾特 k 神,迪特的艾特 k 神,吃一个 siris, 那么对于潘的词,如果大家了解的话,取一列就是 siris, 那这一列就 data 的艾特 k 神, 那么我们要从它里面取出囊牌数值来,我们可以使用这个 date x 涂囊牌方法,或者说要 values。 这个方法啊,真的话就是它一个 nome nda ray 树脂,取出来一个 nda ray 树脂, 那我们来,我们先不复制,先看一看吧,那这就是这么一个数值,但是大家发现他是在一个,而里面,那他并不是三十个纸,那我们希望把它转换成 三十个观测就是三十一,这么一个是 shape, 所以我把它给 shape 一下啊,所以把它给 shape, shape 什么样子呢?这是盘的是,这是囊派的方法了。负一一,那就说这里面负一代表自动计算,一呢,就是代表这个维度的长度,那也就是说在这里面我们 让他确定的维度就第二个维度必须为一,第一个维度你根据自己的个数进行计算,那这样的话就变成了 三十个维度。唯一的输入,真的话比较符合我们这种输入的特点,因为第一位是我们的这种个数位啊,三十个观测数据,那现在我们得到这个数据之后呢,还要对他进行一个这种 转换成我们的呃摊子啊,转换成我们的批约套尺的数据类型,那批约套尺为我们提供一个方法叫做 touchdown from nanpai, 这个方法就是从 ndairy 来创建数据 touchdonformnandpan, 那么这个方法顾名思义就是说从 ndiri 来创建一个特色,那就是 偷吃点芙蓉的摊子这个方法从 nda 来创建一个摊子,那现在我们得到这个摊子呢,就是一个得到数据就是一个摊子了,就是一个摊子。 那么这个方法我们在下一节课啊,在讲完这个例子之后,我们会单独为大家去介绍这个 pipod 的数据结构以及数据类型, 所以这里大家作为了解就可啊。作为了解,那我们使用这个陶瓷的粉漏芙蓉的囊派这个方法呢,就从 nda 瑞来创建了一个输入,从而创建成一个贪色的形式。贪色呢是 皮尔套制当中数最基本的数据结构,最基本的数据结构,下节课我们会讲到,然后呢,我们要对他进行一个转换成数据类型。皮尔套制当中啊,他的这种输入的数据类型,最常默认的数据类型是 float tens 是 flow tense, 那我们可以使用这个点太普这个方法,点太普点太普这个方法是贪色的方法,那么他是在转换数据类型,转换成什么呢?比如说转换成 touch 点 flow 的特色, touch the float, touch their float, 嗯,叫做 touched, 我们使用一个数据类型叫做 touch their float。 大写的 f 吧,大写的 f 啊,大写的 f, touch their float, float tens, 那么在这里面其实也可以,这是一种最常见的这种 float 类型,在陶瓷里面,为了方便我们使用,它定义叫做 float tense, 所以我们转换成这种类型, 那这就是我们目前的形式,我们可以看一下,现在呢,他已经被转换成 flow to tense 了,这就是我们创建的输入,我们把它叫做 x 啊 x, 那对于 y 的创建其实仍然是一样的方法,只不过他的列呢?是,嗯,他的列呢?是这个 income income income。 好的,那么现在我们就得到了咱们的输入和 target, 这就是我们的输入的特征,输出的 target, 那可以看一下他们的形状, shape, shape 这个属性呢?会返回一个贪色的形状,那么它是 touchsize 是什么样的形状?三十一,就是三十个长度为一的输入,是这个意思,那么对于 y 呢,其实也是这样子的, white size, 这是他的目标,嗯, whether why the ship 啊,歪的 shape, 歪的视频也是三十个目标,唯一的这种贪色。然后呢,我们就可以来创建模型啊,创建模型,创建模型呢,我们大家来了解一下啊,就是我们如何来在 撇脱齿当中创建模型,在撇脱齿当中创建模型呢?我们需要从继承自己去心定一个类,那么这个类呢?必须继承字,安安的没毛丢,必须必须 寄橙子,安安点 model 啊,安安的 model model 啊,蒙,安安的 model, 我们必须从这个安安的 model 这个负累去定一个新的累来创建这个模型。 所以我们可以看一下,假如说我们创建的这个模型的名字叫做,嗯, ei, 还就是 education income 一个模型嘛,那叫做 ei model, ei model, ei model, 那么这个类呢?他必须继承子这个负类,我们这就是我们 pa 套路当中去创建模型,他的一个要点就是你自己去定义这个类,并且这个类呢要继承子 i n m 六,那么在这里面我们需要去, 嗯,主要是定义两个方法,一个是初始化方法,那这是类拍散当中类必须你去做答案,你必须去定义这个初始化方法, 那么初始化方法里面我们要初始化我们的层和一些这种,呃,这种属性,还有变量属性等等。那在这里面首先继承复利的属性,那就是 super 啊 eimemodo 继承负累的属性,因为我们继承的这个负累吗?然后是 self, 对,刚刚 in it, 注意是双下巴线,刚刚双下巴线啊,然后我们初始画一个类,那初始画一个层,那我现在我们的模型是什么样子的?我们的模型就是一张一个公式, 一个线性公式,权重乘以输入再加 b, 那么在 ps 当中它对应的就是 line 层, line 层了,哎,那 line 层它就为我们初始化一个 w 和一个 b, 初始化 w 和 b, 对这个输入进行加权求和,那这就是 line 层所做的事情。 那经过这个例子,你应该了解勒念层,他干了什么,他就会自己去初始化一个权重,成立这个输入,再加上一个初始化的偏执, 这就是 line 层为我们所做的事情。所以我们可以直接去创建这个 line 层,那就是怎么创建?就是首先出示画一个 line 层,我们叫做 line 层,叫做 self de line 吧, self de line, 那么这个 line 层呢?它在 ai 模块下有玉,玉石 模块下模型,我们集成了雷捏层,那我们可以这样来,嗯嗯,点雷捏,这样的话就可以直接创建一个雷捏层,那么这个嗯嗯呢,实际上是从 touch 当中去导入的这个安安,我在这里忘了导入安安了,我们从 from touch in pot, 嗯嗯,那么嗯嗯,这个模块是套尺当中最重要的一个模块,他是套尺的一个高阶模块,那么套尺当中最常用的那些层,他都以及我们的这种损失函数,他都在这个嗯嗯模块下面,所以我们创建模型啊,等等吧,都是使用嗯嗯这个模块。 那我们使用安安的 line, 那么安的 line 呢?他有两个参数,最重要就是 in factors 和 auto factors, 就是输入的特, 特征的长度以及输出的特征长度。那么输入的特征长度是什么?输入就是我们的这种,你的这种收缴年限,收缴年限他的长度就是一了,实际上就是比如说三十或者二十这样的一,所以输入的特征长度是一,那么输出的特征长度呢? 输出就是你的这种收入也是一个,这种输长度为一的,这种指长度为一的输出,所以输出的特征长度也是一,所以这里面他的 in factors 是一啊。 in factors 是一,我们写的全一点,方便大家了解。然后 out factors, alt features 呢?也是一, alt features 也是一,这就是称的话,我们就创进了这个雷念层,那么他会根据我们的这个输入的维度和输出的维度去 自动的去初始化一些权重。比如说现在只有一个输入,那他就会初始化一个权重去成立这个输入,再加上一个偏执,这就是雷念层操作完成的事情 啊,他做完成的事情,好的,那么我我们初始画好了这个雷念层之后,然后我们要定义一个怎么去使用这个初始画雷念层呢?就是定义一个 forward 的方法,这也是我们在 forward 啊, forward 这个方法, 这是拍 pr touch 模型,它一个特点就是我们定义它的模型是要定义初始化方法以及定义 forward 的方法。那么我们初始画好了这个层,要在 forward 的方法中告诉他如何去在输入上去应用这些层啊,这就是如何进行前项传播,所以 这个他的第一个参数当然是赛尔夫了,第二个参数就是我们的输入,在这里我们记为 x, 或者说你写的清楚一些的话叫做 inputs 啊, inputs, 那么他对 inputs 怎么进行计算呢?进行怎么调用呢啊?他就会对这个音谱词进行一个输出,在这个赛夫的 line 层上进行个调用, 经过这个勒捏层,首先这个输出呢,会经过勒捏层得到一个输出,那这个输出呢,就是捞底词啊,我们叫做捞底词,捞底词得到这个输出,那然后呢我们将这个输出返回啊, return laudates, 这就是我们定义的整个的模型,那在这个我定义的过程中啊,最关键的两点就是说我们拥有三个点需要我们注意,第一是我们 定义这个累的时候要继承自恩爱的猫调,这是第一点。第二点呢,我们要在初始化方法当中,也就是刚刚阴历的这个方法当中啊,我们要啊去初始化我们要使用的层。第三点呢,我们要在第翻这个 for 的方法当中去定义它的一个前向传播,有时候我们这输入 要经过哪些层最后得到结果,这就是在 peace 当中去定一个模型的一个特点。那么我们定好这个类之后,他是一个类,我们还没有把它进行实力化,有得到我们的模型的话,我们要对他进行一个实力化,所以就是 model 等于什么?等于 e i'm model 对这个类进行实力化,他的初始化没需要参数啊,所以就是直接括号就可以了。真的话我们就得到这个摩托这个模型,我们看下这个模型,这个模型非常简单,就只有 一个雷念层,它输入是一个 faces, outfoot 也是一个 faces, 他有偏执把我斯定处,这是一个默认制。 那这样的话我们就可以进行啊下面的一个定义了,比如说定义优化函数,定义这种训练过程。那这些定义呢?我们下节课再讲,这节课我们主要讲一下这个模型的创建。好的,这节课讲到这里,谢谢大家,再见。
整理好数据之后,那接下来我们就需要去写训练的代码了,因为数据有了,模型结构也有了,那剩下的就是训练好,那我们训练的话,首先会想到什么?是不是会想到梯度下降啊? 是不是?那梯度下降的作用是不是找到啊?一组合适的 w 和 b, 让损失值越小越好, 是吧?那这个里面啊,我想一下, w 和 b 在我们的模型结构里面已经有了,那损失值是多少?我们不知道对不对?那这个损失值需要什么?是不是要需要确定一下我到底用什么样的一个损 是函数啊,对不对?那接下来我们就需要定一下我们的损失函数,那像我们这种分类的任务,一般都是用交叉三损失函数,所以呢,我们需要定义 n n 点 cross enter be loss, 那这个就是交叉三损失,那其实用起来很简单,括号,然后呢,这个函数会返回一个交叉三损失函数的对象,那么我们比如说就叫啊 loss function, 好,那这样子啊,这样一个损失函数的对象就有了。然后我们再想一下,我们在做 t 路下降的时候,我们是不是有这样一个概念啊?他就是在下山啊,对不对?瞎子 下山,那这个瞎子怎么下山?我们是不是也要设置一下对不对?那怎样下山啊?说白了就是要确定我在确定的时候要用什么样的一个 优化器,优化器就相当于是怎么下山,那拍拖子里面呢?给我们提供了非常非常多的优化器,但是一般来说,你如果没有什么特别的癖好的话,我们一般都是无脑又啊蛋 有这样一个优化器,那这样一个优化器怎么设置呢?是这样子, touch 点 optm, 这个是 optimizer 的缩写,点 a 弹, 那这么一堆啊,都是优化器,然后括号,那这个尔代函数里面啊,我们这期 码是要填两个参数的,第一个参数就是 pose, 这个就是参数,什么意思呢?就是你要设置一下,我到底要去优化哪些参数, 那我们这里肯定像优化我这个 model 里面的参数嘛,是不是?所以呢?就是 model 点 hunters 啊,就这么个意思。好,然后接下来还有一个概念,就是学习率,也就是 l r。 那学习率是什么意思呢?其实 非常简单啊,就是我瞎子下山的时候,我步子迈多大知道吧?我步子迈多大,所以呢?呃,这个 lr 你如果越大的话,那么他步子就迈的越大,子越小,那步子就迈的越小。那一般来说,我们蛋的一个 学习率一般都是零点零零一,大概这个样子啊,或者再加个零也可以。好,那这样子的话,我们就能实地画出一个优化器的对象啊,那比如说就这样 upt matter, 有了这两玩意之后呢?然后我们接下来就可以着手训练了。怎么训练呢?我们训练的话一般还有一个概念, 就是轮数,训练的轮数,也就是我到底要迭代多少次, 那这个东西一般就是你自己去定一个数字,比如说我要训练一百轮的话,那我们一般都是写个循环,循环一百次,那就是 four i enrage 一百,你如果 不是想训练两百轮,也就两百,那这个训练轮数有什么讲究吗?啊?有,一般来说的话,我训练轮数越多,那么我这个模型在训练级上的表现应该是会更好的, 知道了吧?啊,那这里呢,我就假设是一百轮啊,好,有了这个东西之后呢,那我们接下来就可以去开始训练了,首先第一步是干嘛呢?清空优化器的梯度, 这里的梯度啊,其实就是偏导的意思,那我们这样一个呃,弹里面啊,它是会存放我们历史的一些偏导值的啊,所以我们要把它清空,那清空的话是这个样子啊, optimizer 好点, zero right 这么一横调用就可以了。清空完梯度之后,然后接下来我们就可以开始走我们这个一个前向传播的一个流程了,也就是预测的流程。那预测的话 前面也写过了啊,就是这个样子嘛,对不对?那么我们啊这里一样插过来, 至于这个 data, 那就肯定不是这个 data 了,而是什么,而是我们训练级上的什么呢? feature 对不对?那就把它传过来,传过来之后呢,就会有这样一个预测结果,那这个就是所谓的前像传播的过程啊,或者叫预测的过程,也就是把数据扔进去啊,算出一个结果好,有了结果之后呢,我们接下来还要干嘛?还要去算一下我这个 预测结果和标准答案之间有多少误差,是不是?那这个就是算损失值,那损失值怎么算呢?我们一开始定义了这样一个损失函数对不对?然后呢就把它撸过来好,然后呢把这个预测结果扔进去,还有就是把我们的 标准答案扔进去,标准答案就是这个 train label 扔进来,扔进来之后呢,就会计算出损失值来,比如说这个损失值就叫 los, 对吧? 好,那有了这个 loss 之后,那接下来我们应该是要去做梯度下降,对不对?但是在神经网络里面,你要做梯度下降,那么你要干的事情先是做反向传播,对不对?所以呢, loss 叠 backward 啊,这个就是做反向传播,然后做完反向传播之后呢,然后接下来才是做梯度下降,那这个梯度下降啊,是在 optimizer 里面搞的啊,所以就是 optimizer 点 step, 那 step 走一步啊,就是那个瞎子下山往下面走一步啊,也就是梯度下降的意思。 到这为止呢,整个一个更新参数,也就是更新 w 的过程就已经完事了。但是我们一般来说都是希望去看一下我们每一轮训练完了,他的一个损失值,还有准确率是多少,对不对? 那么我们接下来来答应这些东西。首先啊,最简单的是这个损失值,那损失值的话,那就是 print loss, 但是呢,这个 loss 啊,它其实是一个 tensor, 所以你 你想拿它真正的值的话,那肯定是要 at, 懂了吧?好,然后呢,我们来运行试一下, 然后你发现报错了,是不是报错不要紧,我们来看一下啊,他说在做这一步的时候报错了,然后我们再往下看,这里有个报错,他说你输入的必须设置一个 tens, 但并不能是一个 number 对象。 那么想想啊,我们的输入是不是这个 train feature 啊?对不对?那这个 train feature 我们这边是通过这个 values 拿到的,它是一个安排的对象, 所以呢,我们得把它转成听式才能用,那么我们这里可以这个样子。呃,把它转一下是不是啊? 那就是 train feature 等于 torch 点 tensor train feature 对不对?这样一来就转掉了吧,然后呢,其他的也是一样画葫芦啊。嗯,那这里就是 label 啊,吹 level, 那这个是 test 啊,那这个就是 test, 然后这个的话也是 test, 好,搞过来。好,我们再来运行一下。 哎,他又报了一个错,他报什么呢?还是在这里啊?然后我们看一下他报什么错,他说,呃,我希望的数据是一个小数,但是你给我的是个什么?给我的是一个 long, 是个整数。那这个报错其实 词就是在说我这个 train feature 应该里面的数据是小数,所以我们这个东西还得转换一下 two 还记得吧,改它的 detail, 呃, toss 点 fox 对不对?那同样的,我测试级的理由。 好,我们再来运行一下。哎, 抛起来了是不是?而且有没有发现啊,我这个损失值随着迭代,随着训练,他是越来越小的吧, 是不是啊?越来越小,那就比较合理了,对不对?那说明这个模型里面的 w 和 b 是越来越好的, 对不对?好,那我们先停下来,这样一个 los, 也就是损失值能够打印出来了。那接下来还有一个东西就是准确率,对不对?那准确率怎么搞呢? 呃,我们首先啊,先分析一下这个 predict 出来是个什么,我们打个断点,然后调试好代码,断在这的时候呢,我们这个 predict 是个什么样的? 它是个什么样子的一个数据啊?那这个 shift 这里,它是三万三千六百行十列的一个数据, 对不对?然后我们点一个这个 view 看一下,那里面都是一个一个概率,对不对?那这就说明什么呢?其实 它是这个意思啊,这个 pdx 说白了,嗯,是一个矩阵,然后呢可能是什么零点九啊,零点零啊,零点一零, 零点零,然后零点零,然后零点零,然后零点零,零点零,零点零,假设这里有实力啊,然后呢?我有很多行,哎, 零零零零。嗯,我这里先把它注视起来。好,假设呢,这里有实力,然后呢有很多行啊,有很多行,有很多行, 假设有这么四行吧,我这里随便改点数字二,然后呢三一五, 呃,一六啊,当然这些数字可能改的不对啊,但是呢,表达的意思肯定是能表达的, 我们的 prediction 大概就是这个样子的一个数据,然后呢这一行代表第一条数据,它的那个图片里面的数字分别是零、一、二、三、四、五、六七八、九的概率是多少, 对不对?那这个零点九就说,呃,我认为第一张图片他是零的概率是百分之九十,认为是一的概率是百分之零,认为是二的概率是百分之十,是这个样子。 如果我们想要去算这个预测结果,他的一个准确率是多少,那么我们是不是应该在这里面,比如说这一行里面,这一行里面找最大的那个值是零点四,零点四所对 的下标,或者说也就是零,所以呢,他的预测结果应该是零啊。还有比如说这里这里面最大的是零点五嘛,是不是?那么他的预测结果应该是零一二三四五, 他预测书是数字五,这个呢也是零,那这个呢?就数字六,懂我意思了吧,我们应该拿到的是这种东西啊,那这个东西怎么拿呢?是不是可以用 acmex 去搞啊, 对不对?好,所以呢,这个结果啊,是这个样子, without 等于 torch 点 arc max, 然后呢,对它进行 arc max, 然后根据哪个轴来算最大值呢?那肯定是一号轴吧, 对不对?肯定是根据一号轴去搞吧,我是一行一行的去看吧。所以呢,我们再来把这个 result 打一下啊,我这里就不要运行,你看是不是 不是那个概率了吧,而是真正的零到九的数字了吧。好,那有了这个数字之后,那这个准确率就好上了 tort me 就可以了吧,是不是啊,那这个训练级上的 a c c, 也就是它的准确率的话,就等于 tort 点命,然后呢,里面是什么 exot 和我们的这个 train label 是不是相等的,对不对?然后之前也说过, 把这里我要转成啊小数,对不对?不然他会报错啊 plus。 然后呢,我们把这个 a, c, c 打一下,走,你看,准确率出来了吧,而且是越来越高的, 那应该就是比较正确的了。好,那损失值和准确率都能算出来之后呢,那么我们一起打印是吧,搞得好看一点。嗯,那就 print。 呃,格式化一下吧,比如说 train loss 训练级上的损失值, 呃,它等于这个,然后呢,再来一个训练级上的 a, c, c, 好吧,等于这个,然后点呢?点 for mat, 呃 呃,这个就是 los 点 it, 然后这个是 train a, c c 点 it 是吧?啊?运行一下啊,走,你看出来了吧,而且我这个损失值越来越小,他这个准确率越来越高啊,这是非常合理的一个情形是不是? 嗯,准确率越来越高,越来越高,越来越高。好,这是训练级上的表现啊,我们一般来说除了看训练级之外,还要看测试级上的表现,对不对?那测试级上怎么搞呢?其实啊,都差不多,差不太多, 一个模子搞出来怎么样子呢?我们可以接下去写一下啊。呃,这里的话,我们一样的 清空一下这个优化器的梯度,然后呢,一样的,我们要对测试级的那个数据进行预测,同样也会出一个 please, 然后呢,同样的把这个结果算一下, 是吧?算完结果之后呢,然后就会有它的一个准确率,对不对?那这个准确率呢?呃,这边就是 test 的 label, 是吧?那这个就是 test a c c, 然后呢,我要算那个损失值的话,也可以这样子把它抄过来。 然后呢,这个 train 这里改成 test 啊,然后呢,这两步啊,就不需要做了, 对吧?因为这两步是用来更新那个模型里面的 wb 的,我测试的时候是不需要去更新的, 对不对啊?测试的时候是就不要去学习的,所以这里不用写,所以这两行代码不用考过来。然后呢,接下来我们再来打印一下他的这个测试级上的表现。 test, test, 然后呢,这里是 test。 好吧,然后呢,我们来看一下, 嗯,你看出来了吧? 是不是?而且他训练级和测试级上的表现基本上是差不多的,对不对啊?这个就比较合理了。 好,一百轮训练完毕之后呢,我们会发现啊,这个模型在训练级上的准确率大概是百分之九十二点六,在测试级上的准确率大概是百分之九十二点五,百分之九十二点四的样子。嗯,还是挺牛逼的吧。