ai时代,个人学习还重要吗?大佬们都在学,不学习还干嘛呢?

MCP

Huggingface

学习目标

  • 使用huggingface提供的模型和transformers api完成各类推理任务

transformers使用

  • huggingface中autoXXX的类,都是通过from_pretrained()函数,传入模型名字字符串自动加载对应的模型,免去用户手动导入特定的模型类(模型实在太多了)
  • 模型被下载到(ubuntu): .cache/huggingface/hub/model-name/下的blob目录下,snapshot下存放的是链接到模型文件的softlink,可以看到有config.json | model.safetensors | tokenizer_config.json | vocab.txt这些文件,vocab.txt是词汇表,model.safetensor是模型参数,safetensor是huggingface的参数文件格式,比pytorch的bin更安全(不会被恶意代码注入),可以用pip install safetensors这个lib打开。

文本分类

  • 文本分类模型不一定支持中文,比如默认的distilbert-base-uncased-finetuned-sst-2-english模型是个忽略大小写的英文模型
  • 使用pipeline(“text-classification”),默认调用的是sentiment分类,其他分类任务需要补充model参数

MATH

资料

  • 3blue1brown可视化学习ai相关数学知识,原谅自己本科阶段。

PROMPT ENGINEERING

资料

paper

RAG

资料

工具

FINE-TUNE

资料google’s saif

工具

概念

稀疏向量

“向量稀疏”指的是一个向量中大多数元素为零,只有少数元素是非零值的情况。在机器学习和自然语言处理中,向量稀疏通常是由于向量维度很高,而实际数据中只包含少数非零元素的结果。反义词是“稠密向量”(Dense Vector):一个向量中大多数元素是非零值的情况。

One-Hot编码

One-Hot编码是一种常用的特征表示方法,用于将离散特征转换为向量表示。把某个“类别”表示成一个 全是 0,只有一个位置是 1 的向量。

  • 🤔 为什么要用 One-Hot 编码?
    因为机器学习模型(尤其是线性模型、神经网络)不懂“类别”这些概念。
    如果你直接用字符串,模型是无法处理的。
    One-Hot 把“类别”变成了“数字向量”,使得模型可以进行数学计算。
  • ⚠️ 缺点:
    维度高:如果你有上万个类别(比如 NLP 里的词汇),One-Hot 向量会非常稀疏(大部分都是 0)。
    不包含语义关系:比如“北京”和“上海”的 One-Hot 向量之间完全没有距离或关联。
    因此,在复杂应用中(如 NLP),我们通常用 词嵌入(word embeddings) 来代替 One-Hot,比如 Word2Vec、BERT 等。

Tokenization

将文本切分为一个个子词,然后再映射为词汇表中的ID,就是token。
词汇表中通常已经把常见的单个字符包含了,所以正常情况下,所有文本都可以顺利被tokenization,如何遇到未知字符,会有个特殊的UNK token表示。
gpt3.5有5万多个词

词嵌入(Word Embedding)

词嵌入是一种将单词表示为向量的技术,这些向量捕捉单词之间的语义关系。
维度低:每个词被映射到一个低维向量空间,通常是 50 到 300 维。
捕捉语义关系:词嵌入向量之间的距离可以表示单词之间的语义关系。

  • 🧩 词嵌入怎么来的?有两大类方法:

    统计方法,比如Word2Vec、GloVe 等

    深度学习方法,比如 BERT、GPT 等。

  • ⚠️ 缺点:
    需要大量的训练数据:词嵌入需要大量的文本数据来训练,才能捕捉单词之间的语义关系。

激活函数(activation function)

激活函数是神经网络中用于引入非线性变换的函数。它们将输入信号转换为输出信号,使得神经网络可以学习复杂的非线性关系。

  • 🤔 为什么要用激活函数?
    如果没有激活函数,神经网络每一层只是:

    这其实就是线性变换,多个线性变换堆叠起来,本质上仍然是一个线性函数(向量投影),虽然也能反映一定的关系,但无法表示复杂的关系。
    激活函数引入非线性变换,可以使神经网络学习到更复杂的模式。





梯度下降(Gradient Descent)

对于一维函数,梯度等价于导数,对于多维函数,梯度就是一个向量,它的方向指向函数值增加最快的方向。
而梯度下降,就是沿着梯度的反方向,不断地更新参数,使得函数值(比如 Loss 越小越好)不断减小。
在工程中,梯度下降通过 loss.backward() + optimizer.step() 来实现。框架帮你自动做了链式求导和参数更新,你只需要选好模型 → 选好 loss → 调 optimizer → 调训练循环

  • loss.backward() 会自动用链式法则计算出所有参数的梯度(这就是反向传播)
  • optimizer.step() 会调用优化器,比如 SGD/Adam,用梯度来更新模型参数(相当于“沿负梯度方向走一步”),可以用公式W = W - 学习率 × 梯度来理解。

神经元

神经网络的结构是分层的,每一层有一定数量的神经元,这个数量通常是训练之前就已经确定的。且神经元的数量要与输入向量的维度保持一致。
假设有一个输入向量(相当于一个样本,或者理解成一个token经过嵌入的向量):

x = [x₁, x₂, x₃, …, xₙ] ∈ ℝⁿ

当前layer有m个神经元,每个神经元的weight是一个向量,这个向量的维度和输入向量的维度必须相同:

wᵢ = [wᵢ₁, wᵢ₂, wᵢ₃,…, wᵢₙ] ∈ ℝⁿ

每个神经元的bias是一个标量:

bᵢ ∈ ℝ

输入经过每个神经元进行计算(点积加上偏置,再输入到激活函数里转成概率),输出一个标量:

yᵢ = f(wᵢ * x + bᵢ)

多个神经元同时接收输入,进行并行计算,每个神经元输出一个标量,组合在一起就形成了一个向量,多个样本就形成了一个矩阵。

隐藏状态(Hidden State)

每一层的计算结果输出的向量通常被称为 隐藏状态(Hidden State),隐藏状态向量的维度和上一层的神经元数量相同。
在神经网络的上下文中,隐藏状态是指每一层神经网络在进行计算后得到的中间结果。
前向传播:这个中间结果是输入数据经过该层计算得到的特征表示。在网络的传递过程中逐层向后传播。
反向传播:前向传播结束后,最后一层的输出的隐藏状态向量传递到损失函数loss中,得到损失值。损失值通过反向传播计算出梯度,梯度会沿着每一层的隐藏状态进行反向传递。通过计算这些梯度,更新每一层的权重。

encoder & decoder

神经网络中的两个不同“子系统”,分别负责「理解输入」和「生成输出」。
可以理解成模型的两个不同模块,每个模块负责不同的任务,都包含了多个layer。
🤖 在 Transformer 中的例子:
✅ Encoder(编码器)结构
由多个 Encoder Layer 组成,通常是 6 层(也可能是 12、24 层,视模型大小而定):
每一层都包括:/home/huangshuai/code/my-github-blog/source/_posts
多头自注意力机制(Multi-Head Self Attention)
前馈神经网络(Feed Forward Network)
残差连接 + LayerNorm

✅ Decoder(解码器)结构
同样由多个 Decoder Layer 组成:
每一层包括:
Masked 多头自注意力机制(不能看到未来)
编码器-解码器注意力机制(Attention over encoder outputs)
前馈神经网络
残差连接 + LayerNorm

注意力机制attention

注意力机制是一种用于解决序列模型中的长距离依赖问题的技术。
本质是根据一个输入(query),在多个候选项(key)中找出与它最相关的信息(value)。
每个token的嵌入向量经过与qkv权重的线性变换后,得到qkv三个向量。

A(q, k, v) = Σ p(a(kᵢ, q)) * vᵢ

其中,p(a(kᵢ, q)) 是一个注意力分数,它表示当前 token 对其他 token 的注意力权重。a(kᵢ, q):表示 q 和 kᵢ 之间的相似度(打分函数,通常是点积 q ⋅ kᵢ),p函数通常是一个softmax函数,用于将分数归一化到 0 到 1 之间。

多头注意力机制:
输入的向量维度被切分成多个子向量,每个子向量分别进行注意力计算,最后将多个子向量的结果拼接起来。
这么做有什么用?
每个头能从不同的视角看输入,每个注意力头关注的角度是训练过程中自动涌现的,哪些头学会看长距离、哪些头学会看位置、哪些头学会看同义词关系……这些是自然涌现的。