自己怎么做系统网站/nba总得分排行榜最新
目录
- 一、引言
- 二、矩阵运算案例
- 三、求导初试
- 四、常见公式
- 五、参考文献
一、引言
这部分参考B站GRNovmbrain博主的视频和一些网上的其他资料进行学习。一些后续继续学习的资料包括:
1、MIT线代课程。
2、mathematics for machine learning书籍,可以在这里下载。第139页专门讲了矩阵求导方面的知识。
3、其他Up的视频。空狐公子、西凉阿土伯。
二、矩阵运算案例
先解决一些基本语法问题,再对比使用NumPy库和纯代码方式实现的矩阵乘法时间差异。
1、关于Python中的[:-1]和[::-1]区别。
# a[i:j]表示复制a[i]到a[j-1],以生成新的list对象
test_a = [0,1,2,3,4,5,6,7,8,9]
print(test_a)
test_b = test_a[1:3]
print(test_b)
test_c = test_a[:3] # 当i缺省时,默认为0。这里相当于a[0:3]
print(test_c)
test_a_len = len(test_a)
print(test_a_len)
test_d = test_a[1:] # 当j缺省时,默认为len(test_a),这里相当于a[1:10]
print(test_d)
test_e = test_a[:] # 当i,j都缺省时,相当于完整复制一份a
print(test_e)
# a[i:j:s]表示按s表示步进生成从i到j的list对象,缺省时s为1,a[i:j:1]就相当于a[i:j]
# 当s<0时,如果i缺省,默认i为-1,如果j缺省,默认j为-len(test_a)-1
test_f = test_a[::-1] #这里相当于test_a[-1:-len(test_a)-1:-1],即从最后一个元素到第一个元素复制一遍,为倒序
print(test_f)
结果如下。
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2]
[0, 1, 2]
10
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
2、numpy.dot()函数用法。dot()返回的是两个数组的点积。
1°如果处理的是一维数组,则得到的是两数组的內积。
test_a = np.arange(0,9)
test_b = test_a[::-1]
np.dot(test_a,test_b)
返回结果,为84,正确。
2°如果是二维数组(矩阵)之间的运算,则得到的是矩阵积。
test_a = np.arange(1,5).reshape(2,2)
test_b = np.arange(5,9).reshape(2,2)
print(test_a)
print(test_b)
test_c = np.dot(test_a,test_b)
print(test_c)
test_d = test_a.dot(test_b) #由数组实例对象来进行调用
print(test_d)
得到数组中的每个元素为,第一个矩阵中与该元素行号相同的元素与第二个矩阵与该元素列号相同的元素,两两相乘后再求和。
[[1 2][3 4]]
[[5 6][7 8]]
[[19 22][43 50]]
[[19 22][43 50]]
3°矩阵乘法案例。
import time
test_a = np.random.rand(1000000)
test_b = np.random.rand(1000000)
tic = time.time()
test_c = np.dot(test_a,test_b)
toc = time.time()
print(test_c)
print("Vectorized version:" + str(1000*(toc-tic)) + "ms")
test_c = 0
tic = time.time()
for i in range(1000000):test_c += test_a[i]*test_b[i]
toc = time.time()
print(test_c)
print("For loop:" + str(1000*(toc-tic)) + "ms")
从输出结果可以看到,计算过程中使用向量化、矩阵化的计算,会快很多,要尽量避免大量使用for循环来计算。
250275.9156612208
Vectorized version:1.9679069519042969ms
250275.9156612197
For loop:464.7529125213623ms
三、求导初试
1、向量函数。
向量函数相对的是标量函数,标量函数为输出是标量(一个数)的函数(输入没要求,标量向量都行)。向量函数为输出是向量的函数(输入向量或标量都行)。这个地方Up讲的几个例子很清楚。
小结:输入X可以为标量、向量和矩阵。输出f(X)也可以是标量、向量和矩阵。先重点讨论的是输入X和输出f(X)分别为标量和向量的情况,矩阵的暂时不涉及。2*2有四种可能:标量对标量的求导、标量对向量的求导、向量对标量的求导、向量对向量的求导。
矩阵求导的本质:dA/dB为矩阵A中的每一个元素,对矩阵B中的每一个元素求导。
从求导后的元素个数的角度理解。比如A为1x1的矩阵,B为1x1的矩阵,即A和B都是标量元素,dA/dB结果为1个元素。又如A为1xp的矩阵,B为1xn的矩阵,dA/dB结果为pxn个元素。再如A为qxp的矩阵,B为mxn的矩阵,dA/dB结果为qxpxmxn个元素。
2、求导秘术——YX拉伸。
1°标量不变,向量拉伸。df(x)/dX中,如果有f(x)或X为标量,则不变,反之有向量则进行拉伸。拉伸包括横向拉伸和纵向拉伸两者,具体那种看1°。
2°前面横向拉,后面纵向拉。比如YX拉伸中,前面Y就横向拉,X就纵向拉。
3°例子1:f(x)标量函数,X列向量[x1,x2,…,xn](转置),即f(x)=f(x1,x2,…,xn)。求df(x)/dX。
df(x)dX=[∂f(x)∂x1∂f(x)∂x2...∂f(x)∂xn]\frac{df\left( x \right)}{dX}=\left[ \begin{array}{c} \frac{\partial f\left( x \right)}{\partial x_1}\\ \frac{\partial f\left( x \right)}{\partial x_2}\\ ...\\ \frac{\partial f\left( x \right)}{\partial x_n}\\ \end{array} \right] dXdf(x)=⎣⎢⎢⎢⎡∂x1∂f(x)∂x2∂f(x)...∂xn∂f(x)⎦⎥⎥⎥⎤
f(x)就是YX拉伸中的Y,在前面,为标量,保持不变。X为向量,在后面,需要纵向拉伸。从结果可以发现,就是对多元函数求偏导(其实就是梯度),放到一个列向量里。而最终的元素个数为1xn,也是满足之前的本质的。
4°例子2:f(x)向量函数,X标量,求df(x)/dX。
f(x)=[f1(x)f2(x)...fn(x)]f\left( x \right) =\left[ \begin{array}{c} f_1\left( x \right)\\ f_2\left( x \right)\\ ...\\ f_n\left( x \right)\\ \end{array} \right] f(x)=⎣⎢⎢⎡f1(x)f2(x)...fn(x)⎦⎥⎥⎤
根据向量拉伸,f(x)需要按照横向来进行拉伸。标量不变。最终的结果如下:
df(x)dX=[∂f1(x)∂x∂f2(x)∂x...∂fn(x)∂x]\frac{df\left( x \right)}{dX}=\left[ \begin{matrix} \frac{\partial f_1\left( x \right)}{\partial x}& \frac{\partial f_2\left( x \right)}{\partial x}& ...& \frac{\partial f_n\left( x \right)}{\partial x}\\ \end{matrix} \right] dXdf(x)=[∂x∂f1(x)∂x∂f2(x)...∂x∂fn(x)]
5°例子3:f(x)向量函数,X向量。表示就和之前的一样。同样,求df(x)/dX。
df(x)dX=[∂f(x)∂x1∂f(x)∂x2...∂f(x)∂xn]=[∂f1(x)∂x1∂f2(x)∂x1⋯∂fn(x)∂x1∂f1(x)∂x2∂f2(x)∂x2⋯∂fn(x)∂x2⋮⋮⋯⋮∂f1(x)∂xn∂f2(x)∂xn⋯∂fn(x)∂xn]\frac{df\left( x \right)}{dX}=\left[ \begin{array}{c} \frac{\partial f\left( x \right)}{\partial x_1}\\ \frac{\partial f\left( x \right)}{\partial x_2}\\ ...\\ \frac{\partial f\left( x \right)}{\partial x_n}\\ \end{array} \right] =\left[ \begin{matrix} \frac{\partial f_1\left( x \right)}{\partial x_1}& \frac{\partial f_2\left( x \right)}{\partial x_1}& \cdots& \frac{\partial f_n\left( x \right)}{\partial x_1}\\ \frac{\partial f_1\left( x \right)}{\partial x_2}& \frac{\partial f_2\left( x \right)}{\partial x_2}& \cdots& \frac{\partial f_n\left( x \right)}{\partial x_2}\\ \vdots& \vdots& \cdots& \vdots\\ \frac{\partial f_1\left( x \right)}{\partial x_n}& \frac{\partial f_2\left( x \right)}{\partial x_n}& \cdots& \frac{\partial f_n\left( x \right)}{\partial x_n}\\ \end{matrix} \right] dXdf(x)=⎣⎢⎢⎢⎡∂x1∂f(x)∂x2∂f(x)...∂xn∂f(x)⎦⎥⎥⎥⎤=⎣⎢⎢⎢⎢⎡∂x1∂f1(x)∂x2∂f1(x)⋮∂xn∂f1(x)∂x1∂f2(x)∂x2∂f2(x)⋮∂xn∂f2(x)⋯⋯⋯⋯∂x1∂fn(x)∂x2∂fn(x)⋮∂xn∂fn(x)⎦⎥⎥⎥⎥⎤
结果是一个n*n的矩阵。仔细一看,就是雅可比矩阵。
四、常见公式
1、例子1:f(x)=TAxX。TA为矩阵A的转置,是系数矩阵,X为矩阵B,具体如下。求df(x)/dX的值。
A=[a1a2⋮an]X=[x1x2⋮xn]A=\left[ \begin{array}{c} a_1\\ a_2\\ \vdots\\ a_n\\ \end{array} \right] \ \ \ X=\left[ \begin{array}{c} x_1\\ x_2\\ \vdots\\ x_n\\ \end{array} \right] A=⎣⎢⎢⎢⎡a1a2⋮an⎦⎥⎥⎥⎤ X=⎣⎢⎢⎢⎡x1x2⋮xn⎦⎥⎥⎥⎤
先将f(x)表示为具体的计算式子。
f(x)=ATX=∑i=1naixif\left( x \right) =A^TX=\sum_{i=1}^n{a_ix_i} f(x)=ATX=i=1∑naixi
根据之前的结论,可以发现,最后求出来的结果,就是系数矩阵A。
df(x)dX=[∂f(x)∂x1∂f(x)∂x2...∂f(x)∂xn]=[a1a2⋮an]=A\frac{df\left( x \right)}{dX}=\left[ \begin{array}{c} \frac{\partial f\left( x \right)}{\partial x_1}\\ \frac{\partial f\left( x \right)}{\partial x_2}\\ ...\\ \frac{\partial f\left( x \right)}{\partial x_n}\\ \end{array} \right] =\left[ \begin{array}{c} a_1\\ a_2\\ \vdots\\ a_n\\ \end{array} \right] =A dXdf(x)=⎣⎢⎢⎢⎡∂x1∂f(x)∂x2∂f(x)...∂xn∂f(x)⎦⎥⎥⎥⎤=⎣⎢⎢⎢⎡a1a2⋮an⎦⎥⎥⎥⎤=A
可以得到如下结论:f(x)=ATX=XTAdATXdX=dXTAdX=Af\left( x \right) =A^TX=X^TA\ \ \ \frac{dA^TX}{dX}=\frac{dX^TA}{dX}=A f(x)=ATX=XTA dXdATX=dXdXTA=A
2、例子2:f(x)=TXxAxX。具体矩阵信息如下。求df(x)/dX的值。
X=[x1x2⋮xn]A=[a11a12⋯a1na21a22⋯a2n⋮⋮⋯⋮an1an2⋯ann]X=\left[ \begin{array}{c} x_1\\ x_2\\ \vdots\\ x_n\\ \end{array} \right] \ \ A=\left[ \begin{matrix} a_{11}& a_{12}& \cdots& a_{1n}\\ a_{21}& a_{22}& \cdots& a_{2n}\\ \vdots& \vdots& \cdots& \vdots\\ a_{n1}& a_{n2}& \cdots& a_{nn}\\ \end{matrix} \right] X=⎣⎢⎢⎢⎡x1x2⋮xn⎦⎥⎥⎥⎤ A=⎣⎢⎢⎢⎡a11a21⋮an1a12a22⋮an2⋯⋯⋯⋯a1na2n⋮ann⎦⎥⎥⎥⎤
从TX、A和X为1xn、nxn和nx1的大小,可以得到结果是一个元素的标量。可以先把f(x)的表达式用线性方程表示出来,这里挖坑,复习完线代的二次型后再来弄,直接先跳一步,把结果写出来。
df(x)dX=[∂f(x)∂x1∂f(x)∂x2...∂f(x)∂xn]=[∑j=1na1jxj+∑i=1nai1xi∑j=1na2jxj+∑i=1nai2xi⋮∑j=1nanjxj+∑i=1nainxi]\frac{df\left( x \right)}{dX}=\left[ \begin{array}{c} \frac{\partial f\left( x \right)}{\partial x_1}\\ \frac{\partial f\left( x \right)}{\partial x_2}\\ ...\\ \frac{\partial f\left( x \right)}{\partial x_n}\\ \end{array} \right] =\left[ \begin{array}{c} \sum_{j=1}^n{a_{1j}x_j+\sum_{i=1}^n{a_{i1}x_i}}\\ \sum_{j=1}^n{a_{2j}x_j+\sum_{i=1}^n{a_{i2}x_i}}\\ \vdots\\ \sum_{j=1}^n{a_{nj}x_j+\sum_{i=1}^n{a_{in}x_i}}\\ \end{array} \right] dXdf(x)=⎣⎢⎢⎢⎡∂x1∂f(x)∂x2∂f(x)...∂xn∂f(x)⎦⎥⎥⎥⎤=⎣⎢⎢⎢⎡∑j=1na1jxj+∑i=1nai1xi∑j=1na2jxj+∑i=1nai2xi⋮∑j=1nanjxj+∑i=1nainxi⎦⎥⎥⎥⎤
把公式再化简下得到下式。
df(x)dX=[∑j=1na1jxj∑j=1na2jxj⋮∑j=1nanjxj]+[∑i=1nai1xi∑i=1nai2xi⋮∑i=1nainxi]\frac{df\left( x \right)}{dX}=\left[ \begin{array}{c} \sum_{j=1}^n{a_{1j}x_j}\\ \sum_{j=1}^n{a_{2j}x_j}\\ \vdots\\ \sum_{j=1}^n{a_{nj}x_j}\\ \end{array} \right] +\left[ \begin{array}{c} \sum_{i=1}^n{a_{i1}x_i}\\ \sum_{i=1}^n{a_{i2}x_i}\\ \vdots\\ \sum_{i=1}^n{a_{in}x_i}\\ \end{array} \right] dXdf(x)=⎣⎢⎢⎢⎡∑j=1na1jxj∑j=1na2jxj⋮∑j=1nanjxj⎦⎥⎥⎥⎤+⎣⎢⎢⎢⎡∑i=1nai1xi∑i=1nai2xi⋮∑i=1nainxi⎦⎥⎥⎥⎤
仔细观察,可以发现,其实就是这样的。
df(x)dX=[a11a12⋯a1na21a22⋯a2n⋮⋮⋯⋮an1an2⋯ann][x1x2⋮xn]+[a11a21⋯an1a12a22⋯an2⋮⋮⋯⋮a1na2n⋯ann][x1x2⋮xn]\frac{df\left( x \right)}{dX}=\left[ \begin{matrix} a_{11}& a_{12}& \cdots& a_{1n}\\ a_{21}& a_{22}& \cdots& a_{2n}\\ \vdots& \vdots& \cdots& \vdots\\ a_{n1}& a_{n2}& \cdots& a_{nn}\\ \end{matrix} \right] \left[ \begin{array}{c} x_1\\ x_2\\ \vdots\\ x_n\\ \end{array} \right] +\left[ \begin{matrix} a_{11}& a_{21}& \cdots& a_{n1}\\ a_{12}& a_{22}& \cdots& a_{n2}\\ \vdots& \vdots& \cdots& \vdots\\ a_{1n}& a_{2n}& \cdots& a_{nn}\\ \end{matrix} \right] \left[ \begin{array}{c} x_1\\ x_2\\ \vdots\\ x_n\\ \end{array} \right] dXdf(x)=⎣⎢⎢⎢⎡a11a21⋮an1a12a22⋮an2⋯⋯⋯⋯a1na2n⋮ann⎦⎥⎥⎥⎤⎣⎢⎢⎢⎡x1x2⋮xn⎦⎥⎥⎥⎤+⎣⎢⎢⎢⎡a11a12⋮a1na21a22⋮a2n⋯⋯⋯⋯an1an2⋮ann⎦⎥⎥⎥⎤⎣⎢⎢⎢⎡x1x2⋮xn⎦⎥⎥⎥⎤
最终,得到如下结论:
dXTAXdX=AX+ATX=(A+AT)X\frac{dX^TAX}{dX}=AX+A^TX=\left( A+A^T \right) X dXdXTAX=AX+ATX=(A+AT)X
五、参考文献
python 中的[:-1]和[::-1]
后续工作1:剩下的两节视频。
后续工作2:看一些引言中的一些资料。