有时我们需要衡量一个向量的大小。在机器学习中,我们经常使用被称为范数(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

范数介绍及C++/OpenCV/Eigen的三种实现相关推荐

  1. 协方差矩阵介绍及C++/OpenCV/Eigen的三种实现

    函数f(x)关于某分布P(x)的期望(expectation)或者期望值(expected value)是指,当x由P产生,f作用于x时,f(x)的平均值.对于离散型随机变量,这可以通过求和得到: 对 ...

  2. 概率论中均值、方差、标准差介绍及C++/OpenCV/Eigen的三种实现

    概率论是用于表示不确定性声明(statement)的数学框架.它不仅提供了量化不确定性的方法,也提供了用于导出新的不确定性声明的公理.在人工智能领域,概率论主要有两种用途.首先,概率法则告诉我们AI系 ...

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

    奇异值分解(singular value decomposition, SVD):将矩阵分解为奇异向量(singular vector)和奇异值(singular value).通过奇异值分解,我们会 ...

  4. ROS学习:cv_bridge与opencv版本冲突三种解决方案

    cv_bridge与opencv版本冲突三种解决方案 1 问题描述: 2 解决方案: 2.1 不使用cv_bridge包 2.2 令cv_bridge使用opencv版本切换为自己工程所使用的版本 2 ...

  5. BaiduMap---百度地图官方Demo之路径规划功能(介绍公交,驾车和步行三种线路规划方法和自设路线方法)

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  6. 简单介绍apache虚拟主机配置的三种方式

    本文主要介绍了apache虚拟主机配置的三种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 记事本打开httpd.conf文 ...

  7. 简单介绍NAS、DAS、SAN三种存储方式

    随着主机.磁盘.网络等技术的发展,对于承载大量数据存储的服务器来说,服务器内置存储空间,或者说内置磁盘往往不足以满足存储需要.因此,在内置存储之外,服务器需要采用外置存储的方式扩展存储空间. 存储架构 ...

  8. 简要介绍VGA、DVI、HDMI三种接口之间的关系

    这三种接口都是视屏接口,一般高清电视都会带有这些接口.再者我们在用笔记本办公的时候可能会觉得屏幕有点小,想要再外接一个显示器,那么这个时候就会用到这几个接口(用到其中一个) 在购买这三种接口线的时候都 ...

  9. 行列式介绍及Eigen/OpenCV/C++的三种实现

    行列式,记作det(A),是一个将方阵A映射到实数的函数.行列式等于矩阵特征值的乘积.行列式的绝对值可以用来衡量矩阵参与矩阵乘法后空间扩大或者缩小了多少.如果行列式是0,那么空间至少沿着某一维完全收缩 ...

最新文章

  1. vs2013突然没有代码提示功能了。
  2. 基于RDP开源许可rdesktop基本介绍
  3. nginx php-fpm调优
  4. tkinter中button按钮控件(三)
  5. 华为智能家居app未能连接上远程云服务_【InForSec通讯】智能家居云平台实体间交互状态安全分析 | Usenix2019...
  6. NLP 自然语言分析理解
  7. [CATARC_2017] 第一周
  8. FID指标复现踩坑避坑 文本生成图像FID定量实验全流程复现(Fréchet Inception Distance )定量评价实验踩坑避坑流程
  9. 1155低功耗cpu排行_低功耗是亮点 Intel第三代酷睿CPU评测
  10. LabVIEW控制Arduino采集DHT11温湿度数值(进阶篇—4)
  11. 哈啰出行高质量故障复盘法:“3+5+3”(附模板)
  12. js动态添加修改删除元素
  13. CodeMirror 格式化内容和内容选择CodeMirror 官方文档
  14. html css x y相对定位坐标,HTML与CSS之相对定位、绝对定位
  15. M401a armbian下安装cups共享打印机
  16. 双拼输入法,设计方案
  17. C语言数据结构课程设计任务书
  18. 网景R6400做无线中继服务器,不是推荐,是吐槽!网件路由器 R6400真好,好的连个简单的活你都干不好!...
  19. dnf用计算机算比例,DNF:干货来啦,教你如何使用伤害计算器
  20. Webpack详细打包步骤

热门文章

  1. harris角点检测与绘制。通过滑动滚动条来控制阈值,以控制检测角点的数量并返回角点坐标
  2. 红外遥感设计报告论文+电路原理图
  3. 学习《Linux设备模型浅析之驱动篇》笔记(一)
  4. 数据结构与算法(2-2)线性表之链式存储(单链表、静态链表、循环链表、双向循环链表)
  5. python opencv单通道转多通道_13、OpenCV绘图和文本显示
  6. js中Object类型和Array类型的变量被赋值(复制)给其他变量后,修改被赋值(复制)的新变量的值,会影响原始变量的值,这是为什么呢?
  7. linux下远程传输文件命令scp使用注解
  8. linux系统目录树/内核源码目录树
  9. nicstat命令安装与分析
  10. linux命令find命令详解