qr分解求线性方程组_梯度下降求解线性方程组算例设计

74a729a8b2af765ea71f7461b037e35b.png

凸二次优化问题

Theory.

是实对称正定矩阵,
,则求解凸二次优化问题

等价于求解线性方程组

Proof. 二次型二阶可导,极小值点处梯度为零,现对优化的目标函数求梯度。二次型本质上具有:

计算梯度的分量表达式:

合在一起写成矩阵形式:

显然,凸二次优化问题的极值条件等价于该线性方程组。凸二次优化问题在建模中十分常见,这说明讨论线性方程组的求解方法具有普遍的实用价值。然而对于规模较大的问题,使用线性代数中的克莱姆法则暴力展开将导致时间开销巨大,而高斯消元法算法流程又较为复杂。本文将介绍一种常见的数值分析方法,求得线性方程组的数值近似解。

最速梯度下降法

称优化目标函数的梯度为残量(Residue),即是当前解对于线性方程组的不满足量:

由于函数是凸函数,极值点一定存在。当前解处函数的梯度值表示了函数值上升最快的方向(梯度方向上方向导数最大)。那么沿着相反的方向每迭代一步就会更加靠近最优的极小值解。于是,我们定义迭代关系:

其中

表示迭代第
轮的解,
表示每轮迭代的步长,即每一步下降多少的权重。之所以需要设计一个与
相关的步长,是因为随着迭代的进行,梯度是变化的。越靠近驻点的梯度将会越小,直到接近于0时收敛。同时还要考虑在接近于驻点时应该放缓步伐,否则会出现梯度在正负之间频繁震荡,解在最优解左右摇摆的情况。

在最速下降法中,将

作为自变量代入原函数,并看作
的函数,对其进行最小化:

同样的,驻点处梯度为零。根据链式求导法则:

最后一步由于

是正定矩阵,所以分母也是一个正定二次型,值不为零,可以直接除过来。由此,我们最终得到了解的迭代关系:

算例设计与实验

参考南科大的数值分析作业题EH计算设计SUSTech的算例一(由于版权关系无传送门)

生成实对称正定矩阵 采用文献[1]中的类似方法生成矩阵

其中

分别为Householder矩阵和对角矩阵:

Householder矩阵是对称正交矩阵,这时,对角矩阵的特征值就是

的特征值,参考矩阵的正交分解。取:

推导条件数计算公式 矩阵

的最大特征值和最小特征值分别为:

那么其特征值介于

之间,对称正定矩阵的条件数公式为

于是可以反解处条件数的计算公式:

为了能够重复试验数据,使用线性同余法计算伪随机数进行向量的初始化(也可以使用相同的随机种子,调用编程语言内部的随机值库,这里尊重南科大的原题要求)。令xopt表示最优解

,x0表示解的初始向量
。伪随机数算法参数给定如下面MATLAB程序所示:
v = zeros(n, 1); xopt = zeros(n, 1); x0 = zeros(n, 1);
t = 0; for j = 1: n t = mod(t * 31416 + 13846, 46261); v(j) = t * (2 / 46261) - 1; end;
t = 0; for j = 1: n t = mod(t * 42108 + 13846, 46273); xopt(j) = t * (5 / 46273) + 5; end;for j = 1: n t = mod(t * 42108 + 13846, 46273); x0(j) = t * (5 / 46273) - 10; end;

这里设定最优解的分量在

之间,不为零的初始向量分量在
之间。根据以上公式可以根据向量
得到矩阵
的值,其后使用
计算得到向量
的值。这时将
作为问题的给定参数,x0作为初始向量,使用梯度下降的方式计算xk,并计算它与最优解的真值之间的相对误差:

这里设定算法的停机标准为当前梯度变为接近于零的极小量:

Python程序代码

import numpy as npdef initialize(cond, numb):gamma = (np.cos(np.pi / (numb + 1)) + cond * np.cos(numb * np.pi / (numb + 1)) - (cond - 1)) / (cond - 1)diags = np.array(list(map(lambda i: np.cos(i * np.pi / (numb + 1)) + 1 + gamma, np.arange(1, numb + 1))))SIGMA = np.diag(diags)v = np.zeros((numb, 1))xopt = np.zeros((numb, 1))x0 = np.zeros((numb, 1))t = 0for j in range(numb):t = (t * 31416 + 13846) % 46261v[j] = t * (2 / 46261) - 1t = 0for j in range(numb):t = (t * 42108 + 13846) % 46273xopt[j] = t * (5 / 46273) + 5for j in range(numb):t = (t * 42108 + 13846) % 46273x0[j] = t * (5 / 46273) - 10V = np.identity(numb) - 2 * v @ v.T / np.linalg.norm(v) ** 2A = V @ SIGMA @ V.Tb = A @ xoptreturn A, b, xopt, x0def gradientDescent(A, b, x0, epsilon):x_now = x0; epoch = 0gnorm = ginit = np.linalg.norm(A @ x0 - b)while gnorm / ginit > epsilon:g_now = A @ x_now - bgnorm = np.linalg.norm(g_now)xnext = x_now - (gnorm ** 2) / (g_now.T @ A @ g_now) * g_now # * LR_linearDecay(epoch)x_now = xnextepoch += 1return epoch, x_nowdef LR_linearDecay(epoch):return - epoch / 5e4 + 0.9def LR_expertDecay(epoch):return np.exp(- np.log(0.9) * (epoch / 4e3 - 1))if __name__ == '__main__':print("{:>8}".format("EPOCH/ERR"), end="  ")for n in range(1, 6):print("n={:>9}".format(100*n), end="  ")print()for c in range(3, 7):print(f"COND=1e+{c}", end=" ")for n in range(1, 6):A, b, xopt, x0 = initialize(cond=10**c, numb=100*n)epoch, xk = gradientDescent(A, b, x0, epsilon=1e-6)error = np.linalg.norm(xk - xopt) / np.linalg.norm(x0 - xopt)print("{:>5}/{:.4f}".format(epoch, error), end=" ")print()

MATLAB程序代码

Linear_init.m

function [A, b, xopt, x0] = linear_init(cond, numb)gamma = (cos(pi / (numb + 1)) ...+ cond * cos(numb * pi / (numb + 1)) - (cond - 1)) / (cond - 1);diags = zeros(numb, 1);for i = 1: numb;diags(i) = cos(i * pi / (numb + 1)) + 1 + gamma;end;SIGMA = diag(diags);v = zeros(numb, 1); xopt = zeros(numb, 1); x0 = zeros(numb, 1);t1 = 0; t2 = 0;for j = 1: numbt1 = mod(t1 * 31416 + 13846, 46261); v(j) = t1 * (2 / 46261) - 1; end;   for j = 1: numbt2 = mod(t2 * 42108 + 13846, 46273); xopt(j) = t2 * (5 / 46273) + 5; end;for j = 1: numbt2 = mod(t2 * 42108 + 13846, 46273); x0(j) = t2 * (5 / 46273) - 10; end;V = eye(numb) - 2 * (v * v') / norm(v, 2)^2;A = V * SIGMA * V';b = A * xopt;
end

Linear_solu.m

function [epoch, x_now] = linear_solu(A, b, x0, epsilon)x_now = x0; epoch = 0;gnorm = norm(A * x0 - b, 2);ginit = gnorm;while gnorm / ginit > epsilong_now = A * x_now - b;gnorm = norm(g_now, 2);xnext = x_now - (gnorm^2) / (g_now' * A * g_now) * g_now;x_now = xnext;epoch = epoch + 1;end;
end

Linear_impr.m

function [epoch, x_now] = linear_impr(A, b, x0, epsilon)lr = @(epoch) - epoch / 5e4 + 0.9;x_now = x0; epoch = 0;gnorm = norm(A * x0 - b, 2);ginit = gnorm;while gnorm / ginit > epsilong_now = A * x_now - b;gnorm = norm(g_now, 2);xnext = x_now - lr(epoch) * (gnorm^2) / (g_now' * A * g_now) * g_now;x_now = xnext;epoch = epoch + 1;end;
end

Linear_eval.m

function linear_eval(type)
% linear_eval('normal') for normal gradient descent algorithm
% linear_eval('improv') for improved radient descent algorithmepsilon = 1e-6;fprintf('%8s  ', 'EPOCH/ERR');for n = 1: 5fprintf('      n=%3d  ', 100 * n);end;fprintf('n');for c = 3: 6fprintf('COND=1e+%d ', c);for n = 1: 5[A, b, xopt, x0] = linear_init(10^c, 100 * n);if strcmp(type, 'improv')[epoch, xk] = linear_impr(A, b, x0, epsilon);else[epoch, xk] = linear_solu(A, b, x0, epsilon);end;error = norm(xk - xopt, 2) / norm(x0 - xopt, 2);fprintf('%5d/%.4f ' , epoch, error);end;fprintf('n');end;
end

实验结果

1
EPOCH/ERR  n=      100  n=      200  n=      300  n=      400  n=      500  
COND=1e+3  3382/0.0786  8910/0.0682 14400/0.0511 15750/0.0492 15696/0.0525 
COND=1e+4  3382/0.0786  8910/0.0682 14400/0.0511 15750/0.0492 15696/0.0525 
COND=1e+5  3382/0.0786  8910/0.0682 14400/0.0511 15750/0.0492 15696/0.0525 
COND=1e+6  3382/0.0786  8910/0.0682 14400/0.0511 15750/0.0492 15696/0.0525 -epoch / 5e4 + 0.9
EPOCH/ERR  n=      100  n=      200  n=      300  n=      400  n=      500  
COND=1e+3   203/0.0786   459/0.0682   419/0.0510   588/0.0494   544/0.0536 
COND=1e+4   221/0.0786   534/0.0682   855/0.0513   538/0.0494   761/0.0535 
COND=1e+5   203/0.0786   333/0.0682   617/0.0509   538/0.0494   761/0.0535 
COND=1e+6   203/0.0786   534/0.0682   617/0.0509   588/0.0494   544/0.0536np.exp(- np.log(0.9) * (epoch / 4e3 - 1))
EPOCH/ERR  n=      100  n=      200  n=      300  n=      400  n=      500  
COND=1e+3   287/0.0786   462/0.0682   513/0.0512   579/0.0489   545/0.0535 
COND=1e+4   313/0.0786   531/0.0682   705/0.0512   617/0.0496   710/0.0528 
COND=1e+5   287/0.0786   412/0.0682   619/0.0510   617/0.0496   710/0.0528 
COND=1e+6   287/0.0786   531/0.0682   619/0.0510   579/0.0489   545/0.0535

算法变体

这里清川对原始算法做了一些小改进,在

前面加上了一个人为设定的二次权重值
。实验结果中每部分的第一行代表了
的取值方式,表中斜线前面代表停机时的总迭代次数,后面代表相对误差。可以看出,在保持解的精度不变的前提下,加上人工修正的权重使得算法快了30倍。一开始清川想改进成随机梯度下降,但显然他理解错了,SGD算法的随机指的是神经网络训练时每轮迭代选取随机的样本,和这里没有什么关系。但是清川从SGD中采纳了指数衰减和线性衰减的方法,并加以调参就得到了改进。

这个改进并不能让人喜悦,显然它是在当前数据(矩阵A与b的值)下过拟合的。对于新的数据,该算法未必能够加速。但是这说明了另一个问题:最速下降法并不是最速的

这是因为这里选取的欧式范数(

分子上的二范数)并不一定是最合适的衡量标准。每轮迭代总是假设梯度在当前迭代时是近似不变的,以初始位置的梯度模拟整个步长上的梯度,这样并不准确。而清川加了人工调参的二次权重后更好地模拟了梯度的变化,所以更快。如果想进一步实验这一点,可以将
直接用
替换,去调参,预计仍然能得到一个很好的收敛速度。做实验前最好对
进行归一化,否则调参过程中可能出现数值溢出。关于最速下降法不总是最速的这个结论,也可以参考梯度下降法和最速下降法区别。注意本文并未对这两个概念作区分。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/435079.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

dem聚类只能成为一类

将各个图层分类后在进行聚类

VMware下桥接设置

操作环境 主机:Win7 X86 SP1 虚拟机:VMware station 8 虚拟机里的系统:Fedora 15 环境上,不管什么系统,什么版本的虚拟机,使用上都是大同小异的,毕竟核心是不变的。 VM虚拟机下linux系统&am…

分享21个丰富多彩的 HTML5 小游戏

作为下一代的网页语言,HTML5 拥有很多让人期待已久的新特性。HTML5 的优势之一在于能够实现跨平台游戏编码移植,现在已经有很多公司在移动设备上使用 HTML5 技术。随着 HTML5 跨平台支持的不断增强和智能手机的迅速普,HTML5 技术有着非常好的…

python白森_氧气恋人

江白森002.发布于2019-07-18 13:37再次见到江白森的时候是三天后,也就是军训的第二天。晚间的时候,以小组为单位举行篝火晚会。修辞坐在树枝堆前,看着堆积的树枝霎时间被点燃,火光一瞬间炸裂,越来越旺。树堆那边的人像…

我算是优秀的程序员吗?

介绍我已经工作5年之久,但我还纠结于是不是优秀的程序员,怎样做优秀的程序员这些问题当中。心态我经常问自己,我算是优秀的程序员吗?有的时候我觉得自己是优秀的程序员,什么时候呢?当我解决问题的时候&…

quick time不可用是什么意思_fpga是什么意思(fpga怎么用)

1、不熟悉 FPGA的内部结构,不了解可编程逻辑器件的基本原理。FPGA为什么是可以编程的?恐怕很多菜鸟不知道,他们也不想知道。因为他们觉得这是无关紧要的。 他们潜意识的认为可编程嘛,肯定就是像写软件一样啦。软件编程的思想根深蒂固&#x…

ArcGIS斜坡单元工具箱

目前全国开始了地质灾害风险调查评价,其中斜坡单元在地质灾害风险调查中有着非常重要的地位,斜坡单元是野外调查的前提,斜坡单元划分的好坏对野外调查也有一定的影响。所以你需要相关技术人员对数据进行处理,并且技术人员在按以下…

与老大的交谈——估算项目时间

介绍上一次我们聊到 估算项目的时间进度! ,感谢很多博友的建议。我也向我们老大咨询了一下,他给了我很多宝贵的意见。以下是我跟老大的一些交谈,希望对大家有所帮助。把握三个点以下是老大给我的建议,大家可以考虑一下。这三个点中…

VS2008 只生成DLL不生成lib文件

对于VS2008的Win32工程只生成DLL文件而不生成lib文件 添加Module-Definition File.def文件 注意:需要添加新文件,如果选择 Add Existing Item不能解决问题转载于:https://www.cnblogs.com/SunChina/archive/2011/05/16/2047492.html

八皇后问题python_python八皇后问题的解决方法

本文为大家分享了python八皇后问题的解决方法,供大家参考,具体内容如下题目:给定一个 N*N 正方形棋盘,在上面放置 N个棋子,又叫皇后,使每两个棋子都不在同一条横线上、竖线上、斜线上。一般我们都讨论8皇后…

arcgis中的python字符串比较

字段类型为字符串 jj为int类型 在使用python的ifelse时对字符串进行比较时并赋值,输出结果全部为1 正确代码如下 # -*- coding: utf-8 -*- z0 def a(td):tdtd.encode(utf-8);global zif(td低风险):z1elif(td中风险):z2elif(td高风险):z3elif(td极高风险):z4else…

禅道——需要我们斟酌

一则故事一个苦者对和尚说:“我放不下一些事,放不下一些人。” 和尚说:“没有什么东西是放不下的。”他说:“可我就偏偏放不下。”和尚让他拿着一个茶杯,然后就往里面倒热水,一直倒到水溢出来。苦者被烫到马…

【转】“线程间操作无效: 从不是创建控件的线程访问它”

经典解决“线程间操作无效: 从不是创建控件的线程访问它”在编程中经常会遇到在一个按钮中执行复杂操作,并将复杂操作最后返回的值加入一个ListView或ComboBox中候选。这个时候程序会卡,当程序员将这些卡代码放进线程(Thread)中后发现当对控件操作时出现…

python正则判断_Python 正则表达式

一、基础语法1.1 语法速查1.2 最简单的正则匹配学习正则一般是从 match 和 search 函数开始,推荐教程。matchmatch(pattern, string) 函数会从字符串的头部开始搜索,如果匹配到了 pattern 则将其结果存入 group 中,匹配到了几次就存入几次&am…

arcgis中字段计算器利用python比较大小

# -*- coding: utf-8 -*- z0 def numbersize(a,b):global zif(a>b):zaelif(a<b):zbelif(ab):zaelse:z99return z

程序员到底怎么了?

程序员到底怎么了&#xff0c;我们当然不否认有很多出色的程序员&#xff0c;他们生活的好&#xff0c;赚的也多&#xff0c;可是毕竟大多数都还是一般水平&#xff0c;很多还是挣扎在基本满足吃住的水平。特别深的问题&#xff0c;比如国家社会问题&#xff08;总有人会说我们…

python读取单波段影像dem

from osgeo import gdal import matplotlib.pyplot as plt ds gdal.Open(r"。。。\DEM1.tif") im_width ds.RasterXSize im_height ds.RasterYSize im_data ds.ReadAsArray(0, 0, im_width, im_height) plt.figure(figsize(20,18)) plt.imshow(im_data) plt.show…

qt int转换成qstring_「QT界面编程实例」创建颜色下拉框并改变窗体颜色(调色板)...

【实例】Qt创建窗体下拉框并改变窗体颜色&#xff1a;QPalette、QColor、QPixmap、QSize、QIcon、QStringList、QString本例是想创建一个颜色下拉框(颜色是自动从QColor中添加的)&#xff0c;当选择某个颜色时&#xff0c;改变对应窗体(控件)的颜色(背景色、字体颜色等)。主要函…

持久化雪花视图实例学习

【实例学习】在实践Pdf版书中P52的例子中&#xff0c;继续学习&#xff1a;NSMutableArray类The NSMutableArray class declares the programmatic interface to objects that manage a modifiable array of objects. This class adds insertion and deletion operations to th…