transformer学习笔记-位置编码

news2024/12/18 22:56:59

在transformer学习笔记-自注意力机制(1)学习原理的时候,我们提到:

将句子从“苹果梨”,改成“梨苹果”,最终的到的新苹果和新梨,竟然是一样的,因为苹果和梨两个向量调换顺序后,对应计算的权重也换了顺序,因此最终计算出来的结果一样

也就是仅通过词嵌入和attention计算,并不会体现不同词token之间的位置关系,这也就是为何需要引入位置编码。
当然理解这一知识点,需要点空间物体移动的想象力。

还是以“我 喜欢 学习 Python”为例,我们可以怎么表示每个词token的位置:
我(位置0),喜欢(位置1),学习(位置2)、Python(位置3)
假设我们现在的词嵌入的维度是2,位置我们也用两位的二进制表示:

在这里插入图片描述
假设我们把位置增长方向当做一个坐标轴,这个xy平面的点,实际是按一个沿着token个数增长方向的三维空间运动(尝试用动态前进的点的轨迹,稍后我们还会再一次使用这种方法),虽然沿着增长方向很容易区分先后顺序,但是从xy二维平面很难直接观察出顺序(二维空间上不连续)。


如果这时我们有第五个点(“。”位置5),虽然在增长方向上不会跟现有的点重叠,但仅从xy平面来看,就跟位置0(0,0)重叠了。因此,我们需要增加一个维度z,当点在xy平面无法区分时,在zx平面区分出来:
在这里插入图片描述
原来的四个点,增多一个维度,该维度值都为0,而第五个点则为(0,0,1),从xy平面看到重叠的点(位置0,位置5),可以从xz平面看到区别((0,0,0),(0,0,1))
这个zy平面的点,实际也是按沿着增长方向的三维空间运动。
很难想象xy平面、zx平面同时垂直于token个数增长方向,但我们可以对多维空间,每两个维度拆出一个二维平面,然后与增长方向垂直。

问题来了,用二进制的方式,一个二维空间,最多能表示四个位置,三维空间,最能表示8个位置,空间严重浪费。

聪明的人又想出了一种针对词嵌入的位置编码方法,我们暂且叫它绝对位置编码:

一、 绝对位置编码

绝对位置编码为序列中(n行d列)的每个位置 i 分配一个固定的位置向量 P i P_i Pi,使模型能够区分同一词汇在不同位置表示的语义。对于一个包含k个token的句子(0,1,2,…k-1),对于每个位置 k和每个维度 i,有如下公式:

P ( k , 2 i ) = s i n ( k n 2 i / d ) P(k,2i) = sin(\frac{k}{n^{2i/d}}) P(k,2i)=sin(n2i/dk)
P ( k , 2 i + 1 ) = c o s ( k n 2 i / d ) P(k,2i+1) = cos(\frac{k}{n^{2i/d}}) P(k,2i+1)=cos(n2i/dk)
n是一个用户自定义的超参,我们暂且定为:10000, P ( k , 2 i ) P(k,2i) P(k,2i)表示第k个token的2i维度的值, P ( k , 2 i + 1 ) P(k,2i+1) P(k,2i+1)表示第k个token的2i维度下一个维度的值。

乍一看,这都啥乱七八糟的,别急,我们逐个理解下:

在这里插入图片描述
k:表示有k个词token
d:表示每个token词嵌入的维度,也就是位置编码的维度
i:表示列的索引,取值[0,d/2-1],每个i定位词token的(2i,2I+1)两个维度
那么第k个token的第i索引的两个维度的取值为:P(k,2I),P(k,2I+1),

再回到上面的公式,设a= k 1000 0 2 i / d , a 与 k 成正比 \frac{k}{10000^{2i/d}},a与k成正比 100002i/dk,ak成正比

P ( k , 2 i ) = s i n ( a ) P(k,2i) = sin(a) P(k,2i)=sin(a)
P ( k , 2 i + 1 ) = c o s ( a ) P(k,2i+1) = cos(a) P(k,2i+1)=cos(a)
可以看到这个公式把维度的列,分成了d/2-1组(sin(a),cos(a))

我们把其中一个分组的sin(a),cos(a)放入二维平面,以sin(a)为横轴,以cos(a)为纵轴,a随着k增大而增大,这时,点(sin(a),cos(a))的运动轨迹得到一个单位圆:

在这里插入图片描述
箭头就是随着a增大(K增大),点(sin(a),cos(a))运动方向

画圆的代码如下:

import numpy as np
import matplotlib.pyplot as plt

# 定义角度范围
a = np.linspace(0, 2 * np.pi, 1000)

# 计算 sin(a) 和 cos(a)
x = np.sin(a)
y = np.cos(a)

# 绘制图像
plt.figure(figsize=(6, 6))
plt.plot(x, y, label='Unit Circle')
plt.title('Plot of cos(a) vs sin(a)')
plt.xlabel('sin(a)')
plt.ylabel('cos(a)')
plt.axhline(0, color='black',linewidth=0.5)
plt.axvline(0, color='black',linewidth=0.5)
plt.grid(color = 'gray', linestyle = '--', linewidth = 0.5)
plt.legend()
plt.axis('equal')  # 确保 x 和 y 轴的比例相同
plt.show()

想象一下:点(sin(a),cos(a))是随着a变化运动的,也就是说还有个隐藏的坐标轴表示a的变化方向,也就是说点(sin(a),cos(a))的运动轨迹,虽然从二维平面看是个圆,运动的点会周期性重叠,但在与a轴前进方向上,其实是个弹簧的形状,永远不会重叠。就像地球围着太阳转的时候,太阳也在银河系转时,地球的运动轨迹。所以在某个i对应的(sin(a),cos(a))平面,当有重叠的点,则需要通过下一个i的(sin(a),cos(a))平面来区分先后顺序,当然下一个平面的点也是在另一个a轴前进方向上的(a= k 1000 0 2 i / d \frac{k}{10000^{2i/d}} 100002i/dk,i变大,k不变的情况下,a也变大),想象一下,整个银河系也在绕着某个核心在转。
相当于当前的角度(i固定,a的前进方向)看的平面区分不出重叠的点,就换个角度看,最后,得到d/2-1个平面,每个平面都对应一个圆。
在这里插入图片描述
再回到a= k 1000 0 2 i / d \frac{k}{10000^{2i/d}} 100002i/dk,随着i变大,在K不变的情况下,a越来越小,也就是说,i越小,点(sin(a),cos(a))移动的速度越快,随着K的增大,P(k,2I),P(k,2I+1)的值变化越大;i越大,变化越不明显。又回到天体运行上,太阳沿着a轴的前进方向随k的改变速度,要比银河系沿着另一个a轴前进的方向要快得多,远的相对运动慢得感受不到位置移动变化,嗯,我们似乎找到了宇宙运行的奥秘。
用代码来感受下:

import torch
import math
import matplotlib.pyplot as plt

def get_absolute_position_encoding(max_len, d_model):
    """生成绝对位置编码"""
    position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
    div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))
    
    pe = torch.zeros(max_len, d_model)
    pe[:, 0::2] = torch.sin(position * div_term)
    pe[:, 1::2] = torch.cos(position * div_term)
    
    return pe

# 参数设置
max_len = 512  # 最大序列长度
d_model = 64  # 嵌入维度

# 获取绝对位置编码
pe = get_absolute_position_encoding(max_len, d_model)

# 绘制不同维度的位置编码随位置变化的情况
plt.figure(figsize=(12, 6))

# 绘制前几个维度
for i in range(18,20):
    plt.plot(pe[:, i], label=f'Low Dim {i}')

# 绘制后几个维度
high_dims = [d_model - 10 + i for i in range(2)]
for i in high_dims:
    plt.plot(pe[:, i], label=f'High Dim {i}', linestyle='--')

plt.title('Absolute Position Encodings')
plt.xlabel('Position Index')
plt.ylabel('Embedding Value')
plt.legend()
plt.grid(True)
plt.show()

在这里插入图片描述
这里我们设置位置编码维度为64,token个数最多为512个,可以看到低维度的曲线周期性变化快,而高维度变化慢。

说明什么问题:

i较小时,i对应的平面内的P(k,2I),P(k,2I+1)对K敏感,k增大一点点,P(k,2I),P(k,2I+1)的值就有明显变化,但同时也容易出现轨迹重叠,后续出现的token,只能从更高的维度(i的值更大的平面)识别,因此低纬度的P(k,2I),P(k,2I+1)体现的相近的词token的位置关系,反之,高纬度的P(k,2I),P(k,2I+1)对K增长不敏感,需要K增长非常多,才有变化,体现长距离的位置关系。

现在来看看,位置距离对内积的影响:

初始化Q和K向量,Q固定在位置0,感受下K的位置逐渐远离时QK的内积变化。

import torch
import math
import matplotlib.pyplot as plt

def get_absolute_position_encoding(max_len, d_model):
    """生成绝对位置编码"""
    position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
    div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))
    
    pe = torch.zeros(max_len, d_model)
    pe[:, 0::2] = torch.sin(position * div_term)
    pe[:, 1::2] = torch.cos(position * div_term)
    
    return pe

# 参数设置
max_len = 512  # 最大序列长度
d_model = 512# 嵌入维度

# 获取绝对位置编码
pe = get_absolute_position_encoding(max_len, d_model)

# 初始化 Q 和 K
Q = torch.randn(d_model)
K = torch.randn(d_model)
# 初始化 query 向量,固定在位置 0
query = pe[0]

# 初始化 key 向量,位置逐渐远离
keys = pe

# 计算 query 和 key 在不同位置上的内积
inner_products = []
for i in range(max_len):
    inner_product = torch.dot(Q+query, K+keys[i])
    inner_products.append(inner_product.item())

# 绘制内积变化图
plt.figure(figsize=(12, 6))
plt.plot(inner_products, label='Inner Product with Query at Position 0')
plt.title('Inner Product of Query and Key Vectors at Different Positions')
plt.xlabel('Position Index')
plt.ylabel('Inner Product Value')
plt.legend()
plt.grid(True)
plt.show()

在这里插入图片描述
可以看到,随着距离逐渐变远,内积先快速下降,然后逐渐收敛,这个逐渐收敛的过程叫远程衰减。体现近距离更强的依赖关系。

我不知道原作者是不是也是用这种理念设计的,但我用空间运动的方式理解这个公式的时候,心想这家伙是怎么想到的。

回到正题:
得到位置编码后,将原本的词嵌入与位置编码相加,得到包含位置信息的词嵌入。此时,句子从“苹果梨”,改成“梨苹果”,得到的新苹果和新梨,就不一样了。
在这里插入图片描述

注意: 我们可能会担心加入了位置编码后的词嵌入会影响原有的语义,这里主要考虑以下几点:
1、使用的sin和cos,取值[-1,1],数值小,对原有词嵌入的影响很少。
2、随着k的增长,sin和cos的值变化幅度很小,对整体矩阵结构(整体特征)的影响很少,
3、矩阵相加后的可分解性,由于计算位置编码的公式固定,在后续的处理中,能够分解出位置编码,并在多层神经网络结构中,对噪音进行优化处理。
实践也证明,位置编码对词嵌入本身的影响,微乎其微,相反模型因为位置编码的加入,增强了对词token在不同语境下的理解能力。

上面介绍的这种绝对位置编码方式叫:Sinusoidal位置编码。
当然还有一种绝对位置编码方式,叫训练式绝对位置编码,通过初始化一个n * d 的位置编码权重矩阵(n为最长token个数,d编码权重矩阵的维度)通过大量语料训练得到,此处不做介绍。

绝对位置编码也存在一些问题:

1、模型训练通过固定词token个数的序列长度完成训练(包括 W Q 、 W K 、 W V {W^Q}、W^K、W^V WQWKWV等权重),当实际处理的序列超过模型训练的序列长度时,现有训练的权重参数等,不能有效处理。比如 W Q 、 W K 、 W V {W^Q}、W^K、W^V WQWKWV的行数都是跟训练序列的行数一致,位置编码的行数也一致。
2、绝对位置编码更关注整体的位置编码,对局部的位置相对较弱,比如,“我喜欢学习Python”,和“近几年,我喜欢学习Python”,后面句更会对前面的“近几年”几个token投入过多关注,不利于识别关键信息。大多数时候,我们更关心距离较近的部分的位置信息,而不是整体的。
3、从局部看,后面句子的"我喜欢学习Python",会因前面的token位置编码发生较大变化,语义上这两句应该是相同的,但绝对位置认为不同,对模型处理的稳定性造成影响。

如何让模型能够更加关注局部的相对位置信息呢,这也是接下来需要学习的RoPE旋转位置编码所实现的目标:

二、RoPE旋转位置编码

先来看看二维空间中,向量旋转的一些特性:

在这里插入图片描述
首先,旋转后的向量长度不变,也就是特征能够保持,比如,小狗的图像经过旋转后还是小狗的图像;
其次,旋转得有多远可以通过夹角α表示。

假设现在有单位旋转角度θ,向量Q原始位置在0,然后移动到1,然后2,用向量旋转表示则如下:

在这里插入图片描述
此时Q0、Q1、Q2不仅可以通过0* θ、1* θ、2* θ 表示绝对距离,Q2与Q1之间还可以通过旋转角度2* θ - 1* θ表示,

RoPE位置编码就是这么干的。
RoPE通过对Q的位置下标m * 单位旋转角度θ,对K的位置下标n * 单位旋转角度θ,也就是Q旋转mθ,K旋转nθ,然后求旋转后的内积,从而使内积带上相对位置的信息,设旋转矩阵为R:

旋转前的内积: Q T ⋅ K Q^T ·K QTK
旋转后的内积: Q T ⋅ R ( m − n ) ⋅ K Q^T ·R_{(m-n)}·K QTR(mn)K(省略推导,直接说结论)
在这里插入图片描述

目前为止,我们讨论的都还是二维的的情况,对于高维的Q和K,应该如何处理:
RoPE采取了跟上面Sinusoidal位置编码类似的方式:
首先,还是将d个维度,分成d/2个分组:

分组索引为: i(0,1,2,…,d/2-1)
每个i分组旋转的单位角度 θ i θ_i θi 1 n 2 i / d \frac{1}{n^{2i/d}} n2i/d1(n工程上一般取10000)
在这里插入图片描述
以上图为例,取i = 1, θ 1 θ_1 θ1= 1 1000 0 2 / d \frac{1}{10000^{2/d}} 100002/d1,序列的第m个token,旋转m倍 θ 1 θ_1 θ1
也就是d/2个分组对应d/2个平面,每个平面按照 m m mθ_i θ i θ_i θi各自转各自的。


更一般的,对于d维的第m个词嵌入,旋转可有如下表示
在这里插入图片描述
可以将上面的矩阵乘法,简化为一下逐乘然后相加的计算方式:
在这里插入图片描述
简化后的式子虽然方便了计算,但是不方便理解,理解还得看简化前的式子。

再回到式子 θ i θ_i θi = 1 1000 0 2 i / d \frac{1}{10000^{2i/d}} 100002i/d1,随着维度增大,i增大, θ i θ_i θi变小,i对应的平面的向量旋转的角度越小,当维度d较大时,i比较大的平面,m需要比较大才能有所反应。而维度低的平面,相邻的向量间旋转的夹角就能比较大。这也反应跟Sinusoidal位置编码相似的特性:低维度短距离依赖,高维度长距离依赖

示例代码如下:
初始化Q和K向量,Q固定在位置0,感受下K的位置逐渐远离时QK的内积变化。

import numpy as np
import matplotlib.pyplot as plt

def apply_rotation(K, delta_k, d):
    """应用旋转矩阵"""
    rotated_K = np.zeros_like(K)
    
    for i in range(d // 2):
        theta_i = 1 / (10000 ** (2 * i / d))
        delta_theta_i = theta_i * delta_k
        
        # 构造旋转矩阵
        R = np.array([[np.cos(delta_theta_i), -np.sin(delta_theta_i)],
                      [np.sin(delta_theta_i), np.cos(delta_theta_i)]])
        
        k_rotated = R @ np.array([K[2*i], K[2*i+1]])
        rotated_K[2*i:2*i+2] = k_rotated
    
    return rotated_K

def compute_inner_product(Q, K):
    """计算内积"""
    return np.dot(Q, K)

# 参数设置
d_model = 512  # 嵌入维度
max_distance = 1024  # 最大距离
inner_products = []
# 初始化 Q 和 K
# Q = torch.randn(d_model)
K = torch.randn(d_model)
# 计算不同距离下的内积
for delta_k in range(max_distance):
    rotated_Q = apply_rotation(K, 0, d_model)
    rotated_K = apply_rotation(K, delta_k, d_model)
    inner_products.append(compute_inner_product(rotated_Q, rotated_K))

# 绘制内积随距离变化的情况
plt.figure(figsize=(12, 6))
plt.plot(range(max_distance), inner_products, label='Inner Product')
plt.title('Inner Product of Rotated Q and K with Increasing Distance')
plt.xlabel('Distance (Δk)')
plt.ylabel('Inner Product Value')
plt.legend()
plt.grid(True)
plt.show()

在这里插入图片描述

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

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

相关文章

【Unity3D】实现UGUI高亮引导点击

Unity版本2019.4.0f1 Personal <DX11> using UnityEngine; using UnityEngine.UI;public class GuideMask : MonoBehaviour, ICanvasRaycastFilter {public Canvas canvas;public Transform guideTargetTrans;public Image image;private Vector3 guideTargetWorldPos;pr…

Springboot3.x配置类(Configuration)和单元测试

配置类在Spring Boot框架中扮演着关键角色&#xff0c;它使开发者能够利用Java代码定义Bean、设定属性及调整其他Spring相关设置&#xff0c;取代了早期版本中依赖的XML配置文件。 集中化管理&#xff1a;借助Configuration注解&#xff0c;Spring Boot让用户能在一个或几个配…

SpringBoot增删改查导入导出操作【模板】

SpringBoot增删改查导入导出操作【模板】 文章目录 SpringBoot增删改查导入导出操作【模板】前期数据库操作IDEA上进行操作1. 创建 Spring Boot 项目2. 项目结构3. pom.xml文件4. 配置数据库连接并进行测试5. 创建实体类6. 创建 MyBatis Mapper7. 创建服务层8. 创建控制器9. 启…

mfc140.dll是什么东西?mfc140.dll缺失的几种具体解决方法

mfc140.dll是Microsoft Foundation Classes&#xff08;MFC&#xff09;库中的一个动态链接库&#xff08;DLL&#xff09;文件&#xff0c;它是微软基础类库的一部分&#xff0c;为Windows应用程序的开发提供了丰富的类库和接口。MFC库旨在简化Windows应用程序的开发过程&…

探索Starship:一款用Rust打造的高性能终端

在终端的世界里&#xff0c;效率和美观往往并行不悖。今天&#xff0c;我们要介绍的是一款名为Starship的终端工具&#xff0c;它以其轻量级、高颜值和强大的自定义功能&#xff0c;赢得了众多开发者的青睐。 安装 任选一种方式进行安装 Windows &#x1fa9f; # scoop scoo…

2024年NSSCTF秋季招新赛-WEB

The Beginning F12看源码&#xff0c;有flag http标头 黑吗喽 题目说要在发售时的0点0分&#xff0c;所以添加标头data Date: Tue, 20 Aug 2024 00:00:00 GMT然后改浏览器头 User-Agent: BlackMonkey曲奇就是Cookie cookieBlackMonkey这个一般就是Referer Referer:wukon…

TQ15EG开发板教程:使用SSH登录petalinux

本例程在上一章“创建运行petalinux2019.1”基础上进行&#xff0c;本例程将实现使用SSH登录petalinux。 将上一章生成的BOOT.BIN与imag.ub文件放入到SD卡中启动。给开发板插入电源与串口&#xff0c;注意串口插入后会识别出两个串口号&#xff0c;都需要打开&#xff0c;查看串…

windos系统安装-mysql 5.7 zip压缩包教程

一, 安装包下载 在mysql官网上下载mysql5.7版本的压缩包 官方网址: https://dev.mysql.com/downloads/mysql/5.7.html#downloads选择历史版本 选择系统和数据库版本下载 下载完成后解压到安装的目录 二, 新增数据目录,配置文件, 配置环境变量 新建data文件夹用于存放数据库…

js 获取屏幕高度和宽度的几种方式

1、document.documentElement.clientHeight 屏幕可视区域高度&#xff0c;文档的根元素&#xff08;通常是 <html> 元素&#xff09;的高度&#xff0c;但会受到CSS样式的影响。 实际应用&#xff1a;对于H5的移动端&#xff0c;希望video元素在全屏状态下占满整个手机屏…

Tree-of-Counterfactual Prompting for Zero-Shot Stance Detection

论文地址&#xff1a;Tree-of-Counterfactual Prompting for Zero-Shot Stance Detection - ACL Anthologyhttps://aclanthology.org/2024.acl-long.49/ 1. 概述 立场检测被定义为对文本中立场态度的自动推断。根据 Biber 和 Finegan (1988) 的定义&#xff0c;立场包含两个主…

css基础-认识css

什么是css css是一个样式表&#xff0c;是对html的一种装饰&#xff0c;它决定了浏览器如何显示html元素&#xff0c;例如&#xff1a; h1 {color:blue; //文字颜色是蓝色font-size:12px; //字体大小为12像素 }上段css代码就是对HTML 中 <h1>标签的修饰&#xff1b;所以…

【Unity功能集】TextureShop纹理工坊(二)图层(下)

项目源码&#xff1a;后期发布 索引 图层渲染绘画区域图层Shader 编辑器编辑模式新建图层设置当前图层上、下移动图层删除图层图层快照 图层 在PS中&#xff0c;图层的概念贯穿始终&#xff08;了解PS图层&#xff09;&#xff0c;他可以称作PS最基础也是最强大的特性之一。 …

云计算HCIP-OpenStack02

书接上回&#xff1a; 云计算HCIP-OpenStack01-CSDN博客 7.OpenStack核心服务 7.1Horizon&#xff1a;界面管理服务 Horizon提供了OpenStack中基于web界面的管理控制页面&#xff0c;用户或者是管理员都需要通过该服务进行OpenStack的访问和控制 界面管理服务需要依赖于keyston…

Word2Vec:将词汇转化为向量的技术

文章目录 Word2Vec来龙去脉分层Softmax负采样 Word2Vec 下面的文章纯属笔记&#xff0c;看完后不会有任何收获&#xff0c;如果想理解这两种优化技术&#xff0c;给大家推荐一篇博客&#xff0c;讲的很好&#xff1a; 详解-----分层Softmax与负采样 来龙去脉 word2vec,即将词…

电商商品详情API接口(item get)数据分析上货

电商商品详情API接口&#xff08;item get&#xff09;在数据分析与商品上货方面发挥着重要作用。以下是对这两个方面的详细探讨&#xff1a; 一、数据分析 数据源获取&#xff1a; 商品详情API接口提供了丰富的数据源&#xff0c;包括商品的标题、价格、库存、描述、图片、用…

如何将你的 Ruby 应用程序从 OpenSearch 迁移到 Elasticsearch

作者&#xff1a;来自 Elastic Fernando Briano 将 Ruby 代码库从 OpenSearch 客户端迁移到 Elasticsearch 客户端的指南。 OpenSearch Ruby 客户端是从 7.x 版 Elasticsearch Ruby 客户端分叉而来的&#xff0c;因此代码库相对相似。这意味着当将 Ruby 代码库从 OpenSearch 迁…

如何对 Java 项目简化接口设计提升开发效率

文章目录 摘要引言简洁接口设计的原则示例代码OrderProcessor 接口StandardOrderProcessor 实现类Order 数据类调用方代码&#xff1a;OrderService 模块之间的协作QA 环节总结参考资料 摘要 简洁的接口设计可以有效降低代码依赖与耦合度&#xff0c;提高代码的可维护性和扩展…

Python字符串及正则表达式(十):字符串常用操作、字符串编码转换

前言&#xff1a;在编程的世界里&#xff0c;字符串无处不在。它们是构建用户界面、存储数据、进行通信的基础元素。无论是财务系统的总账报表、电子游戏的比赛结果&#xff0c;还是火车站的列车时刻表&#xff0c;这些信息最终都需要以文本的形式呈现给用户。这些文本的背后&a…

JAVA爬虫获取1688关键词接口

以下是使用Java爬虫获取1688关键词接口的详细步骤和示例代码&#xff1a; 一、获取API接口访问权限 要使用1688关键词接口&#xff0c;首先需要获取API的使用权限&#xff0c;并了解接口规范。以下是获取API接口的详细步骤&#xff1a; 注册账号&#xff1a;在1688平台注册一…

【AIGC】与模型对话:理解与预防ChatGPT中的常见误解

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;模型的工作原理和用户期望差异人工智能模型的基本工作原理认知上的局限与误解用户期望与模型实际能力的差距精确理解用户意图的重要性实际应用中的建议 &…