微积分(python实现)
前言
写blog的原因
希望能够监督自己好好学完机器学习,尤其啃完是西瓜书,然后看完《动手学深度学习——pytorch版》,每天来写一个blog,记录今天的学习内容,如果可以对别人的学习起到帮助,那是更好的。
对于数学基础,我几乎是参考的是《机器学习数学基础》这本书
一、函数和极限
-
函数的定义
-
反函数
-
复合函数
-
多元函数
-
函数极限的性质
-
洛必达法则
-
函数的连续性
-
拉格朗日乘数法
-
函数间断点
对于上述目录我认为就两点,一个就是求极限,第二个就是求极值
对于极限的问题:这本书写了两个例子 -
例子1:求解 lim a → 0 s i n ( a ) a \lim_{a\to0} \frac {sin(a)} a a→0limasin(a)
- 解决步骤
- 步骤1:定义a
- 步骤2:定义b= s i n ( a ) a \frac {sin(a)}{a} asin(a)
- 步骤3:定义 result= lim n → 0 b \lim_{n\to 0}b n→0limb
- 代码实现
- 解决步骤
# -*- coding:utf -*-
import sympy
sympy.init_printing()#输出设置
from sympy import oo
#1.求sin(a) / a 在a = 0 处的极限
a = sympy.Symbol('a')#定义极限的自变量是a
b = sympy.sin(a)/a#用b把式子表现出来
result =sympy.limit(b,a,0)
print('sin(a)/a在a=0处的极限',result)
- 例子2:求解
lim
n
→
∞
(
n
+
3
n
+
2
)
n
\lim_{n\to\infin}\ (\frac {n+3}{n+2})^n
n→∞lim (n+2n+3)n
这个问题跟上面一样
# -*- coding=utf-8 -*-
import sympy
from sympy import oo
sympy.init_printing()#输出
n = sympy.Symbol('n')#定义变量为n
h = ((n+3)/(n+2))**n
result = sympy.limit(h,n,sympy.oo)#sympy.oo表示无穷的意思
print(result)
另外一个是求极值的问题,就是通过拉格朗日乘数法(我觉得这个对后面学习向量机会有作用,所以加了进来),具体是这样的一个问题,简单来说:
x
2
a
2
+
y
2
b
2
+
z
2
c
2
≤
1
\frac{x^2}{a^2} +\frac{y^2}{b^2}+\frac{z^2}{c^2} \leq1
a2x2+b2y2+c2z2≤1在这个条件下求解
f
(
x
,
y
.
z
)
=
8
x
y
z
f(x,y.z)=8xyz
f(x,y.z)=8xyz的最大值,正常的数学解法是
F
(
x
,
y
,
z
,
λ
)
=
f
(
x
,
y
,
z
)
+
λ
g
(
x
,
y
,
z
)
其中
g
(
x
,
y
,
z
)
是不等式的函数
F(x,y,z,\lambda)=f(x,y,z)+\lambda g(x,y,z)其中g(x,y,z)是不等式的函数
F(x,y,z,λ)=f(x,y,z)+λg(x,y,z)其中g(x,y,z)是不等式的函数然后分别对
x
,
y
,
z
,
λ
x,y,z,\lambda
x,y,z,λ求偏导得:
∂
F
(
x
,
y
,
z
,
λ
)
∂
x
=
8
y
z
+
2
λ
x
a
2
=
0
;
\frac{\partial F(x,y,z,\lambda)}{\partial x}=8yz+\frac{2\lambda x}{a^2}=0;
∂x∂F(x,y,z,λ)=8yz+a22λx=0;
∂
F
(
x
,
y
,
z
,
λ
)
∂
y
=
8
x
z
+
2
λ
y
b
2
=
0
;
\frac{\partial F(x,y,z,\lambda)}{\partial y}=8xz+\frac{2\lambda y}{b^2}=0;
∂y∂F(x,y,z,λ)=8xz+b22λy=0;
∂
F
(
x
,
y
,
z
,
λ
)
∂
z
=
8
x
y
+
2
λ
z
c
2
=
0
;
\frac{\partial F(x,y,z,\lambda)}{\partial z}=8xy+\frac {2\lambda z}{c^2}=0;
∂z∂F(x,y,z,λ)=8xy+c22λz=0;
∂
F
(
x
,
y
,
z
,
λ
)
∂
λ
=
x
2
a
2
+
y
2
b
2
+
z
2
c
2
−
1
=
0.
\frac{\partial F(x,y,z,\lambda)}{\partial \lambda}=\frac{x^2}{a^2} +\frac{y^2}{b^2}+\frac{z^2}{c^2}-1=0.
∂λ∂F(x,y,z,λ)=a2x2+b2y2+c2z2−1=0.联立这四个方程得
x
=
3
3
a
;
x=\frac{\sqrt3}{3}a;
x=33a;
y
=
3
3
b
;
y=\frac{\sqrt3}{3}b;
y=33b;
z
=
3
3
c
.
z=\frac{\sqrt3}{3}c.
z=33c.
最后得出最大值
V
m
a
x
=
f
(
3
3
a
,
3
3
b
,
3
3
c
)
=
8
3
9
a
b
c
V_{max}=f(\frac{\sqrt3}{3}a,\frac{\sqrt3}{3}b,\frac{\sqrt3}{3}c)=\frac{8\sqrt3}{9}abc
Vmax=f(33a,33b,33c)=983abc
from scipy.optimize import minimize
import numpy as np
e = 1e-10 # 非常接近0的值
fun = lambda x : 8 * (x[0] * x[1] * x[2]) # f(x,y,z) =8 *x*y*z
cons = ({'type': 'eq', 'fun': lambda x: x[0]**2+ x[1]**2+ x[2]**2 - 1}, # x^2 + y^2 + z^2=1
{'type': 'ineq', 'fun': lambda x: x[0] - e}, # x>=e等价于 x > 0
{'type': 'ineq', 'fun': lambda x: x[1] - e},
{'type': 'ineq', 'fun': lambda x: x[2] - e}
)
x0 = np.array((1.0, 1.0, 1.0)) # 设置初始值
res = minimize(fun, x0, method='SLSQP', constraints=cons)
#SLSQP:序贯最小二乘规划算法,可以处理边界约束、等式约束和不等式约束条件。SLSQP 算法性能良好,是带有约束条件优化问题的默认算法
#minimize()函数默认是求解目标函数的最小值,但是可以通过设置参数method='SLSQP'来使用序列最小优化算法来求解约束条件下的最大值
print('最大值:',res.fun)
print('最优解:',res.x)
print('迭代终止是否成功:', res.success)
print('迭代终止原因:', res.message)
不过这里又学到python非线性规划scipy.optimize.minimize的操作。一般可以利用method='SLSQP’来转换成求最大值
二、导数
- 导数的概念
- 偏导数、全导数
- 高阶导数
- 链式求导
- 泰勒公式
三、 方向导数和梯度
-
方向导数和梯度
1. 方向导数和梯度的理解:**方向导数简单来说是一个函数沿指定方向的变化率**,方向导数取最大值的方向就是梯度,也就是函数变化率最大的方向
-
雅可比矩阵与近视问题
-
黑塞矩阵
2. 简单来说 - 一元数量的导数是一个数量,即斜率 - 多元数量函数的导数是一个向量,即梯度 - 多元向量值函数的导数是一个矩阵,即雅可比矩阵(多元向量值函数就是输入一个向量(n维),函数输出一个向量(m维),即m个n元数量函数) - 黑塞矩阵可以帮助解决雅可比矩阵的近视问题(就是最值问题)
具体参考雅可比矩阵直观理解
- 代码实现
实现雅可比矩阵和黑塞矩阵
#-*- coding :utf-8 -*-
import sympy
m,n,i,j = sympy.symbols("m n i j")#设置变量符号
m = i**4 - 2*j**3 -1
n = j-i*j**2+5
func = sympy.Matrix([m,n])#矩阵的维度m,n
args = sympy.Matrix([i,j])#对于i,j来求解
res = func.jacobian(args)#调用雅可比矩阵求解,仅仅返回的是雅可比矩阵的形状
print(res)
#-*- coding:utf-8 -*-
import theano
from theano import function,config,shared,sandbox
import theano.tensor as T
#计算雅可比
x = T.dvector('x')#x作为向量,注意x是向量,可以理解成一维矩阵
y = x**3 + x**4
#利用scan构建循环Graph
J,updates = theano.scan(lambda i,y,x:T.grad(y[i],x),sequences=T.arange(y.shape[0]),non_sequences=[y,x])
#scan函数按照循环函数T.grad(y[i],x)来进行循环,arange函数来判定y的行数,假设y为4行,arange是[0,1,2,3],后面又写到non_sequences是y和x,这又证明不变量是y和x
f1 = function([x],J,updates=updates)
print("f1=",f1[5,5])
四、积分
- 不定积分
- 定积分
五、总结和反思
对于机器学习的微积分知识进行了总结,主要联系了凸优化方面,要想更系统的了解,更需要对凸优化方面进行学习,一步一步来,加油!!!