Pytorch 2.3.4 预备知识 -积分Calculus
微积分 Calculus
关于那些求导的基础知识我就不细讲了,如果有需要的话请访问:一篇关于微积分入门的文章 So,我们直接从代码开讲
1. 绘制函数 \(y = f(x) = x^3 - \frac{1}{x}\) 和其在\(x = 1\)处切线的图像。
我们先来定义函数和切线
#求导 第一题
def f(x):
return x**3 - 1/x
def numerical_lim(f,x):
return (f(x+h)-f(x))/h
def tangent_line(f,x):
#d就是调用numerical_diff求得在x点点导数``
k=numerical_lim(f,x)
# 这里直接y=kx+b求截,简单粗暴,y就是截距
b=f(x)-k*x
#使用lambda匿名函数,t是形参,':'后是要执行的函数表达式
return lambda t:k*t+b #返回的是函数形式
h这里我们取0.1就好了,如果想要得到更好的精度的话就得取更小的值。但是要注意当h取到非常小的值但是数据类型不支持的时候,整个计算就会出错,返回0.(比如说我的数据长度只有8个字节,但是我的精度达到了8字节装不下的程度,这时候h=0.)
import numpy as np
import matplotlib.pyplot as plt
h=0.1
x=np.arange(0.0,20.0,0.1)
y=f(x)
plt.xlabel('x')
plt.ylabel('f(x)')
#把函数作为形参时i,传入实参函数时,只要函数名即可,不用()
tf=tangent_line(f,10)
#因为tf返回的是lambda函数,所以要多调一次函数
y2=tf(x)
plt.grid()
plt.plot(x,y)
plt.plot(x,y2)
plt.show()
2. 求函数\(f(\mathbf{x}) = 3x_1^2 + 5e^{x_2}\)的梯度。
#第二题
import numpy as np
def numerical_grandient(f,x):
h = 10e-4 #设置一个合适的 h
grad = np.zeros_like(x) #生成和x形状相同的数组
for idx in range(x.size): #计算所有偏导
tmp_val = x[idx] #第idx个参数
x[idx] = tmp_val + h #要计算的那个自变量加h,其余不变
fxh1 = f(x) #计算f(x+h)
x[idx] = tmp_val - h #计算f(x-h)
fxh2 = f(x)
grad[idx] = (fxh1 - fxh2) / (2*h) #计算偏导
x[idx] = tmp_val
return grad
def f(x): #定义函数:𝑓(𝐱)=x**3+5𝑒**𝑥2
return 3*x[0]**2 + 5*np.e**x[1]
print(
numerical_grandient(f,np.array([1.0,2.0])),
numerical_grandient(f,np.array([3.0,3.0])))
输出:array([ 6. , 36.94528665])
3. 函数\(f(\mathbf{x}) = \|\mathbf{x}\|_2\)的梯度是什么?
#同第二题,只需要将第二题中的函数修改成第二范数的公式就好了
import numpy as np
def f(x): # L2范数的函数
total = 0
for i in range(x.size):
total += np.power(x[i],2)
return np.power(total,1/2)
def numerical_grandient(f,x):
h = 10e-4
grand = np.zeros_like(x)
for i in range(x.size): # 计算所有的偏导数
tempal_value = x[i]
x[i] = h + tempal_value
fxh1 = f(x)
x[i] = tempal_value - h
fxh2 = f(x)
grand[i] = (fxh1 - fxh2)/(2*h)
x[i] = tempal_value
return grand
print(numerical_grandient(f,x = np.array([1.0,1.0,3.0])))
输出:[0.30151133 0.30151133 0.90453403]
你可以写出函数\(u = f(x, y, z)\),其中\(x = x(a, b)\),\(y = y(a, b)\),\(z = z(a, b)\)的链式法则吗?
import torch
x = torch.tensor(1.2)
a1 = torch.tensor(2.3, requires_grad=True)
b1 = torch.tensor(1.3)
y1 = x * a1 + b1
a2 = torch.tensor(2.2)
b2 = torch.tensor(1.4)
y2 = y1 * a2 + b2
a3 = torch.tensor(1.1)
b3 = torch.tensor(2.2)
y3 = y2 * a3 + b3
# PyTorch自动实现链式法则的求导
# dy2_dw1 = torch.autograd.grad(y2, [w1], retain_graph=True)
# print(dy2_dw1[0])
# 手动用链式法则的方式求一下看看
dy3_dy2 = torch.autograd.grad(y3, [y1], retain_graph=True)
dy2_dy1 = torch.autograd.grad(y2, [y1], retain_graph=True)
dy1_dw1 = torch.autograd.grad(y1, [a1], retain_graph=True)
print(dy3_dy2[0] * dy2_dy1[0] * dy1_dw1[0])
输出: tensor(6.3888)
posted on 2021-12-12 20:32 YangShusen' 阅读(776) 评论(0) 编辑 收藏 举报