吴恩达深度学习笔记:神经网络的编程基础2.15-2.17

目录

  • 第一门课:神经网络和深度学习 (Neural Networks and Deep Learning)
    • 第二周:神经网络的编程基础 (Basics of Neural Network programming)
      • 2.15 Python 中的广播(Broadcasting in Python)
      • 2.16 关于 python _ numpy 向量的说明(A note on python or numpy vectors)
      • 2.17(选修)logistic 损失函数的解释(Explanation of logistic regression cost function)

第一门课:神经网络和深度学习 (Neural Networks and Deep Learning)

第二周:神经网络的编程基础 (Basics of Neural Network programming)

2.15 Python 中的广播(Broadcasting in Python)

这是一个不同食物(每 100g)中不同营养成分的卡路里含量表格,表格为 3 行 4 列,列表示不同的食物种类,从左至右依次为苹果,牛肉,鸡蛋,土豆。行表示不同的营养成分,从上到下依次为碳水化合物,蛋白质,脂肪。
在这里插入图片描述
那么,我们现在想要计算不同食物中不同营养成分中的卡路里百分比。

现在计算苹果中的碳水化合物卡路里百分比含量,首先计算苹果(100g)中三种营养成分卡路里总和 56+1.2+1.8 = 59,然后用 56/59 = 94.9%算出结果。

可以看出苹果中的卡路里大部分来自于碳水化合物,而牛肉则不同。
对于其他食物,计算方法类似。首先,按列求和,计算每种食物中(100g)三种营养成分总和,然后分别用不用营养成分的卡路里数量除以总和,计算百分比。那么,能否不使用 for 循环完成这样的一个计算过程呢?

假设上图的表格是一个 3 行 4 列的矩阵𝐴,记为 𝐴3×4,接下来我们要使用 Python 的numpy 库完成这样的计算。我们打算使用两行代码完成,第一行代码对每一列进行求和,第二行代码分别计算每种食物每种营养成分的百分比。

import numpy as np

A = np.array([[56.0,0.0,4.4,68.0],
             [1.2,104.0,52.0,8.0],
             [1.8,135.0,99.0,0.9]])
# print(A)
cal  =A.sum(axis=0)
# print(cal)
percentage=100*A/cal.reshape(1,4)
print(percentage)

下面再来解释一下 A.sum(axis = 0)中的参数 axis。axis 用来指明将要进行的运算是沿着哪个轴执行,在 numpy 中,0 轴是垂直的,也就是列,而 1 轴是水平的,也就是行。

而第二个 A/cal.reshape(1,4)指令则调用了 numpy 中的广播机制。这里使用 3 × 4的矩阵𝐴除以 1 × 4的矩阵𝑐𝑎𝑙。技术上来讲,其实并不需要再将矩阵𝑐𝑎𝑙 reshape(重塑)成1 × 4,因为矩阵𝑐𝑎𝑙本身已经是 1 × 4了。但是当我们写代码时不确定矩阵维度的时候,通常会对矩阵进行重塑来确保得到我们想要的列向量或行向量。重塑操作 reshape 是一个常量时间的操作,时间复杂度是𝑂(1),它的调用代价极低。

在 numpy 中,当一个 4 × 1的列向量与一个常数做加法时,实际上会将常数扩展为一个 4 × 1的列向量,然后两者做逐元素加法。结果就是右边的这个向量。这种广播机制对于行向量和列向量均可以使用。

再看下一个例子。

在这里插入图片描述
用一个 2 × 3的矩阵和一个 1 × 3 的矩阵相加,其泛化形式是 𝑚 × 𝑛 的矩阵和 1 × 𝑛的矩阵相加。在执行加法操作时,其实是将 1 × 𝑛 的矩阵复制成为 𝑚 × 𝑛 的矩阵,然后两者做逐元素加法得到结果。针对这个具体例子,相当于在矩阵的第一列加 100,第二列加 200,第三列加 300。这就是在前一张幻灯片中计算卡路里百分比的广播机制,只不过这里是除法操作(广播机制与执行的运算种类无关)。

广播机制的一般原则如下:
首先是 numpy 广播机制
如果两个数组的后缘维度的轴长度相符或其中一方的轴长度为 1,则认为它们是广播兼容的。广播会在缺失维度和轴长度为 1 的维度上进行。

总结一下 broadcasting,可以看看下面的图:

在这里插入图片描述
总结:广播机制,就是为了尽可能满足矩阵的加减乘除规范,当不满足时,通过复制行或列的值使其满足规则;

2.16 关于 python _ numpy 向量的说明(A note on python or numpy vectors)

本节主要讲 Python 中的 numpy 一维数组的特性,以及与行向量或列向量的区别。并介绍了老师在实际应用中的一些小技巧,去避免在 coding 中由于这些特性而导致的 bug。

Python 的特性允许你使用广播(broadcasting)功能,这是 Python 的 numpy 程序语言库中最灵活的地方。而我认为这是程序语言的优点,也是缺点。优点的原因在于它们创造出语言的表达性,Python 语言巨大的灵活性使得你仅仅通过一行代码就能做很多事情。但是这也是缺点,由于广播巨大的灵活性,有时候你对于广播的特点以及广播的工作原理这些细节不熟悉的话,你可能会产生很细微或者看起来很奇怪的 bug。例如,如果你将一个列向量添加到一个行向量中,你会以为它报出维度不匹配或类型错误之类的错误,但是实际上你会得到一个行向量和列向量的求和。

在 Python 的这些奇怪的影响之中,其实是有一个内在的逻辑关系的。但是如果对 Python不熟悉的话,我就曾经见过的一些学生非常生硬、非常艰难地去寻找 bug。所以我在这里想做的就是分享给你们一些技巧,这些技巧对我非常有用,它们能消除或者简化我的代码中所有看起来很奇怪的 bug。同时我也希望通过这些技巧,你也能更容易地写没有 bug 的 Python和 numpy 代码。

为了演示 Python-numpy 的一个容易被忽略的效果,特别是怎样在 Python-numpy 中构造向量,让我来做一个快速示范。首先设置𝑎 = 𝑛𝑝. 𝑟𝑎𝑛𝑑𝑜𝑚. 𝑟𝑎𝑛𝑑𝑛(5),这样会生成存储在数组 𝑎 中的 5 个高斯随机数变量。之后输出 𝑎,从屏幕上可以得知,此时 𝑎 的 shape(形状)是一个(5, )的结构。这在 Python 中被称作一个一维数组。它既不是一个行向量也不是一个列向量,这也导致它有一些不是很直观的效果。举个例子,如果我输出一个转置阵,最终结果它会和𝑎看起来一样,所以𝑎和𝑎的转置阵最终结果看起来一样。而如果我输出𝑎和𝑎的转置阵的内积,你可能会想:𝑎乘以𝑎的转置返回给你的可能会是一个矩阵。但是如果我这样做,你只会得到一个数。

import numpy as np

a = np.random.rand(5)
print(a.shape)
print(a)
print(np.dot(a,a.T))

结果如下:
(5,)
[0.25952355 0.63937714 0.92832645 0.21007159 0.68871566]
1.856404924677065

所以我建议当你编写神经网络时,不要在它的 shape 是(5, )还是(𝑛, )或者一维数组时使用数据结构。相反,如果你设置 𝑎 为(5,1),那么这就将置于 5 行 1 列向量中。在先前的操作里 𝑎 和 𝑎 的转置看起来一样,而现在这样的 𝑎 变成一个新的 𝑎 的转置,并且它是一个行向量。请注意一个细微的差别,在这种数据结构中,当我们输出 𝑎 的转置时有两对方括号,而之前只有一对方括号,所以这就是 1 行 5 列的矩阵和一维数组的差别。

import numpy as np

a = np.random.rand(5,1)
print(a.shape)
print(a)
print(np.dot(a,a.T))

(5, 1)
[[0.59478491]
[0.66576404]
[0.05868431]
[0.04864699]
[0.63411704]]
[[0.35376909 0.3959864 0.03490454 0.02893449 0.37716325]
[0.3959864 0.44324176 0.0390699 0.03238742 0.42217232]
[0.03490454 0.0390699 0.00344385 0.00285481 0.03721272]
[0.02893449 0.03238742 0.00285481 0.00236653 0.03084788]
[0.37716325 0.42217232 0.03721272 0.03084788 0.40210442]]

就我们刚才看到的,再进一步说明。首先我们刚刚运行的命令是这个 (𝑎 =𝑛𝑝. 𝑟𝑎𝑛𝑑𝑜𝑚. 𝑟𝑎𝑛𝑑𝑛(5)),而且它生成了一个数据结构 (𝑎. 𝑠ℎ𝑎𝑝𝑒),𝑎. 𝑠ℎ𝑎𝑝𝑒是(5, ),一个有趣的东西。这被称作 𝑎 的一维数组,同时这也是一个非常有趣的数据结构。它不像行向量和列向量那样表现的很一致,这也让它的一些影响不那么明显。所以我建议,当你在编程练习或者在执行逻辑回归和神经网络时,你不需要使用这些一维数组。

我写代码时还有一件经常做的事,那就是如果我不完全确定一个向量的维度(dimension),我经常会扔进一个断言语句(assertion statement)。像这样,去确保在这种情况下是一个(5,1)向量,或者说是一个列向量。这些断言语句实际上是要去执行的,并且它们也会有助于为你的代码提供信息。所以不论你要做什么,不要犹豫直接插入断言语句。如果你不小心以一维数组来执行,你也能够重新改变数组维数 𝑎 = 𝑟𝑒𝑠ℎ𝑎𝑝𝑒,表明一个(5,1)数组或者一个(1,5)数组,以致于它表现更像列向量或行向量。

我有时候看见学生因为一维数组不直观的影响,难以定位 bug 而告终。通过在原先的代码里清除一维数组,我的代码变得更加简洁。而且实际上就我在代码中表现的事情而言,我从来不使用一维数组。因此,要去简化你的代码,而且不要使用一维数组。总是使用 𝑛 × 1维矩阵(基本上是列向量),或者 1 × 𝑛 维矩阵(基本上是行向量),这样你可以减少很多assert 语句来节省核矩阵和数组的维数的时间。另外,为了确保你的矩阵或向量所需要的维数时,不要羞于 reshape 操作。

总之,我希望这些建议能帮助你解决一个 Python 中的 bug,从而使你更容易地完成练习。

2.17(选修)logistic 损失函数的解释(Explanation of logistic regression cost function)

在前面的视频中,我们已经分析了逻辑回归的损失函数表达式,在这节选修视频中,我将给出一个简洁的证明来说明逻辑回归的损失函数为什么是这种形式。

回想一下,在逻辑回归中,需要预测的结果 y ^ \hat{y} y^,可以表示为 y ^ = σ ( w T x + b ) \hat{y} = σ(w^Tx + b) y^=σ(wTx+b),𝜎是我们熟悉的𝑆型函数 σ ( z ) = σ ( w T x + b ) = 1 1 + e − z σ(z) = σ(w^Tx + b) =\frac{1}{1+e^{-z}} σ(z)=σ(wTx+b)=1+ez1。我们约定 y ^ = p ( y = 1 ∣ x ) \hat{y} = p(y = 1|x) y^=p(y=1∣x) ,即算法的输出 y ^ \hat{y} y^ 是给定训练样本 𝑥 条件下 𝑦 等于 1 的概率。

换句话说,如果y = 1,在给定训练样本 𝑥 条件下 y = y ^ y = \hat{y} y=y^
反过来说,如果y = 0,在给定训练样本𝑥条件下 ( y = 1 − y ^ y = 1 − \hat{y} y=1y^),
因此,如果 y ^ \hat{y} y^ 代表y = 1 的概率,那么 1 − y ^ 1-\hat{y} 1y^ 就是 y = 0的概率。

接下来,我们就来分析这两个条件概率公式。
在这里插入图片描述

这两个条件概率公式定义形式为 𝑝(𝑦|𝑥)并且代表了 𝑦 = 0 或者 𝑦 = 1 这两种情况,我们可以将这两个公式合并成一个公式。需要指出的是我们讨论的是二分类问题的损失函数,因此,𝑦的取值只能是 0 或者 1。上述的两个条件概率公式可以合并成如下公式:
接下来我会解释为什么可以合并成这种形式的表达式:( 1 − y ^ 1 − \hat{y} 1y^)的(1 − y)次方这行表达
p ( y ∣ x ) = y ^ y ( 1 − y ^ ) ( 1 − y ) p(y|x) =\hat{y}^y (1-\hat{y})^{(1-y)} p(yx)=y^y(1y^)(1y)
式包含了上面的两个条件概率公式,我来解释一下为什么。

在这里插入图片描述
第一种情况,假设 y = 1,由于y = 1,那么 ( y ^ ) y = y ^ (\hat{y})^y = \hat{y} (y^)y=y^,因为 y ^ \hat{y} y^的 1 次方等于 y ^ \hat{y} y^ 1 − ( 1 − y ^ ) ( 1 − y ) 1 −(1 − \hat{y})^{(1−y)} 1(1y^)(1y)的指数项(1 − y)等于 0,由于任何数的 0 次方都是 1, y ^ \hat{y} y^乘以 1 等于 y ^ \hat{y} y^。因此当𝑦 = 1时 p ( y ∣ x ) = y ^ p(y|x) = \hat{y} p(yx)=y^(图中绿色部分)。

第二种情况,当 y = 0 时 p(y|x) 等于多少呢? 假设y = 0, y ^ \hat{y} y^的𝑦次方就是 y ^ \hat{y} y^ 的 0 次方,任何数的 0 次方都等于 1,因此 p ( y ∣ x ) = 1 × ( 1 − y ^ ) ( 1 − y ) p(y|x) =1×(1 − \hat{y})^(1−y ) p(yx)=1×(1y^)(1y),前面假设 y = 0 因此(1 −𝑦)就等于 1,因此 p ( y ∣ x ) = 1 × ( 1 − y ^ ) p(y|x) =1×(1 − \hat{y}) p(yx)=1×(1y^)。因此在这里当y = 0时, p ( y ∣ x ) = 1 − y ^ p(y|x) = 1− \hat{y} p(yx)=1y^。这就是这个公式(第二个公式,图中紫色字体部分)的结果。

因此,刚才的推导表明 p ( y ∣ x ) = y ^ ( y ) ( 1 − y ^ ) ( 1 − y ) p(y|x) = \hat{y}^{(y)}(1 − \hat{y})^{(1−y)} p(yx)=y^(y)(1y^)(1y),就是 p(y|x) 的完整定义。由于 log 函数是严格单调递增的函数,最大化 log(p(y|x)) 等价于最大化 p(y|x) 并且地计算p(y|x) 的 log 对数,就是计算 l o g ( y ^ ( y ) ( 1 − y ^ ) ( 1 − y ) ) log(\hat{y}^{(y)}(1 −\hat{y})^{(1−y)}) log(y^(y)(1y^)(1y)) (其实就是将 p(y|x) 代入),通过对数函数化简为:
y l o g y ^ + ( 1 − y ) l o g ( 1 − y ^ ) ylog\hat{y} + (1-y)log(1-\hat{y}) ylogy^+(1y)log(1y^)

而这就是我们前面提到的损失函数的负数 ( − L ( y ^ , y ) ) (−L(\hat{y} , y)) (L(y^,y)),前面有一个负号的原因是当你训练学习算法时需要算法输出值的概率是最大的(以最大的概率预测这个值),然而在逻辑回归中我们需要最小化损失函数,因此最小化损失函数与最大化条件概率的对数log(p(y|x)) 关联起来了,因此这就是单个训练样本的损失函数表达式。

在这里插入图片描述
在 𝑚个训练样本的整个训练集中又该如何表示呢,让我们一起来探讨一下。让我们一起来探讨一下,整个训练集中标签的概率,更正式地来写一下。假设所有的训练样本服从同一分布且相互独立,也即独立同分布的,所有这些样本的联合概率就是每个样本概率的乘积:
在这里插入图片描述
如果你想做最大似然估计,需要寻找一组参数,使得给定样本的观测值概率最大,但令这个概率最大化等价于令其对数最大化,在等式两边取对数:
在这里插入图片描述
在统计学里面,有一个方法叫做最大似然估计,即求出一组参数,使这个式子取最大值,也就是说,使得这个式子取最大值,

∑ i = 1 m − L ( y ^ ( i ) , y ( i ) ) \sum_{i=1}^m−L(\hat{y}^{(i)}, y^{(i)}) i=1mL(y^(i),y(i)) ,可以将负号移到求和符号的外面, − ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) -\sum_{i=1}^mL(\hat{y}^{(i)}, y^{(i)}) i=1mL(y^(i),y(i)),这样我们就推导出了

前面给出的 logistic 回归的成本函数 J ( w , b ) = ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) J(w, b) =\sum_{i=1}^mL(\hat{y}^{(i)}, y^{(i)}) J(w,b)=i=1mL(y^(i),y(i))

在这里插入图片描述

由于训练模型时,目标是让成本函数最小化,所以我们不是直接用最大似然概率,要去掉这里的负号,最后为了方便,可以对成本函数进行适当的缩放,我们就在前面加一个额外的常数因子 1 m \frac{1}{m} m1,即:

J ( w , b ) = 1 m ∑ i = 1 m L ( y ^ ( i ) , y ( i ) ) J(w, b) =\frac{1}{m}\sum_{i=1}^mL(\hat{y}^{(i)}, y^{(i)}) J(w,b)=m1i=1mL(y^(i),y(i))

总结一下,为了最小化成本函数𝐽(𝑤, 𝑏),我们从 logistic 回归模型的最大似然估计的角度出发,假设训练集中的样本都是独立同分布的条件下。尽管这节课是选修性质的,但还是感谢观看本节视频。我希望通过本节课您能更好地明白逻辑回归的损失函数,为什么是那种形式,明白了损失函数的原理,希望您能继续完成课后的练习,前面课程的练习以及本周的测验,在课后的小测验和编程练习中,祝您好运。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/485782.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloud - 架构体系详解

Spring Cloud简介 Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。 Spring并没有重复制造…

我在京东做数据分析,一位京东数据分析师的工作日常

有人说:“种下一棵树最好的时间是十年前,其次是现在”。任何时候,我们都应该抓住机遇,说不定就是改变你现状的一个机会。 2020年,我在疫情得到控制后,面试入职京东大数据组,截止目前&#xff0…

【项目设计】基于MVC的负载均衡式的在线OJ

项目代码(可直接下载运行) 一、项目的相关背景 学习编程的小伙伴,大家对力扣、牛客或其他在线编程的网站一定都不陌生,这些编程网站除了提供了在线编程,还有其他的一些功能。我们这个项目只是做出能够在线编程的功能。…

浏览器工作原理与实践--渲染流程(上):HTML、CSS和JavaScript,是如何变成页面的

在上一篇文章中我们介绍了导航相关的流程,那导航被提交后又会怎么样呢?就进入了渲染阶段。这个阶段很重要,了解其相关流程能让你“看透”页面是如何工作的,有了这些知识,你可以解决一系列相关的问题,比如能…

机器人自动驾驶时间同步进阶

0. 简介 之前时间同步也写过一篇文章介绍机器人&自动驾驶中的时间同步。在最近的学习中发现一些额外需要阐述学习的内容,这里就再次写一些之前没写到的内容。 1. NTP NTP 是网络时间协议,用来同步网络中各计算机时间的协议,把计算机的…

京东商品详情API接口:一键获取商品信息的智能助手

京东商品详情API接口:一键获取商品信息的智能助手 请求示例,API接口接入Anzexi58 在数字化浪潮席卷而来的今天,数据已经渗透到各行各业,成为驱动商业发展的重要引擎。对于电商行业而言,快速、准确地获取商品信息对于…

【Hadoop大数据技术】——Hadoop高可用集群(学习笔记)

📖 前言:Hadoop设计之初,在架构设计和应用性能方面存在很多不如人意的地方,如HDFS和YARN集群的主节点只能有一个,如果主节点宕机无法使用,那么将导致HDFS或YARN集群无法使用,针对上述问题&#…

无人驾驶中的坐标转换

无人驾驶中的坐标转换 无人车上拥有各种各样的传感器,每个传感器的安装位置和角度又不尽相同。对于传感器的提供商,开始并不知道传感器会以什么角度,安装在什么位置,因此只能根据传感器自身建立坐标系。无人驾驶系统是一个多传感器…

知识图谱-图数据库-neo4j (1)踩坑记录

1、neo4j 安装 由于目前还是用的 jdk8;所以需要安装jdk8支持的neo4j 乌班图系统 # 安装指定社区版本 sudo apt-get install neo4j #不指定,安装最新版本 sudo apt-get install neo4j1:3.5.35 # 指定版本 jdk1.8的原因# 企业版本 sudo apt-get install neo4j-ent…

贝尔曼最优方程【BOE】

强化学习笔记 主要基于b站西湖大学赵世钰老师的【强化学习的数学原理】课程,个人觉得赵老师的课件深入浅出,很适合入门. 第一章 强化学习基本概念 第二章 贝尔曼方程 第三章 贝尔曼最优方程 文章目录 强化学习笔记一、最优策略二、贝尔曼最优方程(BOE)三…

【C++ 函数参数】指针类型和指针引用类型的区别

目录 0 引言1 参数是指针类型2 参数是指针的引用3 总结 🙋‍♂️ 作者:海码007📜 专栏:C专栏💥 标题:【C 函数参数】指针类型和指针引用类型的区别❣️ 寄语:人生的意义或许可以发挥自己全部的潜…

对外开放接口的Appkey和Secret应该如何设置?

文章目录 appkey和Secret 分别是什么?App keyapp secret Appkey和Secret 因遵循什么原则?代码示例随机生成有效的appkey校验Appkey调用效果 小结 appkey和Secret 分别是什么? App key App key简称API接口验证序号,是用于验证API…

C++ - 类和对象(上)

目录 一、类的定义 二、访问限定符 public(公有) protected(保护) private(私有) 三、类声明和定义分离 四、外部变量和成员变量的区别与注意 五、类的实例化 六、类对象的模型 七、类的this指针…

linux系统编程 socket part2

报式套接字 1.动态报式套接字2.报式套接字的广播3.报式套接字的多播4.UDP协议分析4.1.丢包原因4.2.停等式流量控制 接linux系统编程 socket part1 1.动态报式套接字 在之前的例子上,发送的结构体中的名字由定长改变长。可以用变长结构体。 变长结构体是由gcc扩展的…

主流电商平台淘宝/1688/京东电商数据实时采集监测|电商API接口接入

电商大数据平台基于网络主流电商平台淘宝/1688/京东电商数据进行搭建,全面监测了包含淘宝、京东、苏宁、美团、大众点评等共计100余个主流电商交易平台,并凭借多年的电子商务数据分析挖掘经验积累形成的电商数据清洗体系和挖掘模型,能高效完成…

ARIMA

一.数据平稳性与差分法 1.平稳性: 2.差分法: 错开时间点,使得数据可以平稳 原数据➡️一阶差分➡️二阶差分: 二、arima 1.自回归模型 2.移动平均模型 关注的是误差项的累积 3.arma p d(几阶差分) q自己指定 4.总…

分手我见得多了,怎么软件也玩分手?

网管小贾 / sysadm.cc 今年年初,我们就注意到了一件忒奇怪的事儿。 我们公司的同事小孙,以前人长得高高瘦瘦,做人做事也是谨小慎微、内敛腼腆,怎么突然间变得容光焕发、大大咧咧,脸上肚子上也多了几斤肉,整…

基于ssm的酒店民宿管理系统的设计与实现

系统主要功能介绍: 1、登录:输入账号密码进行登录,登录后才能进行相应的操作 2、客房管理:客房管理主要是酒店预订,可以选择不同的房间,比如大床房,家庭房等,入住办理,…

【力扣刷题日记】1076.项目员工II

前言 练习sql语句,所有题目来自于力扣(https://leetcode.cn/problemset/database/)的免费数据库练习题。 今日题目: 1076.项目员工II 表:Project 列名类型project_idintemployee_idint (project_id, employee_id)…

AIGC实战——Transformer模型

AIGC实战——Transformer模型 0. 前言1. T52. GPT-3 和 GPT-43. ChatGPT小结系列链接 0. 前言 我们在 GPT (Generative Pre-trained Transformer) 一节所构建的 GPT 模型是一个解码器 Transformer,它逐字符地生成文本字符串,并使用因果掩码只关注输入字…