当前位置: 首页 > 编程日记 > 正文

范数介绍及C++/OpenCV/Eigen的三种实现

有时我们需要衡量一个向量的大小。在机器学习中,我们经常使用被称为范数(norm)的函数衡量向量大小。形式上,Lp范数定义如下:


范数(包括Lp范数)是将向量映射到非负值的函数。直观上来说,向量x的范数衡量从原点到点x的距离。更严格地说,范数是满足下列性质的任意函数:


当p=2时,L2范数被称为欧几里得范数(Euclidean norm)。它表示从原点出发到向量x确定的点的欧几里得距离。

在数学中,欧几里得距离或欧几里得度量是欧几里得空间中两点间”普通”(即直线)距离。使用这个距离,欧式空间成为度量空间。相关联的范数称为欧几里得范数。


L2范数在机器学习中出现地十分频繁,经常简化表示为‖x‖,略去了下标2。平方L2范数也经常用来衡量向量的大小,可以简单地通过点积xTx计算。

平方L2范数在数学和计算上都比L2范数本身更方便。例如,平方L2范数对x中每个元素的导数只取决于对应的元素,而L2范数对每个元素的导数却和整个向量相关。但是在很多情况下,平方L2范数也可能不受欢迎,因为它在原点附件增长得十分缓慢。在某些机器学习应用中,区分恰好是零的元素和非零但值很小的元素是很重要的。在这些情况下,我们转而使用在各个位置斜率相同,同时保持简单的数学形式的函数:L1范数。

当机器学习问题中零和非零元素之间的差异非常重要时,通常会使用L1范数。每当x中某个元素从0增加ε,对应的L1范数也会增加ε。

有时候我们会统计向量中非零元素的个数来衡量向量的大小。有些作者将这种函数称为"L0范数",但是这个术语在数学意义上是不对的。向量的非零元素的数目不是范数,因为对向量缩放α倍不会改变向量非零元素的数目。因此,L1范数经常作为表示非零元素数目的替代函数。

另外一个经常在机器学习中出现的范数是L范数,也被称为最大范数(max norm)。这个范数表示向量中具有最大幅值的元素的绝对值:‖x‖=max|xi|

有时候我们可能也希望衡量矩阵的大小。在深度学习中,最常见的做法是使用Frobenius范数:类似于向量的L2范数。


两个向量的点积(dot product)可以用范数来表示。具体地,xTy=‖x‖2‖y‖2cosθ,其中θ表示x和y之间的夹角。

以上内容摘自: 《深度学习中文版》 和 维基百科

以下是分别用C++、OpenCV、Eigen实现的求范数正无穷、范数L1、范数L2的code:

C++和OpenCV code:

#include "funset.hpp"
#include <math.h>
#include <iostream>
#include <string>
#include <vector>
#include <opencv2/opencv.hpp>
#include "common.hpp"// 求范数
typedef enum Norm_Types_ {Norm_INT = 0, // 无穷大Norm_L1, // L1Norm_L2 // L2
} Norm_Types;template<typename _Tp>
int norm(const std::vector<std::vector<_Tp>>& mat, int type, double* value)
{*value = 0.f;switch (type) {case Norm_INT: {for (int i = 0; i < mat.size(); ++i) {for (const auto& t : mat[i]) {*value = std::max(*value, (double)(fabs(t)));}}}break;case Norm_L1: {for (int i = 0; i < mat.size(); ++i) {for (const auto& t : mat[i]) {*value += (double)(fabs(t));}}}break;case Norm_L2: {for (int i = 0; i < mat.size(); ++i) {for (const auto& t : mat[i]) {*value += t * t;}}*value = std::sqrt(*value);}break;default: {fprintf(stderr, "norm type is not supported\n");return -1;}}return 0;
}int test_norm()
{fprintf(stderr, "test norm with C++:\n");std::vector<int> norm_types{ 0, 1, 2 }; // 正无穷、L1、L2std::vector<std::string> str{ "Inf", "L1", "L2" };// 1. vectorstd::vector<float> vec1{ -2, 3, 1 };std::vector<std::vector<float>> tmp1(1);tmp1[0].resize(vec1.size());for (int i = 0; i < vec1.size(); ++i) {tmp1[0][i] = vec1[i];}for (int i = 0; i < str.size(); ++i) {double value{ 0.f };norm(tmp1, norm_types[i], &value);fprintf(stderr, "vector: %s: %f\n", str[i].c_str(), value);}// 2. matrixstd::vector<float> vec2{ -3, 2, 0, 5, 6, 2, 7, 4, 8 };const int row_col{ 3 };std::vector<std::vector<float>> tmp2(row_col);for (int y = 0; y < row_col; ++y) {tmp2[y].resize(row_col);for (int x = 0; x < row_col; ++x) {tmp2[y][x] = vec2[y * row_col + x];}}for (int i = 0; i < str.size(); ++i) {double value{ 0.f };norm(tmp2, norm_types[i], &value);fprintf(stderr, "matrix: %s: %f\n", str[i].c_str(), value);}fprintf(stderr, "\ntest norm with opencv:\n");norm_types[0] = 1; norm_types[1] = 2; norm_types[2] = 4; // 正无穷、L1、L2cv::Mat mat1(1, vec1.size(), CV_32FC1, vec1.data());for (int i = 0; i < norm_types.size(); ++i) {double value = cv::norm(mat1, norm_types[i]);fprintf(stderr, "vector: %s: %f\n", str[i].c_str(), value);}cv::Mat mat2(row_col, row_col, CV_32FC1, vec2.data());for (int i = 0; i < norm_types.size(); ++i) {double value = cv::norm(mat2, norm_types[i]);fprintf(stderr, "matrix: %s: %f\n", str[i].c_str(), value);}return 0;
}
执行结果如下:

Eigen code:

#include "funset.hpp"
#include <math.h>
#include <iostream>
#include <vector>
#include <string>
#include <opencv2/opencv.hpp>
#include <Eigen/Dense>
#include "common.hpp"int test_norm()
{fprintf(stderr, "test norm with eigen:\n");// 1. vectorstd::vector<float> vec1{ -2, 3, 1 };Eigen::VectorXf v(vec1.size());for (int i = 0; i < vec1.size(); ++i) {v[i] = vec1[i];}double value = v.lpNorm<Eigen::Infinity>();fprintf(stderr, "vector: Inf: %f\n", value);value = v.lpNorm<1>();fprintf(stderr, "vector: L1: %f\n", value);value = v.norm(); // <==> sqrt(v.squaredNorm()) <==> v.lpNorm<2>()fprintf(stderr, "vector: L2: %f\n", value);// 2. matrixstd::vector<float> vec2{ -3, 2, 0, 5, 6, 2, 7, 4, 8 };const int row_col{ 3 };Eigen::Map<Eigen::MatrixXf> m(vec2.data(), row_col, row_col);value = m.lpNorm<Eigen::Infinity>();fprintf(stderr, "matrix: Inf: %f\n", value);value = m.lpNorm<1>();fprintf(stderr, "matrix: L1: %f\n", value);value = m.norm();fprintf(stderr, "matrix: L2: %f\n", value);return 0;
}
执行结果如下:

可见使用C++、OpenCV、Eigen三种方法实现的结果是一致的。


GitHub:

https://github.com/fengbingchun/NN_Test

https://github.com/fengbingchun/Eigen_Test

相关文章:

js添加网页水印和three.js场景中加水印

我们在日常网页开发的时候&#xff0c;可能想给自己的网页或者canvas里面添加水印&#xff0c;增添个人标记&#xff0c;我这里分为普通静态html页面和threejs中3d场景里面添加水印功能。一 静态html页面添加水印你只需要在你的页面添加一个图片遮罩&#xff0c;通过绝对定位和…

JAVA学习笔记(6)

关于多线程的优先级&#xff0c;这个程序里面&#xff0c;现在计算机比较好&#xff0c;int存储不下了&#xff0c;我跑了好几次都是负分&#xff0c;特把int改成long。但是之后跑出来的结果&#xff0c;两个数字都差不多&#xff0c;不知道是什么问题&#xff1f;等待答案中。…

C++/C++11中std::deque的使用

std::deque是双端队列&#xff0c;可以高效的在头尾两端插入和删除元素&#xff0c;在std::deque两端插入和删除并不会使其它元素的指针或引用失效。在接口上和std::vector相似。与sdk::vector相反&#xff0c;std::deque中的元素并非连续存储&#xff1a;典型的实现是使用一个…

贾扬清:我对人工智能方向的一点浅见

阿里妹导读&#xff1a;作为 AI 大神&#xff0c;贾扬清让人印象深刻的可能是他写的AI框架Caffe &#xff0c;那已经是六年前的事了。经过多年的沉淀&#xff0c;成为“阿里新人”的他&#xff0c;对人工智能又有何看法&#xff1f;最近&#xff0c;贾扬清在阿里内部分享了他的…

吴甘沙:天外飞“厕”、红绿灯消失,未来无人驾驶将被重新定义

整理 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;2019 年9 月 5 日至 7 日&#xff0c;由新一代人工智能产业技术创新战略联盟&#xff08;AITISA&#xff09;指导&#xff0c;鹏城实验室、北京智源人工智能研究院支持&#xff0c;专业中文 IT 技术社区 CS…

Linux内核--网络栈实现分析(二)--数据包的传递过程--转

转载地址http://blog.csdn.net/yming0221/article/details/7492423 作者&#xff1a;闫明 本文分析基于Linux Kernel 1.2.13 注&#xff1a;标题中的”&#xff08;上&#xff09;“&#xff0c;”&#xff08;下&#xff09;“表示分析过程基于数据包的传递方向&#xff1a;”…

C++/C++11中std::stack的使用

栈stack 是一个容器适配器(container adaptor)类型&#xff0c;被特别设计用来运行于LIFO(Last-in First-out&#xff0c;后进先出)场景&#xff0c;在该场景中&#xff0c;只能从容器末尾添加和删除元素&#xff0c;其定义在stack头文件中。stack默认基于std::deque实现&#…

团队前四次作业——个人总结

团队前四次作业——个人总结 描述 团队名称待就业六人组相关团队第四次作业答辩——反思与总结做了哪些事&#xff1f;工作量、完成度 作业负责工作量完成度团队队员展示创意合照后期1h95%项目选题报告编写创新和收益部分2h85%项目原型设计原型设计6h95%需求规格说明书功能需求…

吴甘沙:天外飞“厕”、红绿灯消失,未来无人驾驶将被重新定义 | AI ProCon 2019

2019 年9 月 5 日至 7 日&#xff0c;由新一代人工智能产业技术创新战略联盟&#xff08;AITISA&#xff09;指导&#xff0c;鹏城实验室、北京智源人工智能研究院支持&#xff0c;专业中文 IT 技术社区 CSDN 主办的 2019 中国 AI 开发者大会&#xff08;AI ProCon 2019&#x…

MySQL基础day03_数据的导入、导出-MySQL 5.6

MySQL基础day03_数据的导入、导出-MySQL 5.6注&#xff1a;把数据按照一定格式存放到文件里才能进行数据的导入。1&#xff0c;数据导入的条件把文件里的内容保存到数据的表里&#xff1b;把数据按照一定格式存放文件里&#xff1b;注&#xff1a;默认情况下&#xff0c;只有管…

“含光”剑出,谁与争锋?阿里重磅发布首颗AI芯片含光800

作者 | 夕颜、胡巍巍 编辑 | 唐小引 出品 | AI 科技大本营&#xff08;ID:rgznai100&#xff09; 9 月末的杭州气温适宜&#xff0c;宜出游&#xff0c;宜在湖边餐厅浅酌一杯清茶消闲。但在钱塘江水支流河畔的云栖小镇&#xff0c;却完全一副与闲适氛围不相称的热闹景象。 …

c++面试题中经常被面试官面试的小问题总结(一)(本篇偏向基础知识)

原文作者&#xff1a;aircraft 原文链接&#xff1a;https://www.cnblogs.com/DOMLX/p/10711810.html 1.类中的函数定义后加了一个const代表什么&#xff1f; 代表它将具备以下三个性质&#xff1a;1.const对象只能调用const成员函数。2.const对象的值不能被修改&#xff0c;在…

矩阵特征分解介绍及雅克比(Jacobi)方法实现特征值和特征向量的求解(C++/OpenCV/Eigen)

对角矩阵(diagonal matrix)&#xff1a;只在主对角线上含有非零元素&#xff0c;其它位置都是零&#xff0c;对角线上的元素可以为0或其它值。形式上&#xff0c;矩阵D是对角矩阵&#xff0c;当且仅当对于所有的i≠j, Di,j 0. 单位矩阵就是对角矩阵&#xff0c;对角元素全部是1…

Entity Framework CodeFirst数据迁移

原文:Entity Framework CodeFirst数据迁移前言 紧接着前面一篇博文Entity Framework CodeFirst尝试。 我们知道无论是“Database First”还是“Model First”当模型发生改变了都可以通过Visual Studio设计视图进行更新&#xff0c;那么对于Code First如何更新已有的模型呢&…

限时早鸟票 | 2019 中国大数据技术大会(BDTC)超豪华盛宴抢先看!

2019 年12月5-7 日&#xff0c;由中国计算机学会主办&#xff0c;CCF 大数据专家委员会承办&#xff0c;CSDN、中科天玑数据科技股份有限公司协办的 2019 中国大数据技术大会&#xff0c;将于北京长城饭店隆重举行。届时&#xff0c;超过百位技术专家及行业领袖将齐聚于此&…

Google AI 系统 DeepMind无法通过 高中数学

Google 旗下 DeepMind 团队让 AI 系统接受一项高中程度的数学测试&#xff0c;结果在 40 道题目中只答对了 14 题&#xff0c;甚至连「1111111」也算错了。说来难以置信&#xff0c;Google AI 系统能打败人类世界棋王&#xff0c;却无法通过高中程度的数学考试。上周&#xff0…

C++11中std::tuple的使用

std::tuple是类似pair的模板。每个pair的成员类型都不相同&#xff0c;但每个pair都恰好有两个成员。不同std::tuple类型的成员类型也不相同&#xff0c;但一个std::tuple可以有任意数量的成员。每个确定的std::tuple类型的成员数目是固定的&#xff0c;但一个std::tuple类型的…

PHP Countable接口

实现该接口可以使用count()方法来获取集合的总数转载于:https://www.cnblogs.com/xiaodo0/p/3611307.html

矩阵奇异值分解简介及C++/OpenCV/Eigen的三种实现

奇异值分解(singular value decomposition, SVD)&#xff1a;将矩阵分解为奇异向量(singular vector)和奇异值(singular value)。通过奇异值分解&#xff0c;我们会得到一些与特征分解相同类型的信息。然而&#xff0c;奇异值分解有更广泛的应用。每个实数矩阵都有一个奇异值分…

经典!工业界深度推荐系统与CTR预估必读的论文汇总

&#xff08;图片付费下载自视觉中国&#xff09;来源 | 深度传送门&#xff08;ID: gh_5faae7b50fc5&#xff09;导读&#xff1a;本文是“深度推荐系统”专栏的第十一篇文章&#xff0c;这个系列将介绍在深度学习的强力驱动下&#xff0c;给推荐系统工业界所带来的最前沿的变…

docker上传自己的镜像

https://blog.csdn.net/boonya/article/details/74906927 需要注意的就是命名规范 docker push 注册用户名/镜像名 tag命令修改为规范的镜像&#xff1a; docker tag boonya/tomcat-allow-remote boonyadocker/tomcat-allow-remote转载于:https://www.cnblogs.com/MC-Curry/p/1…

多个class相同的input标签 获取当前值!方法!

2019独角兽企业重金招聘Python工程师标准>>> var a $(this).prev( ".你的class" ).val(); 转载于:https://my.oschina.net/u/1169079/blog/210082

C++11中std::forward_list单向链表的使用

std::forward_list是在C11中引入的单向链表或叫正向列表。forward_list具有插入、删除表项速度快、消耗内存空间少的特点&#xff0c;但只能向前遍历。与其它序列容器(array、vector、deque)相比&#xff0c;forward_list在容器内任意位置的成员的插入、提取(extracting)、移动…

即学即用的30段Python实用代码

&#xff08;图片付费下载自视觉中国&#xff09;原标题 | 30 Helpful Python Snippets That You Can Learn in 30 Seconds or Less作 者 | Fatos Morina翻 译 | Pita & AI开发者Python是目前最流行的语言之一&#xff0c;它在数据科学、机器学习、web开发、脚本编写、自…

如何配置IntelliJ IDEA发布JavaEE项目?

一、以war的形式运行项目 步骤1 新建或者导入项目后&#xff0c;选择File菜单-》Project Structure...&#xff0c;如下图&#xff1a; 步骤2 配置项目类型&#xff0c;名字可以自定义&#xff1a; 说明&#xff1a;这里的Artifact如果没有配置好的话&#xff0c;配置Tomcat时没…

网络分布式软件bonic清除

近期&#xff0c;有一款网格计算软件&#xff0c;在很多服务器上进行了部署&#xff0c;利用cpu进行运算。虽然未构成安全隐患&#xff0c;但是比较消耗资源&#xff0c;影响设备正常运行。今天对设备彻底检查&#xff0c;发现了一个分布式计算软件boinc&#xff0c;他是利用网…

C++/C++11中std::list双向链表的使用

std::list是双向链表&#xff0c;是一个允许在序列中任何一处位置以常量耗时插入或删除元素且可以双向迭代的顺序容器。std::list中的每个元素保存了定位前一个元素及后一个元素的信息&#xff0c;允许在任何一处位置以常量耗时进行插入或删除操作&#xff0c;但不能进行直接随…

React组件设计之边界划分原则

简述 结合SOLID中的单一职责原则来进行组件的设计 Do one thing and do it well javaScript作为一个弱类型并在函数式和面对对象的领域里疯狂试探语言。SOLID原则可能与其他语言例如&#xff08;java&#xff09;的表现可能是不同的。不过作为软件开发领域通用的原则&#xff0…

阿里AI labs发布两大天猫精灵新品,将与平头哥共同定制智能语音芯片

作者 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;2019 年&#xff0c;去年刮起的一阵智能音箱热浪似乎稍微冷却下来&#xff0c;新产品不再像雨后春笋一样层出不穷&#xff0c;挺过市场洗礼的产品更是凤毛麟角&#xff0c;这些产品的性能、技术支持和体验基…

js 中文匹配正则

为什么80%的码农都做不了架构师&#xff1f;>>> /^[\u4e00-\u9fa5]{2,4}$/gi.test() 匹配中文正则 转载于:https://my.oschina.net/fedde/blog/211852