国家电网网站开发图片素材宝塔面板做网站不能打开PHP显示404
国家电网网站开发图片素材,宝塔面板做网站不能打开PHP显示404,肥西县重点建设局网站,物流网站和数据库建设案例总是举拟合直线的例子实在太简单了#xff0c;这里就使用一个更加复杂一点问题模型#xff1a;双线性变换。具体来说#xff0c;假设存在两幅地图需要配置#xff0c;并且找到了各自地图上的同名点#xff0c;可以使用双线性变换模型来进行快速、初步的校正。也就是说…案例总是举拟合直线的例子实在太简单了这里就使用一个更加复杂一点问题模型双线性变换。具体来说假设存在两幅地图需要配置并且找到了各自地图上的同名点可以使用双线性变换模型来进行快速、初步的校正。也就是说一组同名点满足如下关系{x1a0x0b0y0c0x0y0d0y1a1x0b1y0c1x0y0d1其中(x0,y0)和(x1,y1)是对应的同名点也就是观测值。而a0,b0,c0,d0和a1,b1,c1,d1则是X和Y方向上的双线性变换系数也就是待定值。对于观测值来说这个函数是非线性的但是对于待定值来说这个问题模型则是线性的。这也是笔者在《最小二乘问题详解1线性最小二乘》中强调的一点最小二乘问题是线性还是非线性需要通过待定值来判断。要实现这个案例那么就需要准备一组同名点(x0,y0)可以通过随机数生成(x1,y1)则可以通过双线性变换公式加上一点噪声值来得到。另外也不需要从头实现矩阵运算的一定规模的矩阵运算库就可以实现线性方程组的求解比如这里笔者使用的Eigen。具体的案例代码实现如下#include Eigen/Dense#include random#include vectorusing namespace std;using namespace Eigen;int main() {// // 1. 设置真实参数我们想要求解的目标// Vector4d params_x_true, params_y_true;params_x_true 1.5, -0.3, 0.1, 2.0; // a0, b0, c0, d0params_y_true 0.4, 1.8, -0.05, -1.0; // a1, b1, c1, d1cout 真实参数 x: a0 params_x_true(0) , b0 params_x_true(1) , c0 params_x_true(2) , d0 params_x_true(3) endl;cout 真实参数 y: a1 params_y_true(0) , b1 params_y_true(1) , c1 params_y_true(2) , d1 params_y_true(3) endl;// // 2. 生成 N 个随机点 (x0, y0) 并计算 (x1, y1)// int N 100; // 点的数量vectordouble x0(N), y0(N), x1(N), y1(N);// 随机数生成器random_device rd; //真随机数生成器生成不可预测的随机种子mt19937 gen(rd()); //伪随机数生成器uniform_real_distributiondouble dis(-10.0, 10.0); // 均匀分布模拟观测值normal_distributiondouble noise(0.0, 0.1); // 正态分布模拟噪声for (int i 0; i N; i) {x0[i] dis(gen);y0[i] dis(gen);// 应用双线性变换double x1_true params_x_true(0) * x0[i] params_x_true(1) * y0[i] params_x_true(2) * x0[i] * y0[i] params_x_true(3);double y1_true params_y_true(0) * x0[i] params_y_true(1) * y0[i] params_y_true(2) * x0[i] * y0[i] params_y_true(3);// 添加噪声x1[i] x1_true noise(gen);y1[i] y1_true noise(gen);}// // 3. 构造设计矩阵 A 和观测向量 b// // 对于 x 方向x1 a0*x0 b0*y0 c0*x0*y0 d0MatrixXd A_x(N, 4); // N 行4 列a0, b0, c0, d0VectorXd b_x(N);// 对于 y 方向y1 a1*x0 b1*y0 c1*x0*y0 d1MatrixXd A_y(N, 4); // N 行4 列a1, b1, c1, d1VectorXd b_y(N);for (int i 0; i N; i) {A_x(i, 0) x0[i]; // a0A_x(i, 1) y0[i]; // b0A_x(i, 2) x0[i] * y0[i]; // c0A_x(i, 3) 1.0; // d0b_x(i) x1[i];A_y(i, 0) x0[i]; // a1A_y(i, 1) y0[i]; // b1A_y(i, 2) x0[i] * y0[i]; // c1A_y(i, 3) 1.0; // d1b_y(i) y1[i];}// // 4. 使用 Eigen 求解最小二乘// Vector4d theta_x A_x.colPivHouseholderQr().solve(b_x);Vector4d theta_y A_y.colPivHouseholderQr().solve(b_y);// // 5. 输出结果// cout \n--- 拟合结果 --- endl;cout 估计参数 x: a0 theta_x(0) , b0 theta_x(1) , c0 theta_x(2) , d0 theta_x(3) endl;cout 估计参数 y: a1 theta_y(0) , b1 theta_y(1) , c1 theta_y(2) , d1 theta_y(3) endl;// // 6. 验证计算残差// VectorXd residual_x b_x - A_x * theta_x;VectorXd residual_y b_y - A_y * theta_y;cout \n残差平方和 (x): residual_x.squaredNorm() endl;cout 残差平方和 (y): residual_y.squaredNorm() endl;cout 总残差平方和: (residual_x.squaredNorm() residual_y.squaredNorm()) endl;return 0;}有以下几点需要注意随机生成观测值数据的实现// 随机数生成器random_device rd; //真随机数生成器生成不可预测的随机种子mt19937 gen(rd()); //伪随机数生成器uniform_real_distributiondouble dis(-10.0, 10.0); // 均匀分布模拟观测值normal_distributiondouble noise(0.0, 0.1); // 正态分布模拟噪声中噪声的随机值不是随意生成的而要符合正态分布高斯分布。这是因为偶然误差随机误差通常符合正态分布。这里分成X方向和Y方向求解了两组线性方程组因为有两组不相关的待定系数(a0,b0,c0,d0)和(a1,b1,c1,d1)。本例使用的QR分解法求解的线性最小二乘问题如果想使用SVD也很简单可以将colPivHouseholderQr替换成如下接口Vector4d theta_x A_x.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(b_x);Vector4d theta_y A_y.bdcSvd(Eigen::ComputeThinU | Eigen::ComputeThinV).solve(b_y);最终运行结果如下真实参数 x: a01.5, b0-0.3, c00.1, d02真实参数 y: a10.4, b11.8, c1-0.05, d1-1--- 拟合结果 ---估计参数 x: a01.5006, b0-0.299571, c00.100173, d01.98956估计参数 y: a10.398688, b11.80047, c1-0.0501635, d1-0.994459残差平方和 (x): 0.745402残差平方和 (y): 0.945377总残差平方和: 1.690783. 精度3.1 引出虽然把最小二乘解求出来了不过笔者更加关心一个问题那就是求解的精度是多少如果我只需要求解一个大致的解那么随便取四组点求解出来就可以了反正不能精确求解得到结果也大差不差——其实这就是最小二乘的意义我不仅仅求解出来了还可以明确计算出求解的精度误差使得观测值与求解的符合度始终在这个误差范围之内从而实现科学上从定性到定量的质变。以这个例子来说由于是先设置的真实参数再进行仿真求解那么可以直接计算估计值与真实值的差值来确定误差。但是在真实场景中肯定是不知道真实值的那么就只能估计精度具体来说就是计算待定参数的协方差矩阵。不过要说清楚协方差矩阵不是一件容易的事情因为这个概念的背景知识是《概率论与数理统计》和《误差理论》和这两门课程的内容。大概论述一下就是协方差矩阵描述了待定参数的估值的不确定性有多大它的对角线元素是每个参数的方差开根号就是标准差而标准差越小说明估计越精确所以标准差就是“精度”的量化。3.2 协方差从头来讲可能我们大学学习的《概率论与数理统计》都忘光了但是高中数学学习的概率与统计知识应该还是记得的。假设我们使用尺子测量一根棍子的长度一共测了5次得到x[10.1,9.9,10.0,10.2,9.8]cm那么平均值估计值是¯x15∑xi10.0cm这个值就是棍子“真实长度”的最佳估计那么方差不确定性是s21n−1∑(xi−¯x)20.025标准差精度则是s√0.025≈0.158cm那么可以这样评估精度“长度是10.0±0.16cm”。那么现在进行升级不是估计一个数而是在估多个参数例如本例中的双线性变换中需要估计θ[a0,b0,c0,d0]这就好比需要同时测量四根棍子的长度并且由于数据的相关性和估计过程的耦合这些参数并不独立。为了更好的描述多个参数的估计就引入了协方差矩阵Covariance Matrix当有多个参数θ[θ1,θ2,…,θp]它们的不确定性用一个矩阵表示Cov(θ)⎡⎢⎢⎣Var(θ1)Cov(θ1,θ2)⋯Cov(θ2,θ1)Var(θ2)⋯⋮⋮⋱⎤⎥⎥⎦对角线每个参数的方差 → 表示它自己的不确定性非对角线两个参数之间的协方差 → 表示它们的估计是否相互影响方差我们还好理解那么协方差是什么的呢这个概念也有点抽象假设有两个随机变量X和Y比如身高和体重如果X大时Y也大 → 正协方差如果X大时Y小 → 负协方差如果无关 → 协方差接近 0也就是说协方差衡量的是两个变量一起变化的趋势。如果还要说的更加具体一点那么可以这样定义对于两个参数^a0和^b0它们的协方差是Cov(^a0,^b0)1N−1N∑i1(^a(i)0−¯a0)(^b(i)0−¯b0)其中N重复实验次数^a(i)0第i次实验估计的a0¯a0所有^a(i)0的平均值¯b0所有^b(i)0的平均值也即是两个参数的协方差就是两者误差乘积的平均如果误差经常同号乘积为正那么协方差就大于0如果误差经常异号乘积为负那么协方差就小于0。3.3 计算那么如何得到这个协方差矩阵呢这里进行推导说明有点复杂先直接给出结论以后有机会再进行详细说明Cov(^θ)σ2(ATA)−1其中σ2是噪声方差的估计^σ2∥r∥2n−pr: 残差n: 数据点数p: 参数个数回到问题要评价最小二乘解的精度就可以取协方差矩阵对角线的值开平方得到每个待定参数的标准差。具体的代码实现如下// 假设求解了 theta_xVectorXd residual b_x - A_x * theta_x;int n A_x.rows(); // 数据点数int p A_x.cols(); // 参数数 4double sigma_squared residual.squaredNorm() / (n - p);// 计算 (A^T A)^{-1}MatrixXd AtA_inv (A_x.transpose() * A_x).inverse();// 协方差矩阵MatrixXd cov_theta sigma_squared * AtA_inv;// 每个参数的标准差即“精度”的量化VectorXd std_error cov_theta.diagonal().cwiseSqrt();cout 参数标准差 (std error): endl;cout a0: ± std_error(0) endl;cout b0: ± std_error(1) endl;cout c0: ± std_error(2) endl;cout d0: ± std_error(3) endl;