零基础学习人工智能—Python—Pytorch学习(二)
大学数学的学习与计算存在明显的割裂,许多学生在完成课程后仍无法理解其背后的真正意义。实际上,大学数学课程的时间安排往往过于冗长(例如高数和线性代数通常需要长达一年半的时间),而其核心目的是为计算机科学中的计算任务提供理论支持。然而,在大多数情况下,学生并未真正掌握这些知识,并且缺乏系统的学习方法和高效的学习资源。
PyTorch作为一种强大的深度学习框架,在处理梯度计算方面具有显著的优势。通过设置张量的requiresgrad属性(如x = torch.randn(3,requiresgrad=True)),可以实现对张量进行自动求导;结合前向传播(如y = x + 2)和逆向传播(如z.backward()),能够高效地计算目标函数相对于输入的梯度;同时通过定义标量函数(如z = z.mean())和加权操作(如z.backward(v)),可以灵活地处理复杂的梯度计算逻辑。需要注意的是,在多次调用backward()之前必须清零梯度(如weights.zero_()),以避免重复累加导致的结果偏差。
通过这些技术手段,PyTorch不仅简化了深度学习模型的设计与实现过程,还显著提升了开发效率。
前言
数学的学习跟数学的计算是要分开的,现在回头再去看大学的高数和线性代数,如果只是学习的话,其实一门课程3天,也就学完了。
学校的课程之所以上那么久,其实是为了考试,也就是为计算准备的。计算是有意义的,但在有计算机的情况下,计算的意义并不是很大。
所以,如果大学数学没学好,只要花一星期,就能补回来。甚至你没上过大学,只要你上过初中,同样,只需要一个星期就能学会高数和线性代数。
但,但,但,问题是,没有人这样给你上课,也没有这样资料让你学习。至少国内是没有这样学习的信息,国内全是耽误我们学习效率的学习模式。
明明是一个星期的知识,非得浪费我们一年到一年半。而且大学数学学习的计算,也没有法应对考研的题,你想考研还是得报班或者自己再继续学习解题技巧。
总之,大学数学是个即浪费学习时间,又完全没有目的性的扯淡课程。
Gradient
上文简要介绍了梯度、正向传播以及反向传播的相关概念。
别被这些术语吓到 worry. 它们本质上都是归纳总结的结果, 确实是我们学习路上的最大障碍. 我们需要避免它们, 但不必对它们感到畏惧.
让我们先深入理解一下...这个关键参数的作用机制.
print("============求梯度1==============")
a = torch.randn(3) #这里是randn 不是rand torch.randn:生成服从标准正态分布(均值为0,标准差为1)的随机数。 torch.rand:生成服从均匀分布(在区间 [0, 1) 之间)的随机数。
print(a)
b=a+2
print(b) # 输出tensor是a+2计算后的结果
x = torch.randn(3,requires_grad=True) #这里是randn 不是rand
print(x)
y=x+2
print(y) # 输出tensor是x+2计算后的结果,同时记录了函数,grad_fn=<AddBackward0> 表示是加法函数 grad=gradient fn=Function
在本研究中,变量a和x分别为启用了requires_grad和未启用了requires_grad的模式。如图所示。

在开启requires_grad之后给x赋值,并为其新增一个属性requires_grad=True。
经过计算得到y=x+2后的结果y,在其属性中包含了grad_fn=< AddBackward0 >。
其中grad表示梯度函数(Function),而Add则是加法运算。
而这个y=x+2的过程,则属于前向传播;前向传播即是我们定义的一系列函数运算。
正态分布简介
在之前的讨论中提到了正态分布的概念。对于中心位置不同的情况,请稍作解释:若以0为中心作为均值,则称该分布为均值为0的情况;当均值为0且标准差为1时,在不同区间内的数据分布遵循68-95-99.7规则;具体来说:
- 距离均值一个标准差(±1σ)之内的数据点约占68%
- 距离均值两个标准差(±2σ)之内的数据点约占95%
- 距离均值三个标准差(±3σ)之内的数据点约占99.7%
特别地:
当均值为0且标准差为1时,在±1σ范围内占比约68%,即[-1, 1]区间内;
在±2σ范围内占比约95%,即[-2, 2]区间内;
在±3σ范围内占比约99.7%,即[-3, 3]区间内。
此外:
当均值仍为0但标准差扩大至2时,在同样的各区间占比分别为:
- ±1σ(即[-2, 2])范围内的数据占约68%
- ±2σ(即[-4, 4])范围内的数据占约95%
- ±3σ(即[-6, 6])范围内的数据占约99.7%
标量函数和逆向传播
在此处采用前向传播方法,并设定y = x + 2这一类的简单线性变换作为初始模块。随后增添了一个新的前向传播环节:z = y² × 2。接着设定标量损失,在反向计算之前完成整个正向过程后进行反向梯度计算以更新参数权重。具体而言,在反向前需先提供相应的缩放因子(即常数C),例如计算平均值操作;或者可引入加权张量来进行调整以适应不同层之间的梯度贡献差异。值得注意的是,在深度学习中我们通常处理数值型数据而非单一数值(虽然理论上这也是可能的),因此正确理解这些术语至关重要。
x = torch.randn(3,requires_grad=True)
print(x)
y=x+2
z=y*y*2
print(z) # 这里会增加属性,grad_fn=<MulBackward0> ,这里的mul表示是乘法
z=z.mean() # 指定标量函数
#这里必须指定标量函数,如果删除z=z.mean() 这句话会提示 grad can be implicitly created only for scalar outputs
print(z) # 属性grad_fn=<MeanBackward0>,Mean表示平均值函数
z.backward() #逆向传播 如果requires_grad=False,则执行z.backward()回抛异常,因为没有记录grad_fn
print(x.grad)
运行如下图:

代码简介如下
x 被配置为采用了自动求导功能的张量。
y被定义为将变量x增加2后的结果,并且这一运算过程同样保留有自动求导的能力。
z被计算为将y平方后再乘以2的结果,并且这一过程也继承了自动求导的功能。
经过对变量z进行mean操作后得到的结果是一个标量(根据mean函数返回的是数据集所有元素均值的特点可知)。
通过调用backward函数,在当前运算上下文中计算并存储了变量x相对于变量z处相对于该路径上的梯度信息。
其中,在此过程中生成了从变量z到变量x处相对于该路径上的梯度信息。
梯度清0
执行第二次计算梯度(即调用backward())之前必须清除当前的梯度值。如果不清除该操作前的初始值,则后续操作将累加先前的结果。
print("============清零grad==============")
weights =torch.ones(4,requires_grad=True)
for epoch in range(3):
model_output =(weights*3).sum()#设置标量值,这里是连写了,分开就是a=weight*3 model_output=a.sum()
model_output.backward()
print(model_output.grad)
model_output.zero_()#可以注释这一行,看看不清零的效果
加权
若未预先设定标量或权重,则会导至错误出现。前面已经介绍过标量,接下来将讲述加权。
x = torch.randn(3,requires_grad=True)
print(x)
y=x+2
z=y*y*2
v = torch.tensor([1.0,2.0,3.0],dtype=torch.float32)
z.backward(v)
print(x.grad)
这里在z.backward(v)调用前,增加了一个创建权度tensor[v]的操作,这个tensor的结构要求和x是一样的,然后再把v做为参数给z.backward()。
像上面那样调用, backward() 时,没有传递参数,则默认会传递一个标量 1。
即:在使用backward时,要么指定一个标量(使用标量函数)要么指定一个权度tensor,如果不满足这两种情况,就会报错。
标量与加权的区别是,标量会乘到张量的每个元素里,而加权是把指定加权的tensor的元素乘到张量的对应行号和列号的元素里。
计算逻辑
在求取梯度的过程中,在完成一次前向传播后,在线提取所有的中间结果,并将其与相应的权重张量进行点积运算。
由于所涉及的两个变量(即梯度和权重张量)具有相同的张量结构,在执行操作时会逐个位置地进行数值相乘。这一操作通常被称为链式法则(即逐项相乘)。
具体计算
y=x+2,dy/dx=y导=1
z=2y²,dz/dy=z导=4y
dz/dx=(dz/dy) * (dy/dx)=1 * 4y=4y
因为y=x+2所以4y=4(x+2)
加权后是三个元素分别是 1 * 4(x1+2) 2 * 4(x2+2) 3 * 4(x3+2)
带入x即可得到梯度。
如下图,4 * (0.8329+2)=11.3316,下图是11.3317,这里应该是有个进位。

学习入口:零基础人工智能入门指南
基础学习就先到这。
注:此文章为原创,任何形式的转载都请联系作者获得授权并注明出处!

若您觉得这篇文章还不错,请点击下方的【推荐】,非常感谢!
