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.mzph.cn/pingmian/38768.shtml

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

相关文章

JS(JavaScript)的BOM操作

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…

一文汇总VSCode多光标用法

光标的创建 按住alt,鼠标左键单击,在单击位置生成光标/删除光标 按住ctrlalt,单击↑/↓,在每行同一个位置(若某一行较短,则在行尾)生成光标,这个不会删除光标,只会在光标…

Day61 代码随想录打卡|回溯算法篇---组合优化

本篇是针对上一题的优化,因为在计算所有可能的组合结果时,不是每一条路径都是我们需要遍历的,如图,当n和k都为4的时候,其实最终的结果只有一个[1,2,3,4]是符合结果的。因此我们遍历的时候就不需要遍历每一条边&#xf…

Go线程实现模型-G

G 概述 一个G就代表一个goroutine(或称Go例程),也与go函数相对应。作为编程人员,我们只是使用go语句向Go的运行时系统提交一个并发任务,而Go的运行时系统则会按照我们要求并发地执行它 Go编译器会把go语句变成对内部函数newproc的调用&…

美德政府转移比特币、以太坊引发市场下跌

小编通过链上地址监控,令人意外的发现德国和美国政府都进行了大规模的数字货币转移,转移了价值 1.5 亿美元的比特币和以太坊。这些大额转移势必引起了数字货币市场分析师和投资者的关注。 BTC价格 从今年起德国政府已转移了其持有的相当一部分比特币&…

【MySQL备份】Percona XtraBackup实战篇

目录 1. 前言 2.准备工作 2.1.创建备份目录 2.2.配置/etc/my.cnf文件 2.3.授予root用户BACKUP_ADMIN权限 3.全量备份 4.准备备份 5.数据恢复 6.总结 "实战演练:利用Percona XtraBackup执行MySQL全量备份操作详解" 1. 前言 本文将继续上篇【My…

玩Stable Diffusion不可不知的5款真人模型!大佬都在用!(附模型包)

模型对于AI绘画起决定性作用,今天推荐5款超好用的Stable Diffusion模型。 这些模型都在市面上收获了各种好评,而且各具特色,能满足你对写实人像的各种要求。 1、MajicMIX realisric 麦橘写实 写实系的人像大模型,具有非常好的质…

数据结构笔记第3篇:双向链表

1、双向链表的结构 注意:这里的 "带头" 跟前面我们说的 "头结点" 是两个概念,实际前面的在单链表阶段称呼不严谨,但是为了同学们更好的理解就直接称为单链表的头结点。 带头链表里的头结点,实际为 "哨兵…

勒索病毒--认知与防范

免责声明:本文仅做技术交流与学习... 目录 应急响应-勒索病毒 1、什么是勒索病毒? 勒索病毒是一种新型电脑病毒,主要以RDP爆破、邮件、程序木马、网页挂马的形式进行传播。该病毒性质恶劣、危害极大,一旦感染将给用户带来无法估量的损失。…

已解决 SyntaxError: invalid syntax,Python报错原因和解决方案。

「作者简介」:冬奥会网络安全中国代表队,CSDN Top100,就职奇安信多年,以实战工作为基础著作 《网络安全自学教程》,适合基础薄弱的同学系统化的学习网络安全,用最短的时间掌握最核心的技术。 这篇文章带大家…

C++编程(七)继承

文章目录 一、继承(一)概念(二)语法格式(三)通过子类访问父类中的成员1. 类内2. 类外 (四)继承中的特殊成员函数1. 构造函数2. 析构函数3. 拷贝构造函数4. 拷贝赋值函数 二、多重继承…

怎样把热门抖音短视频下载保存到手机相册?

怎样把热门抖音短视频下载保存到手机相册? 1、在手机上打开抖音短视频APP; 2、打开后搜索或找到要下载保存的抖音短视频; 3、打开短视频后,点击右则的分享,并滑动找到保存到相册; 4、点击后等待完成下载,…

Python实现接糖果小游戏

介绍: 基于Pygame的糖果从屏幕顶部下落的游戏代码。这个游戏包括了一个可以左右移动的篮子来接住下落的糖果,接住糖果会增加得分。 代码: import pygame import random import os# 初始化pygame和设置屏幕大小 pygame.init() screen_width, screen_height 800, 6…

海康视频播放,包含h5和web插件

自行下载 海康开放平台 demo 都写得很清楚,不多描述 1.视频web插件 vue2写法,公共vue文件写法,调用文件即可 开始时需要以下配置,不知道的找对接平台数据的人,必须要,否则播不了 getParameterData: {po…

万字总结随机森林原理、核心参数以及调优思路

万字总结随机森林原理、核心参数以及调优思路 在机器学习的世界里,随机森林(Random Forest, RF)以其强大的预测能力和对数据集的鲁棒性而备受青睐。作为一种集成学习方法,随机森林通过构建多个决策树并将它们的预测结果进行汇总&…

暴雨来袭,陈赫家变“水帘洞”网友:赫哥滴滴打船吗?

在魔都上海,一场突如其来的暴雨 不仅让街道变成了河流,还悄悄上演了一场现实版的“水帘洞”奇遇 而这场奇遇的主角,竟然是喜剧界的明星——陈赫! 这天,乌云密布,电闪雷鸣 魔都的天空仿佛被捅了个窟窿 雨…

吴恩达《LangChain for LLM Application Development》课程笔记

目录 1. 前言 2. 课程笔记 2.1. 模型、提示和解析器 2.2. LLM记忆,上下文管理 2.3. 链式操作 2.4. 文档问答 2.4.1. stuff 方法 2.4.2. 其他方法 2.5. LLM应用评估 2.6. 代理 2.6.1. 预定义工具 2.6.2. 自定义工具 代码资源: 1. 前言 LangC…

文心一言 VS 讯飞星火 VS chatgpt (293)-- 算法导论21.4 2题

二、证明:每个结点的秩最多为 ⌊lgm⌋ 。如果要写代码,请用go语言。 文心一言: 在数据结构和算法中,当我们谈论“结点的秩”时,这通常与某些特定的数据结构(如B树或B树)相关,其中每…

代码随想录算法训练营第40天| 518. 零钱兑换 II、 377. 组合总和 Ⅳ、70. 爬楼梯 (进阶)

518. 零钱兑换 II 题目链接:518. 零钱兑换 II 文档讲解:代码随想录 状态:不会 思路: 和494.目标和类似,这题属于组合问题,当我们有一个硬币coin时,对于每个金额j,通过添加这个硬币&a…

平安养老险陕西分公司参加2024上半年省级单位驻富平帮扶团联席会

6月28日,平安养老险陕西分公司工会副主席武媛携驻村工作队赴富平县庄里镇永安村参加2024上半年度省级单位驻富平帮扶团联席会议。 会议由省委金融办副主任、省委金融工委委员李嘉辉及省委金融办选派挂职干部、富平县副县长席玮共同主持。 会上,席玮县长带…