Cosine 余弦相似度并行计算的数学原理与Python实现

背景

Cosine 我在LLM与RAG系列课程已经讲了很多次了,这里不在熬述,它在LLM分析中,尤其是在语义相似度的计算中至关重要,在dot attention机制中,也会看到他的身影。这里讲的是纯数学上的运算与python是如何运用相关库进行并行计算的原理及实践。完全掌握了他,在看vector db 里面的语义相似度,你可能会豁然开朗。实现总是如此的优雅。

Cosine的定义,两个向量(A, B), 他们的余弦相似度为:

Cosine(A,B) = (A * B)  /  (len(A) * len (B))

其实就是距离在M维坐标系的分别投影,前面也说了很多次了,不明白可以参看LLM与RAG系列课程。下面举个例子,很简单的初中数学,两个二维向量A,B,如果他们维度所包含的分量都相等,那么Cosine = 1, 很好理解:A(x, y), B(x, y)

A  *  B =  (x, y) * (x, y)= x^2 + y^2

len(A) = sqrt(x^2 + y^2)

len(B) = sqrt(x^2 + y^2)

最后答案就是 Cosine(A, B) = 1

如果是N维向量,很显然,相同。

Cosine(A,B) = (A * B)  /  (len(A) * len (B))

问题来了,我如果给你很多个A,很多个B,要你求所有A,B之间的 Cosine,要怎么处理?最笨的办法就是写个  def cosine(A,B)   return  (A * B)  /  (len(A) * len (B)),  然后写一个二层for循环,case by case,这样的代码交给CPU 做AI,肯定是不合适的。怎么优化呢?那就是线性代数的魅力来了,Matrix 运算。我们看看怎么做。

向量内积

向量内积,不要总想着二,三维,那是初中,高中的东西。在LLM的世界,高维向量普遍存在,在Choma vector db 提供的基础 embedding中,嵌入向量为 384 维度。那还算比较小的。大一点的上千维度都很正常。向量的内积,很简单,就是M维向量的M维度分别相乘后相加,放到Matrix 的指定位置就对了,python 实现更简单,就是 A dot B, 一个 dot 解决了(M , N)与 (N , J)维度的matrix 乘法。有点线性代数功底的都知道:(M , N)* (N , J) = (M, J)。 可是问题来了,在LLM的世界中,因为嵌入向量都是 M维,表达方式都是 (M , N), (J, N) 这种是没办法做 向量内积的,怎么办?很简单,转置一下,(M , N)* (J, N)T = (M, J)。 以前总觉得现线性代数没啥用,现在看到了它的魅力,你要用它的时,如果你概念基础扎实,马上就上手了。讲到了这里,看下 python 的例子:

arr1 = np.array([[1, 2, 3], [2, 3, 5], [1, 4, 3]])
arr2 = np.array([[4, 5, 6], [1, 2, 3]])
print(np.dot(X, Y.T))

非常简洁的代码,看下输出:

nice。不要小看他,它相当于是将将arr1的三个二维向量与arr2的两个二维向量在 O(0)同时完成了计算结果。而且 python 的 numpy 底层是经过 compiler 优化的,性能还是非常出色。

向量外积 

是一个线性代数中的概念,指的是两个向量的张量积(tensor product),其结果是一个矩阵。

具体来说,假设 X_norm 是一个形状为 (m,) 的一维数组(向量),而 Y_norm 是一个形状为 (n,) 的一维数组(向量)。那么,np.outer(X_norm, Y_norm) 将返回一个形状为 (m, n) 的二维数组(矩阵),其中第 i 行第 j 列的元素是 X_norm[i] 和 Y_norm[j] 的乘积。

用数学符号表示,如果 X_norm = [x_1, x_2, ..., x_m] 和 Y_norm = [y_1, y_2, ..., y_n],那么(X_norm, Y_norm)的外积 将产生一个矩阵,其元素为:

python 代码实现:

import numpy as np 
X_norm = np.array([1, 2]) 
Y_norm = np.array([3, 4, 5]) result = np.outer(X_norm, Y_norm)
print(result)

向量的长度

就是 2-范数或称为欧几里得范数,各维度平方相加开根号。

就是上面说的 len

p.linalg.norm 是 NumPy 中的一个函数,用于计算向量或矩阵的范数。具体来说,np.linalg.norm(X, axis=1) 是在 NumPy 数组 X 上沿着指定的轴(在这里是 axis=1)计算向量的 2-范数(或称为欧几里得范数)。

假设 X 是一个形状为 (m, n) 的二维数组(或矩阵),其中 m 是行数,n 是列数。那么 np.linalg.norm(X, axis=1) 会返回一个长度为 m 的一维数组,其中每个元素是 X 中对应行的 2-范数。

还是上面那个例子,看下代码与运行结果:

arr1 = np.array([[1, 2, 3], [2, 3, 5], [1, 4, 3]])
arr2 = np.array([[4, 5, 6], [1, 2, 3]])X_norm = np.linalg.norm(arr1, axis=1)
Y_norm = np.linalg.norm(arr2, axis=1)

发现维度没变,还是之前的,shape 都相同。只是做了平方求和开根号的处理。

LLM中的应用

到了这里,我们发现,如果我们使用:

X = np.array([[1, 2, 3], [2, 3, 5], [1, 4, 3]])
Y = np.array([[4, 5, 6], [1, 2, 3]])
similarity = np.dot(X, Y.T) / np.outer(X_norm, Y_norm)

他就是关于X的每个二维的分量与Y的每个二维分量之间的 Cosine。因为它同时完成了对应每个位置的 (A * B)  /  (len(A) * len (B))

我们看看结果:

数学含义也很明确,比如在 X的 [1,2,3] 对 Y的 [1,2,3]时, Cosine = 1,非常完美的三行代码。不要看不起它,他在vector db 中起着举足轻重的作用。今天介绍到这里,如果你对LLM感兴趣,可以读下我的其他专栏,同步更新中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/365934.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

昇思25天学习打卡营第6天|网络构建

网络构建 概念模型模型参数 概念 神经网络模型是由神经网络层和Tensor操作构成的,mindspore.nn提供了常见神经网络层的实现,在MindSpore中,Cell类是构建所有网络的基类,也是网络的基本单元。一个神经网络模型表示为一个Cell&…

事务的特性-原子性(Atomicity)、一致性(Consistency)、隔离性(Asolation)、持久性(Durability)

一、引言 1、数据库管理系统DBMS为保证定义的事务是一个逻辑工作单元,达到引入事务的目的,实现的事务机制要保证事务具有原子性、一致性、隔离性和持久性,事务的这四个特性也统称为事务的ACID特性 2、当事务保持了ACID特性,才能…

Jasper studio报表工具中,如何判断subDataSource()子报表数据源是否为空

目录 1.1、错误描述 1.2、解决方案 1.1、错误描述 今天在处理一个有关Jasper Studio报表模板制作的线上问题,需要根据某个报表子数据源是否为空,来决定对应的组件是否显示,找了好久的资料都没有实现,最后找到一种解决办法。就是…

【Mybatis 与 Spring】事务相关汇总

之前分享的几篇文章可以一起看,形成一个体系 【Mybatis】一级缓存与二级缓存源码分析与自定义二级缓存 【Spring】Spring事务相关源码分析 【Mybatis】Mybatis数据源与事务源码分析 Spring与Mybaitis融合 SpringManagedTransaction: org.mybatis.spri…

09 - matlab m_map地学绘图工具基础函数 - 绘制区域填充、伪彩色、加载图像和绘制浮雕效果的有关函数

09 - matlab m_map地学绘图工具基础函数 - 绘制区域填充、伪彩色、加载图像和绘制浮雕效果的有关函数 0. 引言1. 关于m_pcolor2. 关于m_image3. 关于m_shadedrelief4. 关于m_hatch5. 结语 0. 引言 本篇介绍下m_map中区域填充函数(m_hatch)、绘制伪彩色图…

Coze搭建《测测你的本命宠物》

前言 本文讲解如何从零开始,使用扣子平台去搭建《测测你的本命宠物》 《测测你的本命宠物》:测测你的本命宠物 - 扣子 AI Bot (coze.cn) 欢迎大家去体验一下!!! 正文 接下来我们开始讲解制作这个bot的流程吧&#…

公网环境使用Potplayer远程访问家中群晖NAS搭建的WebDAV听歌看电影

文章目录 前言1 使用环境要求:2 配置webdav3 测试局域网使用potplayer访问webdav4 内网穿透,映射至公网5 使用固定地址在potplayer访问webdav 前言 本文主要介绍如何在Windows设备使用potplayer播放器远程访问本地局域网的群晖NAS中的影视资源&#xff…

解析 Ferret-UI:多模态大模型在移动用户界面理解中的应用

移动应用的爆炸性增长,用户界面(UI)的设计越来越复杂,功能也越来越丰富。但现有的多模态大模型(MLLMs)在理解用户界面时存在局限,尤其是在处理具有特定分辨率和包含众多小型对象(如图…

debian打包小结

背景 业务需要,打一个openstack组件的deb包 openstack组件有setup.py可直接支持打rpm包,但不支持deb包,所以手动打deb包 用了dh_make准备打包文件,然后用debuild或dpkg-buildpackages打deb包 步骤 方法有很多,我用…

【uniapp】HBuilderx中uniapp项目运行到微信小程序报错Error: Fail to open IDE

HBuilderx中uniapp项目运行到微信小程序报错Error: Fail to open IDE 问题描述 uniapp开发微信小程序,在HBuilderx中运行到微信开发者工具时报错Error: Fail to open IDE 解决方案 1. 查看微信开发者工具端服务端口是否开放 打开微信开发者工具选择&#xff1…

31、matlab卷积运算:卷积运算、二维卷积、N维卷积

1、matlab卷积运算简介 在Matlab中,卷积运算是一种常见的信号处理和图像处理操作,用于将两个函数或信号进行混合以创建一个新的函数或信号。在Matlab中,卷积运算可以通过使用函数conv来实现。 一维卷积:在一维情况下,…

切片的基础知识

文章目录 ● Slice 的底层实现原理?● array 和 Slice 的区别?● 拷贝大切片一定比小切片代价大吗?● Slice 深拷贝和浅拷贝?● 零切片、空切片、nil切片?● Slice 的扩容机制?● Slice 为什么不是线程安全…

Hive SQL:实现炸列(列转行)以及逆操作(行转列)

目录 列转行行转列 列转行 函数: EXPLODE(ARRAY):将ARRAY中的每一元素转换为每一行 EXPLODE(MAP):将MAP中的每个键值对转换为两行,其中一行数据包含键,另一行数据包含值 数据样例: 1、将每天的课程&#…

新款奔驰GLE350升级原厂空气悬挂系统有哪些功能

奔驰 GLE350 升级原厂空气悬挂带来了一系列显著的优势和功能: 1. 舒适性提升 • 能够根据不同的路况和驾驶模式自动调节悬挂硬度和高度,有效过滤路面颠簸,为驾乘者提供更加平稳、舒适的行驶体验。 2. 行驶高度调节 • 驾驶者可以手动或自…

Web服务器与Apache(虚拟主机基于ip、域名和端口号)

一、Web基础 1.HTML概述 HTML&#xff08;Hypertext Markup Language&#xff09;是一种标记语音,用于创建和组织Web页面的结构和内容&#xff0c;HTML是构建Web页面的基础&#xff0c;定义了页面的结构和内容&#xff0c;通过标记和元素来实现 2.HTML文件结构 <html>…

商汤上海AI实验室联合发布:自动驾驶全栈式高精度标定工具箱(含车、IMU、相机、激光雷达等的标定)

前言 在自动驾驶技术飞速发展的今天&#xff0c;传感器的精确标定对于确保系统性能至关重要。SensorsCalibration&#xff0c;一个专为自动驾驶车辆设计的标定工具箱&#xff0c;提供了一套全面的解决方案&#xff0c;用于校准包括IMU、激光雷达、摄像头和雷达在内的多种传感器…

Spring Cloud Gateway 与 Nacos 的完美结合

在现代微服务架构中&#xff0c;服务网关扮演着至关重要的角色。它不仅负责路由请求到相应的服务&#xff0c;还承担着诸如负载均衡、安全认证、限流熔断等重要功能。Spring Cloud Gateway 作为 Spring Cloud 生态系统中的一员&#xff0c;以其强大的功能和灵活的配置&#xff…

双链表的实现

双链表的实现 前言链表的基础知识双链表的有关方法的实现 前言 Hello&#xff0c;亲爱的CSDN的小伙伴们&#xff0c;你们好&#xff0c;今天我来给大家分享有关双链表的知识&#xff0c;希望可以帮助到大家。 链表的基础知识 1.链表一共有八种&#xff0c;而最常见的只有两种…

【pytorch11】高阶操作

高阶操作 WhereGather where 三个参数&#xff0c;第一个是condition&#xff0c;第二个参数是源头A&#xff0c;第三个参数是源头B&#xff0c;也就是说有两项数据A和B&#xff0c;C有可能来自于A也有可能来自于B&#xff0c;如果全部来自于A的话直接赋值给A&#xff0c;如果…

SpringBoot实现图片添加水印

提示&#xff1a;今日完成图片添加水印功能 后续可能还会继续完善这个功能 文章目录 目录 文章目录 前端部分 后端 Xml Controller层 Sercive层 Service实现层 Config配置层 application.properties 文件后缀名获取 常量定义 前端部分 <!DOCTYPE html> <htm…