迭代计算

机器学习中梯度下降法原理及用其解决线性回归问题的C语言实现

元气小坏坏 提交于 2019-12-01 18:22:07
本文讲梯度下降(Gradient Descent)前先看看利用梯度下降法进行监督学习(例如分类、回归等)的一般步骤: 1, 定义损失函数(Loss Function) 2, 信息流forward propagation,直到输出端 3, 误差信号back propagation。采用“链式法则”,求损失函数关于参数Θ的梯度 4, 利用最优化方法(比如梯度下降法),进行参数更新 5, 重复步骤2、3、4,直到收敛为止 所谓损失函数,就是一个描述实际输出值和期望输出值之间落差的函数。有多种损失函数的定义方法,常见的有均方误差(error of mean square)、最大似然误差(maximum likelihood estimate)、最大后验概率(maximum posterior probability)、交叉熵损失函数(cross entropy loss)。本文就以均方误差作为损失函数讲讲梯度下降的算法原理以及用其解决线性回归问题。在监督学习下,对于一个样本,它的特征记为x(如果是多个特征,x表示特征向量),期望输出记为t(t为target的缩写),实际输出记为o(o为output的缩写)。两者之间的误差e可用下式表达(为了节省时间,各种算式就用手写的了): 前面的系数1/2主要是为了在求导时消掉差值的平方项2。如果在训练集中有n个样本,可用E来表示所有样本的误差总和

点云ICP注册

ⅰ亾dé卋堺 提交于 2019-12-01 15:00:21
原文链接 背景 两个点云要注册在一块,一般分两个步骤:先做一个大致的对齐,也就是所谓的初始注册,一般可以通过一些可靠的点对来计算得到(如图3所示);然后在初始注册的基础上进行精细注册,提升注册的精度(如图4所示)。精细注册的方法,一般采用ICP算法,也就是最近点迭代的方法。 ICP算法总览 下面先总的介绍一下ICP算法,之后再详细介绍里面的一些重要步骤。 算法输入是两片有部分重叠的点云a和b,并且已经初始注册好了,输出是ICP注册的刚体变换T: 1. 对b进行点采样,得到采样点集s 2. 在a中寻找采样点集s的最近对应点,得到点对集合c 3. 对c中的点云进行加权处理,并删掉一些不好的点对 4. 应用目标能量来优化点对距离,得到刚体变换Ti。Ti对采样点集进行刚体变换 5. 迭代步骤2-4,直到目标能量优化停止。T=Tn * ...... T1 * T0 点采样 由于计算速度的要求,一般是需要对点云b进行采样。然后用采样点去找对应进行优化。除了计算上的要求,如果用全点云进行匹配的话,精度也不会更加的好。因为更好的采样方法可以避免陷入能量局部极小的情况。常见的采样方法有均匀采样和几何采样。 均匀采样:采样点分布均匀,采样速度快,适合几何特征比较多的点云。因为这样的点云,均匀采样总能采样到几何特征。如果几何特征少的话,如下左图所示,有可能就采样不到几何特征。 几何采样

深究递归和迭代的区别、联系、优缺点及实例对比

久未见 提交于 2019-12-01 10:58:05
深究递归和迭代的区别、联系、优缺点及实例对比 1. 概念区分 递归的基本概念 : 程序调用自身的编程技巧称为递归 , 是函数自己调用自己 . 一个函数在其定义中直接或间接调用自身的一种方法 , 它通常把一个大型的复杂的问题转化为一个与原问题相似的规模较小的问题来解决 , 可以极大的减少代码量 . 递归的能力在于用有限的语句来定义对象的无限集合 . 使用递归要注意的有两点 : 1) 递归就是在过程或函数里面调用自身 ; 2) 在使用递归时 , 必须有一个明确的递归结束条件 , 称为递归出口 . 递归分为两个阶段 : 1) 递推 : 把复杂的问题的求解推到比原问题简单一些的问题的求解 ; 2) 回归 : 当获得最简单的情况后 , 逐步返回 , 依次得到复杂的解 . 利用递归可以解决很多问题 : 如背包问题 , 汉诺塔问题 ,... 等 . 斐波那契数列为 :0,1,1,2,3,5... 由于递归引起一系列的函数调用 , 并且有可能会有一系列的重复计算 , 递归算法的执行效率相对较低 . 迭代 : 利用变量的原值推算出变量的一个新值 . 如果递归是自己调用自己的话 , 迭代就是 A 不停的调用 B. 2. 辩证看递归和迭代 所谓递归,简而言之就是应用程序自身调用自身,以实现层次数据结构的查询和访问。 递归的使用可以使代码更简洁清晰,可读性更好(对于初学者到不见得),但由于递归需要系统堆栈

函数对象

寵の児 提交于 2019-12-01 09:49:33
数组 enum eRelation // 表示计算策略的枚举体 { eLess, // 小于 eEqual, // 等于 eGreater // 大于 }; template< typename T, typename ITER_TYPE> ITER_TYPE find_if_number( ITER_TYPE begin, ITER_TYPE end, eRelation relType, const T &target ) // 用数值表示策略的find_if函数 { for(ITER_TYPE iter = begin; iter!=end; iter++) // 遍历迭代器区间 { switch( relType ) // 根据不同的策略 { case eLess: if( *iter < target ) // 比较当前元素与目标 { return iter; // 返回迭代器 } case eEqual: if( *iter == target ) { return iter; } case eGreater: if( *iter > target ) { return iter; } } } return end; // 失败,则返回区间尾部 } int main(int argc, char *argv[]) // 主函数 { int ary[5] = {1,2,3

配送交付时间轻量级预估实践

感情迁移 提交于 2019-12-01 07:49:44
1. 背景 可能很多同学都不知道,从打开美团App点一份外卖开始,然后在半小时内就可以从骑手小哥手中拿到温热的饭菜,这中间涉及的环节有多么复杂。而美团配送技术团队的核心任务,就是将每天来自祖国各地的数千万份订单,迅速调度几十万骑手小哥按照最优路线,并以最快的速度送到大家手中。 在这种场景下,骑手的交付时间,即骑手到达用户附近下车后多久能送到用户手中,就是一个非常重要的环节。下图是一个订单在整个配送链路的时间构成,时间轴最右部分描述了交付环节在整个配送环节中的位置。交付时间衡量的是骑手送餐时的交付难度,包括从骑手到达用户楼宇附近,到将餐品交付到用户手中的整个时间。 交付时间的衡量是非常有挑战的一件事,因为骑手在送餐交付到用户手中时会碰到不同的问题,例如:骑手一次送餐给楼宇内多个用户,骑手对于特定楼宇寻址特别困难,骑手在交付楼宇附近只能步行,老旧小区没有电梯,写字楼无法上楼,或者难以等到电梯等等。交付时间预估需要具备刻画交付难度的能力,在定价、调度等多个场景中被广泛使用。例如根据交付难度来确定是否调节骑手邮资,根据交付难度来确定是否调节配送运单的顺序,从而避免超时等等。总的来说,交付时间预估是配送业务基础服务的重要一环。 但是,交付时间预估存在如下的困难: 输入信息较少,且多为非数值型数据,目前能够被用来预估的仅有如下维度特征:交付地址、交付点的经纬度、区域、城市

不依赖Python第三方库实现梯度下降

主宰稳场 提交于 2019-12-01 07:19:36
认识 梯度的本意是一个向量(矢量),表示某一函数在该点处的方向导数沿着该方向取得最大值,即函数在该点处沿着该方向(此梯度的方向)变化最快,变化率最大(为该梯度的模), 我感觉, 其实就是 偏导数向量方向呗 , 沿着这个 向量方向可以找到局部的极值 . from random import random def gradient_down(func, part_df_func, var_num, rate=0.1, max_iter=10000, tolerance=1e-10): """ 不依赖第三库实现梯度下降 :param func: 损失(误差)函数 :param part_df_func: 损失函数的偏导数向量 :param var_num: 变量个数 :param rate: 学习率(参数的每次变化的幅度) :param max_iter: 最大计算次数 :param tolerance: 误差的精度 :return: theta, y_current: 权重参数值列表, 损失函数最小值 """ theta = [random() for _ in range(var_num)] # 随机给定参数的初始值 y_current = func(*theta) # 参数解包 for i in range(max_iter): # 计算当前参数的梯度(偏导数导数向量值)

集成学习个人学习总结

[亡魂溺海] 提交于 2019-12-01 05:49:18
说明 :本科普也是借助诸多集成学习文章学习总结而来。 集成学习 一般我们常说的集成学习的方法都是指的同质个体学习器。而同质个体学习器使用最多的模型是CART决策树和神经网络。同质个体学习器按照个体学习器之间是否存在依赖关系可以分为两类,第一个是个体学习器之间存在强依赖关系,一系列个体学习器基本都需要串行生成,代表算法是boosting系列算法,第二个是个体学习器之间不存在强依赖关系,一系列个体学习器可以并行生成,代表算法是bagging和随机森林(Random Forest)系列算法。 集成学习之boosting Boosting算法的工作机制是首先从训练集用初始权重训练出一个弱学习器。1. 根据弱学习的学习误差率表现来更新训练样本的权重,使得之前弱学习器1学习误差率高的训练样本点的权重变高,使得这些误差率高的点在后面的弱学习器2中得到更多的重视。然后基于调整权重后的训练集来训练弱学习器。2. 如此重复进行,直到弱学习器数达到事先指定的数目T,最终将这T个弱学习器通过集合策略进行整合,得到最终的强学习器。 Boosting系列算法里最著名算法主要有AdaBoost算法和提升树(boosting tree)系列算法。提升树系列算法里面应用最广泛的是梯度提升树(Gradient Boosting Tree)。 AdaBoost算法原理 Boosting需要解决如下几个问题:

thymeleaf循环遍历

◇◆丶佛笑我妖孽 提交于 2019-12-01 05:35:28
th:each属性用于迭代循环,语法:th:each="obj,iterStat:${objList}" 迭代对象可以是Java.util.List,java.util.Map,数组等; iterStat称作状态变量,属性有: index:当前迭代对象的index(从0开始计算) count: 当前迭代对象的index(从1开始计算) size:被迭代对象的大小 current:当前迭代变量 even/odd:布尔值,当前循环是否是偶数/奇数(从0开始计算) first:布尔值,当前循环是否是第一个 last:布尔值,当前循环是否是最后一个 <div class="layui-row layui-tab-card" th:each="watermark,statu : ${watermarkList}"> <div class="col-md-4">[[${statu.count}]].[[${watermark.title}]]</div> </div> 来源: https://www.cnblogs.com/ZeroLife/p/11660439.html

漫谈递归和迭代

亡梦爱人 提交于 2019-12-01 04:59:06
先讲个故事吧。 从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?“从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?‘从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?……’”。 这个故事永远也讲不完,因为没有递归结束条件。老师讲递归时总是说,递归很简单,一个递归结束条件,一个自己调用自己。如果递归没有结束条件,那么就会无限递归下去。在编程的时候,没有递归结束条件或者递归过深,一般会造成栈溢出。 下面这个函数,可以利用栈溢出来估测栈的大小: 1 void stack_size() 2 { 3 static int call_time = 0; 4 char dummy[1024*1024]; 5 call_time++; 6 printf("call time: %d\n",call_time); 7 stack_size(); 8 } 递归算法一般用于解决三类问题:这个函数定义了1M的局部变量,然后调用自己。栈溢出时会崩溃,根据最后打印出的数字可以算一下栈的大小。 (1)数据的定义是按递归定义的。(Fibonacci函数) (2)问题解法按递归算法实现。(回溯) (3)数据的结构形式是按递归定义的。(树的遍历,图的搜索) 对于求1+2+3+…+n这种问题,大部分人不会用递归方式求解: 1 2 3 4

redis源码分析3---结构体---字典

被刻印的时光 ゝ 提交于 2019-12-01 03:23:28
redis源码分析3---结构体---字典 字典,简单来说就是一种用于保存键值对的抽象数据结构; 注意,字典中每个键都是独一无二的;在redis中,内部的redis的数据库就是使用字典作为底层实现的; 1 字典的实现 在redis中,字典是使用哈希表作为底层实现的,一个hash表里面可以有多个hash表节点,而每个hash表节点就保存了字典中的一个键值对; hash表定义 table属性是一个数组,数组中的每个元素都是一个指向dictEntry结构的指针,每个dictEntry结构保存着一个键值对; 一个空的hash表: hash表节点 key保存键值对中的键,v为值,union表示三个钟选择一个,next是指向另一个hash表节点的指针,这个指针可以将多个hash值相同的键值对连接在一起,以此来解决冲突的问题; 比如 字典结构 总的来说,没有rehash的字节结构图如下 2 hash算法 当要将一个新的键值对添加到字典里面时,程序需要先根据键值对的键计算出hash值和索引值,然后再根据索引值,将包含新建支队的hash表节点放到哈市表数组的制定索引上面。 3 解决冲突 在hash表中不可避免的会出现冲突,当有两个或者两个以上的键被分配到了hash表数组的同一个索引上面时,就说发生了冲突; 在redis中使用链地址法来解决键冲突;就是我们在前面的结构中定义的next指针实现的; 4