x = np.arange(0, 3, 0.1)
plot(x, [x3 - 1/x, 3*x2 + 1/(x**2)], ‘x’, ‘f(x)’, legend=[‘f(x)’, ‘Tangent line (x=1)’])
[6x_1, 5e^{x_2}]
[x_1/||x||, x_2/||x||,…]
du/da = du/dx*dx/da…
赞同,想问下你们都用什么来编辑数学符号,latex?
第一题:
先求得导函数f’(x)=3x^2+1/(x^2)
当x=1时,切线就是y=4x-4
https://zh.d2l.ai/chapter_preliminaries/calculus.html#subsec-calculus-grad
这里的运算规则给我看迷糊了,为啥Ax的梯度是A转置?
# hw 1
def f(x):
return x ** 3 - 1 / x
plot(x, [f(x), 4 * x - 4], 'x', 'f(x)', legend=['f(x)', 'Tangent line (x=1)'])
其实应该是 2.3 * x - 3.3 ,用 2 * x - 3 在图形界面上看不出区别,所以问题不大。
2.3 是 1.0 位置的斜率,(y2 - y1) / (x2 - x1) 可以得到
-3.3 是为了在 1.0 这个 x 点重合,调整 y 的值
具体可以看下边的注释
x = np.arange(0, 3, 0.1)
y = f(x)
print(x)
x1 = x[10]
x2 = x[11]
y1 = f(x1)
y2 = f(x2)
print(f'x1={x1}') # 取 x = 1.0 这个点
print(f'f(x1)={f(x1)}') # x = 1.0 时,y = -1.0
print(f'(y2 - y1) / (x2 - x1)={(y2 - y1) / (x2 - x1)}') # 差值是 0.1 的时候求斜率,是 2.3,如差值为 0.00001 无穷小,则斜率无限趋近于为 2,所以用 2 也没错
print(f'y1 - (2.3 * x) = {y1 - (2.3 * x1)} ') # 让斜率这条线和曲线在 x=1.0 点重合,看 y 要怎么调整,得到 y 要 - 3.3
plot(x, [y, 2.3 * x - 3.3], 'x', 'f(x)', legend=['f(x)', '2 * x - 3'])
主要是需要理解这里的f(x)=||x||^2中的x是一个n维向量( x=[x1,x2,…,xn] ),||x||是x的欧几里得范数(线性代数),||x||^2就是x各个分量的平方和。即
f(x)=||x||^2,将向量x展开来写,形式就是:
f(x1,x2,…,xn)=x1^2+x2^2+…+xn^2。
x=[x1,x2,…xn]作为输入,它的每个分量都是一个变量,f(x)本质是n元2次函数,f(x)的梯度,就是f(x1,x2,…xn)分别对x1,x2,…xn求偏导(高数)得到的结果组成的向量,即
[2*x1,2*x2,…,2*xn),写成向量的形式就是
f(x)=||x||^2的梯度是2x
import numpy as np
import d2l
x = np.arange(0.1,3,0.1)
f = lambda x: x**3-1/x
d = lambda x: 4*x-4
d2l.torch.plot(x, [f(x), d(x)], 'x', 'f(x)', legend=['f(x)', 'tangent(x=1)'])
交作业:
代码:
import numpy as np
from matplotlib import pyplot as plt
from numpy import arange, exp
import sympy as sp
#1
定义函数
def f(x):
return x3 - x(-1)
定义导数
def df(x):
return 3*x2 + x(-2)
定义切线
def tangent_line(x, a):
return df(a)*x - df(a)*a + f(a)
x = arange(0.1, 3, 0.1) # 避免除以零
plt.plot(x, f(x), label=‘f(x) = x^3 - 1/x’)
plt.plot(x, tangent_line(x, 1), ‘–’,label=‘Tangent line (x=1)’)
plt.xlabel(‘x’)
plt.ylabel(‘f(x)’)
plt.legend()
plt.grid(True)
plt.show()
#2
x1 = arange(0, 3, 0.1)
x2 = arange(0, 3, 0.1)
定义函数
def f(x):
return 3x1**2+5exp(x2)
x1的偏导
def df_x1(x1, x2):
return 6*x1
x2的偏导
def df_x2(x1, x2):
return 5*exp(x2)
f(x)的梯度
def grad_f(x1, x2):
return [df_x1(x1, x2), df_x2(x1, x2)]
print(‘f(x)的梯度:’)
sp.pprint(sp.Matrix(grad_f(x1, x2)).T)
#3
定义函数
def f(x):
return np.linalg.norm(x)
x的偏导
def df(x):
return x/np.linalg.norm(x)
f(x)的梯度
def grad_f(x):
return df(x)
print(‘f(x)的梯度:’)
sp.pprint(sp.Matrix(grad_f(x)))
#4
创建符号变量
a, b = sp.symbols(‘a b’)
x, y, z = sp.symbols(‘x y z’)
定义函数
def u(x, y, z):
return x(a, b), y(a, b), z(a, b)
a的偏导
def du_da(a, b):
return sp.diff(u, x)*sp.diff(x, a) + sp.diff(u, y)*sp.diff(y, a) + sp.diff(u, z)*sp.diff(z, a)
b的偏导
def du_db(a, b):
return sp.diff(u, x)*sp.diff(x, b) + sp.diff(u, y)*sp.diff(y, b) + sp.diff(u, z)*sp.diff(z, b)
u的链式法则
def du_da_chain(a, b):
return (
sp.diff(u, x)*sp.diff(x, a) + sp.diff(u, y)*sp.diff(y, a) + sp.diff(u, z)*sp.diff(z, a)
+sp.diff(u, x)*sp.diff(x, b) + sp.diff(u, y)sp.diff(y, b) + sp.diff(u, z)sp.diff(z, b)
)
第一问:
绘制函数在x=1处切线的图像。我定义函数和导数然后再定义切线。对于x的范围选择0.1开始避免x-1不存在。画图用matplotlib的pyplot画图。用pyplot的show来展示图像。
得到图像。
第二问:
求函数的梯度。梯度为矢量。以x1的偏导和x2的偏导分别为元素的矢量。我定义了x1和x2的范围(0,3)步长为0.1。运行代码,求得每个x1和x2处的偏导组成的函数的梯度。
f(x)的梯度:
⎡0.0 5.0 ⎤
⎢ ⎥
⎢0.6 5.52585459037824⎥
⎢ ⎥
⎢1.2 6.10701379080085⎥
⎢ ⎥
⎢1.8 6.74929403788002⎥
⎢ ⎥
⎢2.4 7.45912348820635⎥
⎢ ⎥
⎢3.0 8.24360635350064⎥
⎢ ⎥
⎢3.6 9.11059400195255⎥
⎢ ⎥
⎢4.2 10.0687635373524⎥
⎢ ⎥
⎢4.8 11.1277046424623⎥
⎢ ⎥
⎢5.4 12.2980155557847⎥
⎢ ⎥
⎢6.0 13.5914091422952⎥
⎢ ⎥
⎢6.6 15.0208301197322⎥
⎢ ⎥
⎢7.2 16.6005846136827⎥
⎢ ⎥
⎢7.8 18.3464833380962⎥
⎢ ⎥
⎢8.4 20.2759998342234⎥
⎢ ⎥
⎢9.0 22.4084453516903⎥
⎢ ⎥
⎢9.6 24.7651621219756⎥
⎢ ⎥
⎢10.2 27.369736958636 ⎥
⎢ ⎥
⎢10.8 30.2482373220647⎥
⎢ ⎥
⎢11.4 33.4294722113964⎥
⎢ ⎥
⎢12.0 36.9452804946533⎥
⎢ ⎥
⎢12.6 40.8308495628383⎥
⎢ ⎥
⎢13.2 45.1250674971706⎥
⎢ ⎥
⎢14.4 55.115881903208 ⎥
⎢ ⎥
⎢15.0 60.9124698035174⎥
⎢ ⎥
⎢15.6 67.3186901750085⎥
⎢ ⎥
⎢16.2 74.3986586243642⎥
⎢ ⎥
⎢16.8 82.2232338554853⎥
⎢ ⎥
⎣17.4 90.8707268472153⎦f(x)的梯度:
⎡0.0 5.0 ⎤
⎢ ⎥
⎢0.6 5.52585459037824⎥
⎢ ⎥
⎢1.2 6.10701379080085⎥
⎢ ⎥
⎢1.8 6.74929403788002⎥
⎢ ⎥
⎢2.4 7.45912348820635⎥
⎢ ⎥
⎢3.0 8.24360635350064⎥
⎢ ⎥
⎢3.6 9.11059400195255⎥
⎢ ⎥
⎢4.2 10.0687635373524⎥
⎢ ⎥
⎢4.8 11.1277046424623⎥
⎢ ⎥
⎢5.4 12.2980155557847⎥
⎢ ⎥
⎢6.0 13.5914091422952⎥
⎢ ⎥
⎢6.6 15.0208301197322⎥
⎢ ⎥
⎢7.2 16.6005846136827⎥
⎢ ⎥
⎢7.8 18.3464833380962⎥
⎢ ⎥
⎢8.4 20.2759998342234⎥
⎢ ⎥
⎢9.0 22.4084453516903⎥
⎢ ⎥
⎢9.6 24.7651621219756⎥
⎢ ⎥
⎢10.2 27.369736958636 ⎥
⎢ ⎥
⎢10.8 30.2482373220647⎥
⎢ ⎥
⎢11.4 33.4294722113964⎥
⎢ ⎥
⎢12.0 36.9452804946533⎥
⎢ ⎥
⎢12.6 40.8308495628383⎥
⎢ ⎥
⎢13.2 45.1250674971706⎥
⎢ ⎥
⎢14.4 55.115881903208 ⎥
⎢ ⎥
⎢15.0 60.9124698035174⎥
⎢ ⎥
⎢15.6 67.3186901750085⎥
⎢ ⎥
⎢16.2 74.3986586243642⎥
⎢ ⎥
⎢16.8 82.2232338554853⎥
⎢ ⎥
⎣17.4 90.8707268472153⎦
第三问:
函数的梯度是什么?该函数是向量x的 2-范数(即欧几里得长度)
numpy中有,linalg.norm。然后同样梯度由偏导元素构成的矢量。x的偏导为x/(x的范数)。
我定义x的范围依旧为:(0,3)步长为0.1。
运行代码得到:
f(x)的梯度:
⎡0.0108116005840384⎤
⎢ ⎥
⎢0.0216232011680767⎥
⎢ ⎥
⎢0.0324348017521151⎥
⎢ ⎥
⎢0.0432464023361534⎥
⎢ ⎥
⎢0.0540580029201918⎥
⎢ ⎥
⎢0.0648696035042301⎥
⎢ ⎥
⎢0.0756812040882685⎥
⎢ ⎥
⎢0.0864928046723068⎥
⎢ ⎥
⎢0.0973044052563452⎥
⎢ ⎥
⎢0.108116005840384 ⎥
⎢ ⎥
⎢0.118927606424422 ⎥
⎢ ⎥
⎢ 0.12973920700846 ⎥
⎢ ⎥
⎢0.140550807592499 ⎥
⎢ ⎥
⎢0.151362408176537 ⎥
⎢ ⎥
⎢0.162174008760575 ⎥
⎢ ⎥
⎢0.172985609344614 ⎥
⎢ ⎥
⎢0.183797209928652 ⎥
⎢ ⎥
⎢ 0.19460881051269 ⎥
⎢ ⎥
⎢0.205420411096729 ⎥
⎢ ⎥
⎢0.216232011680767 ⎥
⎢ ⎥
⎢0.227043612264805 ⎥
⎢ ⎥
⎢0.237855212848844 ⎥
⎢ ⎥
⎢0.248666813432882 ⎥
⎢ ⎥
⎢0.259478414016921 ⎥
⎢ ⎥
⎢0.270290014600959 ⎥
⎢ ⎥
⎢0.281101615184997 ⎥
⎢ ⎥
⎢0.291913215769036 ⎥
⎢ ⎥
⎢0.302724816353074 ⎥
⎢ ⎥
⎣0.313536416937112 ⎦
第四问:
函数u=f(x,y,z),其中x=x(a,b),y=y(a,b),z=z(a,b)的链式法则。
用sympy提供符号代数。根据定义定义函数,链式法则就是嵌套式求偏导,求得偏导值的和,但由于不知道具体的函数所以无法设置值的范围来运行代码。
若有错误,希望大家指正。
——初学者rookie
举个例子就明白了
比如A=(2,1), x = (x1, x2) ,Ax = (Ax1, Ax2)
根据求梯度公式,分别对x1和x2求偏导,得到的是一个列向量,也就是(2, 1)^T
Q&A(1)