SymPy 是一个用于符号型数学计算的 Python 库,它的目标是成为一个功能齐全的计算机代数系统 (CAS),同时保持代码尽可能简单,以便易于理解和扩展。
SymPy 可以进行数学表达式的符号计算、代数运算、微积分、方程求解、矩阵运算、绘图等多种功能。
我们先来使用 SymPy 计算 Sigmoid 函数。也就是根据
这篇
中的公式计算如下微分方程,
使用 SymPy 只需要数行就能搞定。
from sympy import *
# 定义符号
t = symbols('t')
f = symbols('f', cls=Function)
# 定义微分方程
eq = Eq(f(t).diff(t), f(t)*(1-f(t)))
# 求解带初始条件的微分方程
f_sol = dsolve(eq, ics={f(0): 1/2})
print(f_sol)
# 绘制微分方程的解
plot(f_sol.rhs, (t, -10, 10))
Eq(f(t), 1/(1 + 1.0*exp(-t)))
以上代码中我们取
。
怎么样,是不是很好用。其实你也可以改动微分方程来设计自己的激活函数。
好了,演示完毕,进入正题。
微积分运算
SymPy 提供了一些常见的微积分运算函数,例如:
-
diff
函数可以对符号表达式进行求导,也可以求偏导数和高阶导数。
-
integrate
函数可以对符号表达式进行积分,也可以求定积分和多重积分。
-
limit
函数可以计算符号表达式的极限,也可以求一侧极限和无穷极限。
-
solve
函数可以解决符号方程,也可以求解微分方程和方程组。
要使用 SymPy,需要先安装并导入它,然后使用 symbols 函数创建符号变量,例如:
from sympy import *
x, y = symbols('x y')
然后你就可以对符号变量进行各种运算,例如:
展开 (x + 1)^2
expand((x + 1)**2)
# 输出 x*2 + 2x + 1
求导 sin(x)
diff(sin(x), x)
# 输出 cos(x)
求二阶导
f = x*2 + 2x + 1
# 二阶导数
ddf = diff(f, x, 2)
ddf
# 输出 2
求极限 lim(x->0) sin(x)/x
limit(sin(x)/x, x, 0)
# 输出 1
求积分 int(x^2, x)
integrate(x**2
, x)
# 输出 x**3/3
SymPy 还可以将数学表达式转换为 LaTeX 代码,方便在文档中显示,例如:
# 将 x^2 + 2*x + 1 转换为 LaTeX 代码
latex(x*2 + 2x + 1)
'x^{2} + 2 x + 1'
SymPy 支持的数学函数
SymPy 支持多种数学函数,包括:
-
常用的标准函数,如三角函数、指数函数、对数函数、绝对值函数等。
-
特殊的数学函数,如
函数、Bessel 函数、误差函数、超几何函数等。
-
你可以使用
Function
类来创建自定义函数,也可以使用
symbols
函数来指定某个符号为函数类型。例如:
# 使用 Function 类创建自定义函数
f = Function('f')
f(x)
# 使用 symbols 函数指定 g 为函数类型
g = symbols('g', cls=Function)
g(x)
SymPy 支持的数学常量
SymPy 支持多种数学常量,例如:
-
-
-
-
oo
:正无穷大,满足
oo > x
对任意有限的 x 成立。
-
zoo
:复数无穷大,满足
zoo + x = zoo
对任意有限的 x 成立。
-
-
GoldenRatio
:黄金比例,约等于 1.61803。
-
EulerGamma
:欧拉常数,约等于 0.57722。
-
Catalan
:卡塔兰常数,约等于 0.91597。
可以使用这些常量来构建数学表达式或函数,例如:
# 计算 sin(pi/4)
sin(pi/4)
# 输出 sqrt(2)/2
# 计算 e^i*pi
E*(Ipi)
# 输出 -1
# 计算 limit((1 + 1/n)**n, n, oo)
n = symbols('n')
limit((1 + 1/n)**n, n, oo)
# 输出 E
SymPy 求导应用
SymPy 可以用来求解神经网络里的反向传播问题,即根据损失函数对网络参数进行梯度下降更新。
例如,以下代码将构建一个简单的神经网络,包含一个输入层、一个隐藏层和一个输出层,使用 sigmoid 激活函数和均方误差损失函数,然后对网络参数进行反向传播更新:
from sympy import *
# 定义符号变量
x, y = symbols('x y') # 输入和输出
w1, w2, b1, b2 = symbols('w1 w2 b1 b2') # 权重和偏置
alpha = symbols('alpha') # 学习率
# 定义神经网络
z1 = w1 * x + b1 # 隐藏层的线性部分
a1 = 1 / (1 + exp(-z1)) # 隐藏层的激活部分,使用 sigmoid 函数
z2 = w2 * a1 + b2 # 输出层的线性部分
a2 = 1 / (1 + exp(-z2)) # 输出层的激活部分,使用 sigmoid 函数
# 定义损失函数
L = (y - a2)**2 / 2 # 使用均方误差作为损失函数
# 对网络参数求偏导数
dLdw1 = diff(L, w1) # 损失函数对 w1 的偏导数
dLdw2 = diff(L, w2) # 损失函数对 w2 的偏导数
dLdb1 = diff(L, b1) # 损失函数对 b1 的偏导数
dLdb2 = diff(L, b2) # 损失函数对 b2 的偏导数
# 更新网络参数
w1_new = w1 - alpha * dLdw1 # 使用梯度下降法更新 w1
w2_new = w2 - alpha * dLdw2 # 使用梯度下降法更新 w2
b1_new = b1 - alpha * dLdb1 # 使用梯度下降法更新 b1
b2_new = b2 - alpha * dLdb2 # 使用梯度下降法更新 b2
# 打印更新后的网络参数
print(w1_new)
print(w2_new)
print(b1_new)
print(b2_new)
SymPy 中的微分方程求解
SymPy 提供了一个通用的微分方程求解工具
dsolve
,它能够找到许多基本微分方程的解析解。
dsolve
可以用来符号化地求解一阶和高阶微分方程,以及具有较少未知函数的一阶线性常微分方程组。
要使用
dsolve
,需要遵循以下基本步骤:
-
定义符号变量:首先,你需要定义用于表示未知函数和变量的符号。在 SymPy 中,可以使用
Symbol
或
symbols
函数来定义符号变量。例如,可以使用
x = symbols('x')
来定义一个名为 x 的符号变量。
-
定义微分方程:其次,你需要将微分方程表示为符号表达式。在 SymPy 中,可以使用
Eq
函数来表示等式,使用
Derivative
函数来表示导数。例如,可以使用
eq = Eq(Derivative(f(x), x) + f(x), x**2)
来表示如下微分方程
-
求解微分方程:一旦你定义了微分方程,就可以使用
dsolve
函数来求解微分方程。该函数将返回一个表示微分方程的解的符号表达式。例如,可以使用
solution = dsolve(eq, f(x))
来求解上述微分方程的解。
-
带初始条件:对于一般的微分方程,解中通常包含一些常数,如
等。为了获得特定的解,你需要为方程提供初始条件。在 SymPy 中,可以使用
ics
参数来指定初始条件。例如,可以使用
solution = dsolve(eq, f(x), ics={f(0): 3})
来求解上述微分方程在初始条件
下的解。
-
计算特定解:最后,你可以使用
subs
函数将初始条件代入所获得的一般解中,得到特定的解。例如,可以使用
solution.subs(x, 0)
来计算上述微分方程的解在
时的值。
x = symbols('x')
eq = Eq(Derivative(f(x), x) + f(x), x**2)
solution = dsolve(eq, f(x))
solution
solution_ics = dsolve(eq, f(x), ics={f(0): 3})
solution_ics
solution_ics.subs(x, 0)
SymPy 的绘图功能
SymPy 提供了一个简单而强大的绘图模块,可以绘制各种类型的二维和三维图形。
SymPy 使用 Matplotlib 作为绘图后端,因此你需要安装 Matplotlib 才能使用 SymPy 的绘图功能。
SymPy 的绘图模块包含了以下几种主要的绘图函数:
-
plot
:绘制二维线状图,可以绘制一个或多个符号表达式或函数。
-
plot_parametric
:绘制二维参数图,可以绘制一个或多个参数化的曲线。
-
plot_implicit
:绘制二维隐式图或区域图,可以绘制一个或多个隐式方程或不等式。
-
plot3d
:绘制三维线状图,可以绘制一个或多个符号表达式或函数。
-
plot3d_parametric_line
:绘制三维参数线图,可以绘制一个参数化的空间曲线。
-
plot3d_parametric_surface
:绘制三维参数曲面图,可以绘制一个参数化的曲面。
要使用 SymPy 的绘图功能,你需要遵循以下基本步骤:
-
导入绘图模块:首先,从 SymPy 中导入绘图模块,例如
from sympy.plotting import plot
。
-
定义符号变量:其次,定义用于表示未知函数和变量的符号。在 SymPy 中,可以使用
Symbol
或
symbols
函数来定义符号变量,例如
x = symbols('x')
。
-
调用绘图函数:最后,根据需求调用相应的绘图函数,传入符号表达式或函数,以及可选的范围和参数,例如
plot(x**2, (x, -5, 5), title='y = x^2')
。
下面是一些使用 SymPy 绘图功能的示例:
绘制二维线状图
要绘制二维线状图,可以使用
plot
函数,传入一个或多个符号表达式或函数,以及可选的范围和参数。例如,以下代码将绘制
和