日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

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

發布時間:2023/11/27 生活经验 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 范数介绍及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

總結

以上是生活随笔為你收集整理的范数介绍及C++/OpenCV/Eigen的三种实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。