
正文
python未知函数梯度 python如何求未知数
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
OpenCV-Python系列四:图像分割(2)--梯度
上一期提到的图像阈值处理,不仅可以实现获取你想要的目标区域(作为mask使用),还可以帮你获取图像的边缘信息,那关于图像边缘,本期将从另外的角度来处理。
对边缘信息与背景差异较大的场景,你也可以使用threshold分割,不过若阈值不好选取,Laplacian梯度算子就不失为一直尝试方案,而且上网看看,关于Laplacian算子还可以用来判断图像的模糊程度,这个在相机的自动对焦当中,是否可以尝试判断下?
不过处理的效果并不理想,图像低灰阶部分边缘信息丢失严重。
对于sobel,laplacian算子我们可以使用cv2.filter2D()来实现,配置相应的核模板即可,如实现提取水平方向边缘信息:
你可以依据实际的应用需求来配置提取边缘的角度信息,这里以45度角(垂直向下逆时针旋转45度)为例:
对此,你可以采用下面的方式来解决:
相关问答
Q1: python数据分析与应用第三章代码3-5的数据哪来的
savetxt
import numpy as np
i2 = np.eye(2)
np.savetxt("eye.txt", i2)
3.4 读入CSV文件
# AAPL,28-01-2011, ,344.17,344.4,333.53,336.1,21144800
c,v=np.loadtxt('data.csv', delimiter=',', usecols=(6,7), unpack=True) #index从0开始
3.6.1 算术平均值
np.mean(c) = np.average(c)
3.6.2 加权平均值
t = np.arange(len(c))
np.average(c, weights=t)
3.8 极值
np.min(c)
np.max(c)
np.ptp(c) 最大值与最小值的差值
3.10 统计分析
np.median(c) 中位数
np.msort(c) 升序排序
np.var(c) 方差
3.12 分析股票收益率
np.diff(c) 可以返回一个由相邻数组元素的差
值构成的数组
returns = np.diff( arr ) / arr[ : -1] #diff返回的数组比收盘价数组少一个元素
np.std(c) 标准差
对数收益率
logreturns = np.diff( np.log(c) ) #应检查输入数组以确保其不含有零和负数
where 可以根据指定的条件返回所有满足条件的数
组元素的索引值。
posretindices = np.where(returns 0)
np.sqrt(1./252.) 平方根,浮点数
3.14 分析日期数据
# AAPL,28-01-2011, ,344.17,344.4,333.53,336.1,21144800
dates, close=np.loadtxt('data.csv', delimiter=',', usecols=(1,6), converters={1:datestr2num}, unpack=True)
print "Dates =", dates
def datestr2num(s):
return datetime.datetime.strptime(s, "%d-%m-%Y").date().weekday()
# 星期一 0
# 星期二 1
# 星期三 2
# 星期四 3
# 星期五 4
# 星期六 5
# 星期日 6
#output
Dates = [ 4. 0. 1. 2. 3. 4. 0. 1. 2. 3. 4. 0. 1. 2. 3. 4. 1. 2. 4. 0. 1. 2. 3. 4. 0.
1. 2. 3. 4.]
averages = np.zeros(5)
for i in range(5):
indices = np.where(dates == i)
prices = np.take(close, indices) #按数组的元素运算,产生一个数组作为输出。
a = [4, 3, 5, 7, 6, 8]
indices = [0, 1, 4]
np.take(a, indices)
array([4, 3, 6])
np.argmax(c) #返回的是数组中最大元素的索引值
np.argmin(c)
3.16 汇总数据
# AAPL,28-01-2011, ,344.17,344.4,333.53,336.1,21144800
#得到第一个星期一和最后一个星期五
first_monday = np.ravel(np.where(dates == 0))[0]
last_friday = np.ravel(np.where(dates == 4))[-1]
#创建一个数组,用于存储三周内每一天的索引值
weeks_indices = np.arange(first_monday, last_friday + 1)
#按照每个子数组5个元素,用split函数切分数组
weeks_indices = np.split(weeks_indices, 5)
#output
[array([1, 2, 3, 4, 5]), array([ 6, 7, 8, 9, 10]), array([11,12, 13, 14, 15])]
weeksummary = np.apply_along_axis(summarize, 1, weeks_indices,open, high, low, close)
def summarize(a, o, h, l, c): #open, high, low, close
monday_open = o[a[0]]
week_high = np.max( np.take(h, a) )
week_low = np.min( np.take(l, a) )
friday_close = c[a[-1]]
return("APPL", monday_open, week_high, week_low, friday_close)
np.savetxt("weeksummary.csv", weeksummary, delimiter=",", fmt="%s") #指定了文件名、需要保存的数组名、分隔符(在这个例子中为英文标点逗号)以及存储浮点数的格式。
0818b9ca8b590ca3270a3433284dd417.png
格式字符串以一个百分号开始。接下来是一个可选的标志字符:-表示结果左对齐,0表示左端补0,+表示输出符号(正号+或负号-)。第三部分为可选的输出宽度参数,表示输出的最小位数。第四部分是精度格式符,以”.”开头,后面跟一个表示精度的整数。最后是一个类型指定字符,在例子中指定为字符串类型。
numpy.apply_along_axis(func1d, axis, arr, *args, **kwargs)
def my_func(a):
... """Average first and last element of a 1-D array"""
... return (a[0] + a[-1]) * 0.5
b = np.array([[1,2,3], [4,5,6], [7,8,9]])
np.apply_along_axis(my_func, 0, b) #沿着X轴运动,取列切片
array([ 4., 5., 6.])
np.apply_along_axis(my_func, 1, b) #沿着y轴运动,取行切片
array([ 2., 5., 8.])
b = np.array([[8,1,7], [4,3,9], [5,2,6]])
np.apply_along_axis(sorted, 1, b)
array([[1, 7, 8],
[3, 4, 9],
[2, 5, 6]])
3.20 计算简单移动平均线
(1) 使用ones函数创建一个长度为N的元素均初始化为1的数组,然后对整个数组除以N,即可得到权重。如下所示:
N = int(sys.argv[1])
weights = np.ones(N) / N
print "Weights", weights
在N = 5时,输出结果如下:
Weights [ 0.2 0.2 0.2 0.2 0.2] #权重相等
(2) 使用这些权重值,调用convolve函数:
c = np.loadtxt('data.csv', delimiter=',', usecols=(6,),unpack=True)
sma = np.convolve(weights, c)[N-1:-N+1] #卷积是分析数学中一种重要的运算,定义为一个函数与经过翻转和平移的另一个函数的乘积的积分。
t = np.arange(N - 1, len(c)) #作图
plot(t, c[N-1:], lw=1.0)
plot(t, sma, lw=2.0)
show()
3.22 计算指数移动平均线
指数移动平均线(exponential moving average)。指数移动平均线使用的权重是指数衰减的。对历史上的数据点赋予的权重以指数速度减小,但永远不会到达0。
x = np.arange(5)
print "Exp", np.exp(x)
#output
Exp [ 1. 2.71828183 7.3890561 20.08553692 54.59815003]
Linspace 返回一个元素值在指定的范围内均匀分布的数组。
print "Linspace", np.linspace(-1, 0, 5) #起始值、终止值、可选的元素个数
#output
Linspace [-1. -0.75 -0.5 -0.25 0. ]
(1)权重计算
N = int(sys.argv[1])
weights = np.exp(np.linspace(-1. , 0. , N))
(2)权重归一化处理
weights /= weights.sum()
print "Weights", weights
#output
Weights [ 0.11405072 0.14644403 0.18803785 0.24144538 0.31002201]
(3)计算及作图
c = np.loadtxt('data.csv', delimiter=',', usecols=(6,),unpack=True)
ema = np.convolve(weights, c)[N-1:-N+1]
t = np.arange(N - 1, len(c))
plot(t, c[N-1:], lw=1.0)
plot(t, ema, lw=2.0)
show()
3.26 用线性模型预测价格
(x, residuals, rank, s) = np.linalg.lstsq(A, b) #系数向量x、一个残差数组、A的秩以及A的奇异值
print x, residuals, rank, s
#计算下一个预测值
print np.dot(b, x)
3.28 绘制趋势线
x = np.arange(6)
x = x.reshape((2, 3))
x
array([[0, 1, 2], [3, 4, 5]])
np.ones_like(x) #用1填充数组
array([[1, 1, 1], [1, 1, 1]])
类似函数
zeros_like
empty_like
zeros
ones
empty
3.30 数组的修剪和压缩
a = np.arange(5)
print "a =", a
print "Clipped", a.clip(1, 2) #将所有比给定最大值还大的元素全部设为给定的最大值,而所有比给定最小值还小的元素全部设为给定的最小值
#output
a = [0 1 2 3 4]
Clipped [1 1 2 2 2]
a = np.arange(4)
print a
print "Compressed", a.compress(a 2) #返回一个根据给定条件筛选后的数组
#output
[0 1 2 3]
Compressed [3]
b = np.arange(1, 9)
print "b =", b
print "Factorial", b.prod() #输出数组元素阶乘结果
#output
b = [1 2 3 4 5 6 7 8]
Factorial 40320
print "Factorials", b.cumprod()
#output
Q2: python如何实现求函数的在一个连续区间的最值?
如果函数是确定的,可以用导数的方法进行计算,但是如果函数是不确定的,就需要用优化的方法来处理了,比如常用的梯度上升法,模拟退火等,希望可以帮到你。
Q3: 如何使用python计算常微分方程?
常用形式
odeint(func, y0, t,args,Dfun)
一般这种形式就够用了。
下面是官方的例子,求解的是
D(D(y1))-t*y1=0
为了方便,采取D=d/dt。如果我们令初值
y1(0) = 1.0/3**(2.0/3.0)/gamma(2.0/3.0)
D(y1)(0) = -1.0/3**(1.0/3.0)/gamma(1.0/3.0)
这个微分方程的解y1=airy(t)。
令D(y1)=y0,就有这个常微分方程组。
D(y0)=t*y1
D(y1)=y0
Python求解该微分方程。
from scipy.integrate import odeint
from scipy.special import gamma, airy
y1_0 = 1.0/3**(2.0/3.0)/gamma(2.0/3.0)
y0_0 = -1.0/3**(1.0/3.0)/gamma(1.0/3.0)
y0 = [y0_0, y1_0]
def func(y, t):
... return [t*y[1],y[0]]
def gradient(y,t):
... return [[0,t],[1,0]]
x = arange(0,4.0, 0.01)
t = x
ychk = airy(x)[0]
y = odeint(func, y0, t)
y2 = odeint(func, y0, t, Dfun=gradient)
print ychk[:36:6]
[ 0.355028 0.339511 0.324068 0.308763 0.293658 0.278806]
print y[:36:6,1]
[ 0.355028 0.339511 0.324067 0.308763 0.293658 0.278806]
print y2[:36:6,1]
[ 0.355028 0.339511 0.324067 0.308763 0.293658 0.278806]
得到的解与精确值相比,误差相当小。
=======================================================================================================
args是额外的参数。
用法请参看下面的例子。这是一个洛仑兹曲线的求解,并且用matplotlib绘出空间曲线图。(来自《python科学计算》)
from scipy.integrate import odeint
import numpy as np
def lorenz(w, t, p, r, b):
# 给出位置矢量w,和三个参数p, r, b 计算出
# dx/dt, dy/dt, dz/dt 的值
x, y, z = w
# 直接与lorenz 的计算公式对应
return np.array([p*(y-x), x*(r-z)-y, x*y-b*z])
t = np.arange(0, 30, 0.01) # 创建时间点
# 调用ode 对lorenz 进行求解, 用两个不同的初始值
track1 = odeint(lorenz, (0.0, 1.00, 0.0), t, args=(10.0, 28.0, 3.0))
track2 = odeint(lorenz, (0.0, 1.01, 0.0), t, args=(10.0, 28.0, 3.0))
# 绘图
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
fig = plt.figure()
ax = Axes3D(fig)
ax.plot(track1[:,0], track1[:,1], track1[:,2])
ax.plot(track2[:,0], track2[:,1], track2[:,2])
plt.show()
===========================================================================
scipy.integrate.odeint(func, y0, t, args=(), Dfun=None, col_deriv=0, full_output=0, ml=None, mu=None, rtol=None, atol=None, tcrit=None, h0=0.0, hmax=0.0, hmin=0.0, ixpr=0, mxstep=0, mxhnil=0, mxordn=12, mxords=5, printmessg=0)
计算常微分方程(组)
使用 FORTRAN库odepack中的lsoda解常微分方程。这个函数一般求解初值问题。
参数:
func : callable(y, t0, ...) 计算y在t0 处的导数。
y0 : 数组 y的初值条件(可以是矢量)
t : 数组 为求出y,这是一个时间点的序列。初值点应该是这个序列的第一个元素。
args : 元组 func的额外参数
Dfun : callable(y, t0, ...) 函数的梯度(Jacobian)。即雅可比多项式。
col_deriv : boolean. True,Dfun定义列向导数(更快),否则Dfun会定义横排导数
full_output : boolean 可选输出,如果为True 则返回一个字典,作为第二输出。
printmessg : boolean 是否打印convergence 消息。
返回: y : array, shape (len(y0), len(t))
数组,包含y值,每一个对应于时间序列中的t。初值y0 在第一排。
infodict : 字典,只有full_output == True 时,才会返回。
字典包含额为的输出信息。
键值:
‘hu’ vector of step sizes successfully used for each time step.
‘tcur’ vector with the value of t reached for each time step. (will always be at least as large as the input times).
‘tolsf’ vector of tolerance scale factors, greater than 1.0, computed when a request for too much accuracy was detected.
‘tsw’ value of t at the time of the last method switch (given for each time step)
‘nst’ cumulative number of time steps
‘nfe’ cumulative number of function evaluations for each time step
‘nje’ cumulative number of jacobian evaluations for each time step
‘nqu’ a vector of method orders for each successful step.
‘imxer’index of the component of largest magnitude in the weighted local error vector (e / ewt) on an error return, -1 otherwise.
‘lenrw’ the length of the double work array required.
‘leniw’ the length of integer work array required.
‘mused’a vector of method indicators for each successful time step: 1: adams (nonstiff), 2: bdf (stiff)
其他参数,官方网站和文档都没有明确说明。相关的资料,暂时也找不到。
Q4: 一文搞懂梯度下降&反向传播
如果把神经网络模型比作一个黑箱,把模型参数比作黑箱上面一个个小旋钮,那么根据通用近似理论(universal approximation theorem),只要黑箱上的旋钮数量足够多,而且每个旋钮都被调节到合适的位置,那这个模型就可以实现近乎任意功能(可以逼近任意的数学模型)。
显然,这些旋钮(参数)不是由人工调节的,所谓的机器学习,就是通过程序来自动调节这些参数。神经网络不仅参数众多(少则十几万,多则上亿),而且网络是由线性层和非线性层交替叠加而成,上层参数的变化会对下层的输出产生非线性的影响,因此,早期的神经网络流派一度无法往多层方向发展,因为他们找不到能用于任意多层网络的、简洁的自动调节参数的方法。
直到上世纪80年代,祖师爷辛顿发明了反向传播算法,用输出误差的均方差(就是loss值)一层一层递进地反馈到各层神经网络,用梯度下降法来调节每层网络的参数。至此,神经网络才得以开始它的深度之旅。
本文用python自己动手实现梯度下降和反向传播算法。 请点击这里 到Github上查看源码。
梯度下降法是一种将输出误差反馈到神经网络并自动调节参数的方法,它通过计算输出误差的loss值( J )对参数 W 的导数,并沿着导数的反方向来调节 W ,经过多次这样的操作,就能将输出误差减小到最小值,即曲线的最低点。
虽然Tensorflow、Pytorch这些框架都实现了自动求导的功能,但为了彻底理解参数调节的过程,还是有必要自己动手实现梯度下降和反向传播算法。我相信你和我一样,已经忘了之前学的微积分知识,因此,到可汗学院复习下 Calculus
和 Multivariable Calculus 是个不错的方法,或是拜读 这篇关于神经网络矩阵微积分的文章 。
Figure2是求导的基本公式,其中最重要的是 Chain Rule ,它通过引入中间变量,将“ y 对 x 求导”的过程转换为“ y 对中间变量 u 求导,再乘以 u 对 x 求导”,这样就将一个复杂的函数链求导简化为多个简单函数求导。
如果你不想涉及这些求导的细节,可以跳过具体的计算,领会其思想就好。
对于神经网络模型: Linear - ReLu - Linear - MSE(Loss function) 来说,反向传播就是根据链式法则对 求导,用输出误差的均方差(MSE)对模型的输出求导,并将导数传回上一层神经网络,用于它们来对 w 、 b 和 x (上上层的输出)求导,再将 x 的导数传回到它的上一层神经网络,由此将输出误差的均方差通过递进的方式反馈到各神经网络层。
对于 求导的第一步是为这个函数链引入中间变量:
接着第二步是对各中间变量求导,最后才是将这些导数乘起来。
首先,反向传播的起点是对loss function求导,即 。 :
mse_grad()之所以用unsqueeze(-1)给导数增加一个维度,是为了让导数的shape和tensor shape保持一致。
linear层的反向传播是对 求导,它也是一个函数链,也要先对中间变量求导再将所有导数相乘:
这些中间变量的导数分别是:
对向量 求导,指的是对向量所有的标量求偏导( ),即: ,这个横向量也称为y的梯度。
这里 ,是一个向量,因此, 求导,指的是y的所有标量(y_1, y_2, ..., y_n)对向量x求偏导,即:
。
这个矩阵称为雅克比矩阵,它是个对角矩阵,因为 ,因此 。
同理, 。
因此,所有中间导数相乘的结果:
lin_grad() 中的inp.g、w.g和b.g分别是求 的导数,以inp.g为例,它等于 ,且需要乘以前面各层的导数,即 outp.g @ w.t() ,之所以要用点积运算符(@)而不是标量相乘,是为了让它的导数shape和tensor shape保持一致。同理,w.g和b.g也是根据相同逻辑来计算的。
ReLu层的求导相对来说就简单多了,当输入 = 0时,导数为0,当输入 0时,导数为1。
求导运算终于结束了,接下来就是验证我们的反向传播是否正确。验证方法是将forward_backward()计算的导数和Pytorch自动微分得到的导数相比较,如果它们相近,就认为我们的反向传播算法是正确的。
首先,将计算好的参数导数保存到w1g、b1g、w2g和b2g中,再用Pytorch的自动微分来求w11、b11、w22和b22的导数。
最后,用np.allclose()来比较导数间的差异,如果有任何一个导数不相近,assert就会报错。结果证明,我们自己动手实现的算法是正确的。
反向传播是遵循链式法则的,它将前向传播的输出作为输入,输入作为输出,通过递进的方式将求导这个动作从后向前传递回各层。神经网络参数的求导需要进行矩阵微积分计算,根据这些导数的反方向来调节参数,就可以让模型的输出误差的优化到最小值。
欢迎关注和点赞,你的鼓励将是我创作的动力
Q5: python非线性规划用什么模块
python非线性规划用什么模块本文使用SciPy的optimize模块来求解非线性规划问题,结合实际例子,引入非线性规划问题的求解算法及相应函数的调用。
本文提纲一维搜索/单变量优化问题
无约束多元优化问题
非线性最小二乘问题
约束优化问题
非线性规划问题的目标函数或约束条件是非线性的。本文使用SciPy的optimize模块来求解非线性规划问题。
目标函数和约束条件是否连续光滑是非常重要的性质,这是因为如果光滑,则所有决策变量可微,多变量函数的偏导数组成的向量为梯度,梯度是指向目标函数增长最快的方向。将目标函数梯度作为搜索方向,对非线性规划问题的求解具有重要的意义。这些函数或其导数\梯度的不连续性给许多现有的非线性优化问题的求解带来了困难。在下文中,我们假设这些函数是连续且光滑的。
# Importing Modules
from scipy import optimize
import matplotlib.pyplot as plt
import numpy as np
import sympy
1、一维搜索/单变量优化问题(Univariate Optimization)
无约束非线性规划最简单的形式是一维搜索。一维搜索通常作为多维优化问题中的一部分出现,比如梯度下降法中每次最优迭代步长的估计。求解一维搜索常用的两类方法是函数逼近法和区间收缩法。其中函数逼近法是指用较简单的函数近似代替原来的函数,用近似函数的极小点来估计原函数的极小点,比如牛顿法;区间收缩法对于一个单谷函数通过迭代以不断缩小该区间的长度,当区间长度足够小时,可将该区间中的一点作为函数的极小点,比如黄金分割法。
e.g. 最小化一个单位体积的圆柱体的表面积。
r, h = sympy.symbols("r, h")
Area = 2 * sympy.pi * r**2 + 2 * sympy.pi * r * h
Volume = sympy.pi * r**2 * h
关于python未知函数梯度和python如何求未知数的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。






