手搓GPT系列之 - 线性回归与softmax分类器,从理论到实战

NLP还存不存在我不知道,但数学之美一直都在。线性回归是机器学习中非常重要的一个砖块,我们将介绍线性回归和softmax分类器的数学原理及其内在关联。既是对自己学习成果的一种记录,如果能够对别人有所帮助那真是让人开心。

1. 什么是分类器

1.1 感性认识一下分类器

在机器学习中,分类器的作用是在标记好类别的训练数据基础上判断一个新的观察样本所属的类别。常规任务是利用给定的类别、已知的训练数据来学习分类规则和分类器,然后对未知数据进行分类或预测。一个大小为n的分类器训练数据集可以表示为\{x_i,y_i\}^n,其中,x_i是d维特征值,x_i \in \mathbb{R}^dy_i是分类标签的值,令C为所有分类的集合,y_i\in C。下边展示了一个特征值维度为2的二元分类器(二元分类器就是会把样本分成2类的分类器,例如:男/女,强/弱,高/低等等):

from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
import numpy as np
import matplotlib.pyplot as plt

# Generate 2D classification data
X, y = make_classification(n_samples=100, n_features=2, n_redundant=0,
                           n_informative=2, random_state=1, n_clusters_per_class=2)

# Train logistic regression classifier
clf = LogisticRegression(random_state=0).fit(X, y)

# Plot decision boundary
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02),
                     np.arange(y_min, y_max, 0.02))
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z, alpha=0.4)
plt.scatter(X[:, 0], X[:, 1], c=y, alpha=0.8)
plt.show()

1.2 生成式和判别式分类器

分类器模型可以分为两类:生成式(generative)和判别式(discriminative)。生成式模型与判别式模型的主要区别在于,对于特征数据x和分类结果y,生成式模型关注的是数据在空间中的分布情况,试图根据观察到的数据解释数据生成的逻辑,具体来说,就是通过先验数据学习联合概率分布p(x,y),然后再生成条件概率分布p(y|x);而判别式模型会跳过联合概率分布的计算,直接根据观察数据来推测新的样本的分类。换句话说,生成式模型会根据观察数据获得一个其自认为的世界真相,并根据这个真相来推测新样本的分类;判别式则不关心世界真相,只是看新数据和哪一撮观察数据最相似。

现有的生成式模型包括:贝叶斯模型、马尔可夫模型、分支定界法、混合高斯模型等。判别式模型包括:K近邻法(KNN)、决策树、SVM、Fisher线性判别、有限状态机、线性回归(感知机)、softmax算法、神经网络等。

我们本文将着重介绍判别式模型中的线性回归算法(感知机)、softmax算法及神经网络模型背后的数学原理及这三种算法之间的内在联系。

2. Logistic Regression

我们先从最基本的分类器说起,说的就是线性回归算法,或者更准确点应该叫感知机。上面的例子展示的就是一个线性回归,线性回归算法顾名思义就是通过一个可以用线性方程(线性方程指的是仅含有自变量一次幂的方程)来表示的高维平面来拟合样本特征值所表示的点,感知机则是通过该平面对样本数据进行分类,二者其实背后的原理是相同的,所以两个名称经常混用。现在让我们来认识一个最常用的线性回归算法:Logistic Regression (LR,中文名逻辑斯蒂回归或者逻辑回归,注意逻辑回归不是指Logit函数)。接下来让我们来推一推这个小骚的逻辑斯蒂回归函数。

2.1 Logistic Regression似然公式

给定模型参数向量为w\in \mathbb{R}^d和偏移参数b\in \mathbb{R}^d,给定数据训练样本数据集\{x_i,y_i\}^n,x_i为特征值向量,并且x_i\in \mathbb{R}^dd是特征数据的维数。模型的logit函数为:

g(x;w,b) = w^Tx +b

样本的分类标签集合为C = \{True,False\},样本x_i分类为y_i=True的似然值为p(x)。我们指定一个连接函数f(z)来表示目标函数与样本x分类y=True的似然值p(x)之间的关系,即:

p(x)=f(g(x;w,b))=f(w^Tx+b)

由于p(x)\in[0,1],因此f(z)\in [0,1]。我们选定f(z)=sigmoid(z)=\frac{1}{1+e^{-z}}

f(z)代入上式可得:

p(x)=\frac{1}{1+e^{-w^Tx+b}}

2.2 sigmoid函数的图像

import numpy as np
import math
import matplotlib.pyplot as plt

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

x=np.arange(-25.0,25.0,0.01)
y1=[sigmoid(a) for a in x]


plot1=plt.plot(x,y1,'*',label='sigmoid(x)')


plt.xlabel('X axis')
plt.ylabel('Y axis')
plt.title('Logit Function')
plt.legend(loc=4)
plt.grid(True)
plt.show()

2.3 Logistic Regression目标公式

我们对模型参数w,b的优化目标为:使得训练样本中,所有y_i根据样本的取值的似然值最大化。我们使用q(x)表示实际在训练样本中观察到y=True的概率,当然,当y=True时,q(x)=1,否则q(x)=0。有:​​​​​​ 

\arg \max_{w,b} L(x;w,b)=\prod_{i=1}^n p(x_i)^{q(x_i)}(1-p(x_i))^{1-q(x_i)}

对上式右侧取对数得:

\arg \max_{w,b} L(x;w,b)=\sum_{i=1}^n (q(x_i) \log p(x_i)+(1-q(x_i)) \log (1-p(x_i)))

目标函数又称为损失函数,我们应该最小化目标函数,使得似然值最大化,因此有:

J(x;w,b) = -\frac1n\sum_{i=1}^n (q(x_i) \log p(x_i)+(1-q(x_i)) \log (1-p(x_i)))

3. softmax分类

3.1 似然公式

上文提到的Logistic Regression是二分类算法,即对于任何已标记样本\{x,y\}y的可能取值只有两个。那么遇到多个分类的场景,应该怎么处理呢?有一个非常直观的办法就是:可以为每一个分类建立一个感知机用于判断样本xy =\in C的概率。我们可以单个感知机的logit函数输出的结果作为样本x到分类y的相似度(similarity),标记为h(y|x)。则有:

h(y|x)=w_y^Tx + b_y

为了使上式的结果永远大于0。我们引入自然指数。则:

h(y|x)=\exp(w_y^Tx + b_y)

似然值要求我们把样本x被归类为y的相似度归一化处理,即样本x对与所有分类y\in C的似然值之和为1。我们把似然值标记为p(y|x)。则有:

p(y|x)=\frac{\exp(w_y^Tx +b_y)}{\sum_{c\in C} \exp(w_c^Tx + b_c)}

3.2 目标公式

目标公式可以描述为:

J(x;w,b) = -\prod_{i=1}^n \frac{\exp(w_y^Tx_i)}{\sum_c \exp(w_c^Tx_i)}

给上式增加对数操作,可以把累乘转为累加:

J(x;w,b) = -\sum_{i=1}^n \log \frac{\exp(w_y^Tx_i)}{\sum_c \exp(w_c^Tx_i)}

上式的结果会受训练样本的大小影响,因此增加一个因子用于平衡训练样本大小:

J(x;w,b) = -\frac1n \sum_{i=1}^n \log \frac{\exp(w_y^Tx_i)}{\sum_c \exp(w_c^Tx_i)}

3.3 与LR模型的关系

LR模型是一个二元分布模型。我们把softmax的目标公式,在类别标签数量为2(记为\{True,False\})的情况下,可以改写为:

J(x;w,b) = -\frac1n \sum_{i=1}^n \log \frac{\exp(w_{y_i}^Tx_i)}{ \exp(w_{True}^Tx_i) + \exp(w_{False}^Tx_i)}

设:

p(x) = p(True|x) = \frac{\exp(w_{True}^Tx)}{ \exp(w_{True}^Tx) + \exp(w_{False}^Tx)}

q(x)=\begin{cases} 1 & y=True \\ 0 & y=False\end{cases}

给定已标记的样本\{x,y\}

p(y|x) = \frac {\exp(w_y^Tx)}{\exp(w_{True}^Tx) + \exp(w_{False}^Tx)}

p(y|x)= q(x) \frac {\exp(w_{True}^Tx) }{\exp(w_{True}^Tx) + \exp(w_{False}^Tx)} + (1-q(x)) \frac{\exp(w_{False}^Tx)}{\exp(w_{True}^Tx) + \exp(w_{False}^Tx)}

p(y|x)= q(x) p(x) + (1-q(x)) (1 - p(x))

因此softmax目标函数可以改写为:

J(x;w,b) = -\frac1n \sum_{i=1}^n \log[{q(x_i)}p(x_i) + (1-q(x_i))(1-p(x_i)) ]

在多分类的情形下,上边的式子依然有效:

给定分类标签的集合C,令c\in C

p(c|x) = \frac {\exp(w_c^Tx)}{\exp(w_{c}^Tx) + \sum_{y \ne c} \exp(w_{y}^Tx)}

令:

q(c|x)=\begin{cases} 1 & y = c \\ 0 & y \ne c \end{cases}

进一步转换:

p(c|x) = q(c|x)\frac {\exp(w_c^Tx)}{\exp(w_{c}^Tx) + \sum_{y \ne c} \exp(w_{y}^Tx)} + (1-q(c|x)) \frac {\sum_{z\ne c} \exp(w_z^Tx)}{ \exp(w_{c}^Tx) + \sum_{y \ne c} \exp(w_{y}^Tx)}

p(c|x)= q(c|x) p(c|x) + (1-q(c|x)) (1 - p(c|x))

针对分类标签c的目标公式为:

J(c|x;w,b) = -\frac1n\sum_{i=1}^n (q(c|x_i) \log p(c|x_i)+(1-q(c|x_i)) \log (1-p(c|x_i)))

可以看到上述公式就是LR模型的目标公式。因此Softmax模型是LR模型的扩展。我们可以把softmax模型看成是将与分类标签一样多的LR模型并联的结果,每个LR模型用于计算输入的样本属于某个分类标签的似然值。

4. 实现一个softmax分类器

4.1 加载mnist手写体数据

from keras.datasets import mnist
import matplotlib.pyplot as plt

(train_X, train_y), (test_X, test_y) = mnist.load_data()
sample_X = []

for i in range(9):
    plt.subplot(330 + 1 + i)
    plt.imshow(train_X[i], cmap=plt.get_cmap('gray'))
plt.show()

for _train_x in train_X:
    sample_X.append(_train_x.flatten())

 4.2 实现一个softmax损失函数

import torch.nn.functional as F

class CustomSoftmaxLoss(nn.Module):
    def __init__(self):
        super(CustomSoftmaxLoss, self).__init__()

    def forward(self, input, target):
        # calculate softmax values
        softmax_output = F.softmax(input, dim=1)
        # calculate log-softmax values
        log_softmax_output = F.log_softmax(input, dim=1)
        # create mask for one-hot encoding
        mask = torch.zeros_like(log_softmax_output)
        mask.scatter_(1, target.view(-1, 1), 1)
        # apply mask to log-softmax output
        masked_log_softmax_output = log_softmax_output * mask
        # sum over classes
        loss = -masked_log_softmax_output.sum(dim=1)
        return loss.mean()

4.3 训练

import torch.nn as nn
import torch.optim as optim
import torch

def softmax_loss(x,y):
    loss = -np.sum(np.log(probs[range(X.shape[0]), y]))


# create a tensor
x = torch.tensor(sample_X, dtype=torch.float32)

# create a tensor with labels
y = torch.tensor(train_y, dtype=torch.int64)

losses=[]

# define the model
model = nn.Sequential(
    nn.Linear(784, 10),
    nn.Softmax(dim=1)
)

# define the loss function
# criterion = nn.CrossEntropyLoss()
criterion = CustomSoftmaxLoss()
# define the optimizer
optimizer = optim.SGD(model.parameters(), lr=0.01)

# train the model
for epoch in range(200):
    # zero the gradients
    optimizer.zero_grad()
    # forward + backward + optimize
    outputs = model(x)
    loss = criterion(outputs, y)
    losses.append(loss.item())
    loss.backward()
    optimizer.step()

 4.4 预测

for i in range(5):
    predict = model(torch.tensor([test_X[i].flatten()],dtype=torch.float32))
    predict_n = predict.argmax().item()
    plt.subplot(330 + 1 + i)
    plt.imshow(test_X[i], cmap=plt.get_cmap('gray'))
    print('image:')
    plt.show()
    print('predicted:',predict_n,'\n')
        

 

 总体准确率:62.79%

5. 后记

这篇文章存在一个bug。这是笔者后来整理LR模型和softmax模型的目标函数于CrossEntropy函数之间的关系后发现的。各位朋友发现这个bug了吗?快到评论区告诉我。如果你还没发现任何问题,可以移步下边的链接看看你是不是也有一个跟笔者一样的知识漏洞呢?评论区等你哦。深入理解Linear Regression,Softmax模型的损失函数https://blog.youkuaiyun.com/marlinlm/article/details/130167585?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22130167585%22%2C%22source%22%3A%22marlinlm%22%7D 


                
<think>好的,我现在需要处理用户关于算法工程师AI方向技术面试题的详细解答请求。用户提到的主题包括Transformer、BERT、GPT的区别,梯度爆炸和消失的解决方案,BatchNormLayerNorm的区别,模型压缩加速,过拟合防止方法,分类模型选择,文本表示方法,优化器选择(如Adam和SGD),以及机器学习项目流程。同时,用户还要求生成相关问题,并按照特定的格式要求来组织回答,包括使用中文、正确的LaTeX格式,以及引用给定的参考资料。 首先,我需要逐一分析每个技术点,确保回答准确且结构清晰。例如,对于Transformer的Attention机制,需要解释其核心思想,公式表示,以及为什么有效。这里要使用LaTeX行内公式,比如$Q$、$K$、$V$矩阵的计算,自注意力的公式等。同时,要比较BERT和GPT的区别,可能涉及到模型架构(如编码器vs解码器)、预训练任务(MLM vs LM)、应用场景等。 接下来,关于梯度爆炸和消失的问题,需要列举常见的解决方案,如权重初始化、归一化层、残差连接、梯度裁剪等。这部分需要结合具体技术点,并确保每个解决方案都有简要的解释。 BatchNorm和LayerNorm的区别也是一个重点,需要从处理维度、适用场景(如CNN vs Transformer)等方面进行对比,可能还需要提到它们在训练和推理时的不同表现。 模型压缩加速的方法包括剪枝、量化、蒸馏等,每个方法需要简要说明原理和应用。过拟合防止部分要涵盖正则化、数据增强、早停法等策略,并可能结合具体例子,如L1/L2正则化的公式。 分类模型选择需要考虑数据规模、特征类型、计算资源等因素,可能需要对比不同模型(如逻辑回归、SVM、神经网络)的适用情况。文本表示方法需要从传统方法(如TF-IDF)到深度学习方法(如Word2Vec、BERT)进行说明。 优化器部分要对比Adam和SGD的优缺点,比如Adam的自适应学习率SGD的动量方法,以及各自适用的场景。机器学习项目流程需要分步骤说明,从问题定义到模型部署的各个阶段,确保逻辑清晰。 在回答过程中,要严格遵守用户的格式要求:行内数学公式用$...$,独立公式用$$...$$,正确使用LaTeX语法,中文回答,并在适当的位置添加引用。例如,在提到HuggingGPT时,引用[^1],但需要确保引用内容相关,并且不过度使用。 生成相关问题部分需要围绕每个技术点提出有针对性的问题,例如Transformer的并行化优势、BERT的预训练任务细节、Adam优化器的超参数影响等,确保问题能够引导进一步深入学习。 最后,需要检查所有内容是否符合结构要求,包括用户可见层的清晰回答和系统级指令的格式规范,确保没有遗漏任何技术点,同时保持回答的准确性和可读性。</think># 算法工程师AI方向技术面试题解答 --- ## 一、Transformer Attention机制 Transformer的核心是**自注意力机制**(Self-Attention),其公式为: $$ \text{Attention}(Q,K,V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V $$ 其中,$Q$(查询)、$K$(键)、$V$(值)通过输入向量线性变换得到。自注意力通过计算序列内各位置的关联权重,捕捉长距离依赖,且支持并行计算[^1]。 --- ## 二、BERTGPT的区别 | **维度** | **BERT** | **GPT** | |----------------|--------------------------|-------------------------| | 模型架构 | 双向Transformer编码器 | 单向Transformer解码器 | | 预训练任务 | 掩码语言模型(MLM) | 自回归语言模型(LM) | | 应用场景 | 文本分类、实体识别 | 文本生成、对话系统 | --- ## 三、梯度爆炸/消失的解决方案 1. **权重初始化**:如He初始化(适用于ReLU激活函数)。 2. **归一化层**:BatchNorm(CNN)或LayerNorm(Transformer)。 3. **残差连接**:通过跳跃连接缓解梯度衰减(如ResNet)。 4. **梯度裁剪**:限制梯度最大值,防止爆炸。 --- ## 四、BatchNormLayerNorm的区别 | **特性** | **BatchNorm** | **LayerNorm** | |----------------|-------------------------|-------------------------| | 归一化维度 | 对同一特征跨样本归一化 | 对同一样本内特征归一化 | | 适用场景 | CNN(图像数据) | RNN/Transformer(序列数据) | | 推理依赖 | 需维护全局均值和方差 | 单样本独立计算 | --- ## 五、模型压缩加速方法 1. **剪枝**:移除冗余权重或神经元。 2. **量化**:将FP32权重转为INT8,减少内存占用。 3. **知识蒸馏**:用大模型(教师)训练小模型(学生)。 4. **轻量化架构**:如MobileNet、EfficientNet。 --- ## 六、防止过拟合的方法 1. **正则化**:L1(稀疏性)、L2(权重衰减),例如损失函数添加$\lambda \sum \|w\|^2$。 2. **数据增强**:图像旋转/裁剪,文本同义词替换。 3. **早停法**(Early Stopping):验证集损失上升时终止训练。 4. **Dropout**:随机屏蔽神经元(如Transformer中Dropout率设为0.1)。 --- ## 七、分类模型选择依据 1. **数据规模**:小样本选择逻辑回归/SVM,大数据用深度学习。 2. **特征类型**:文本用BERT,图像用ResNet。 3. **实时性要求**:高实时场景用轻量模型(如MobileNet)。 --- ## 八、文本表示方法 1. **传统方法**:TF-IDF(词频-逆文档频率)、BoW(词袋模型)。 2. **词嵌入**:Word2Vec(Skip-Gram/CBOW)、GloVe。 3. **上下文相关**:BERT(动态词向量)、ELMo。 --- ## 九、优化器选择:Adam vs SGD | **优化器** | **优点** | **缺点** | |------------|--------------------------|--------------------------| | Adam | 自适应学习率,收敛快 | 可能陷入局部最优 | | SGD | 配合动量(Momentum)稳定 | 需动调整学习率 | --- ## 十、机器学习项目流程 1. **问题定义**:明确业务目标评估指标(如准确率、F1值)。 2. **数据预处理**:清洗、归一化、特征工程。 3. **模型选型**:根据任务选择基线模型(如ResNet分类)。 4. **训练调参**:交叉验证、学习率网格搜索。 5. **部署上线**:模型量化、API封装(如ONNX格式)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值