Loading...

分类与回归

回归可以用于预测多少的问题。 比如预测房屋被售出价格,或者棒球队可能获得的胜场数,又或者患者住院的天数。事实上,我们也对分类问题感兴趣:不是问“多少”,而是问“哪一个”。

机器学习实践者用分类这个词来描述两个有微妙差别的问题:

    1. 我们只对样本的“硬性”类别感兴趣,即属于哪个类别;
    1. 我们希望得到“软性”类别,即得到属于每个类别的概率。 这两者的界限往往很模糊。其中的一个原因是:即使我们只关心硬类别,我们仍然使用软类别的模型。


Softmax 回归是一个多类分类模型使用, Softmax 操作子得到每个类的预测置信度,使用交叉熵来来衡量预测和标号的区别。

这里的真实概率分别为0和1:


损失函数


L2 loss 蓝色线是loss函数本身,绿色线是似然函数,橘红色是loss函数的梯度。梯度说明越远离准确估计,则梯度下降越快,权重更新快,这也是它的特性



L1 Loss 绝对值。三条线同上。同样,在远离0点的梯度下降速度一致,权重更新稳定。但是缺点是在真实值附近时,这个就不会很稳定



huber鲁棒loss,当预测值和真实值差距大的时候是一个绝对值误差,当预测值和真实值靠的近的时候,就是一个平方误差。这个loss就结合了两者的优势又避免了两者的劣势。


交叉熵损失函数: 表示为 H(p,q)H(p, q),这是一个衡量两个概率分布 ppqq 差异的函数。公式是:

H(p,q)=ipilog(qi)H(p, q) = \sum_i -p_i \log(q_i)

这里 pp 是真实概率分布,qq 是预测概率分布,索引 ii 遍历所有可能的类别。对于每个类别 ii,将真实概率 pip_i 与预测概率 qiq_i 的对数相乘,并对所有类别进行求和,然后取负数。

分类问题的损失函数: 用 l(y,y^)l(y, \hat{y}) 表示,这是在实际的分类问题中用来计算单个样本损失的函数。公式是:

l(y,y^)=iyilog(y^i)l(y, \hat{y}) = - \sum_i y_i \log(\hat{y}_i)

其中 yy 是实际的标签的独热编码表示,而 y^\hat{y} 是模型预测的概率分布。这个表达式计算的是真实标签对应的类别的预测概率的负对数。由于 yy 是独热编码,因此除了正确类别的项,其他项因为 yiy_i 为0都不会对和产生贡献。所以,这个表达式简化为对单个正确类别的预测概率的负对数,即 log(y^y)-\log(\hat{y}_y),其中 yy 是正确类别的索引。


softmax代码

在softmax函数中,输入X是一个二维张量(或者说矩阵),其中每一行代表一个样本,每一列代表一个类别。

在你的例子中,X的形状是(2, 3),意味着有2个样本,每个样本有3个类别。

当你对X_exp进行求和操作时:

  • X_exp.sum(1, keepdim=True):这是沿着列方向(即第1维,索引从0开始)进行求和,结果的形状是(2, 1)。这意味着对每个样本的所有类别进行求和。

在softmax函数的最后,X_exp/partition是对每个样本的所有特征值进行归一化,使得每个样本的所有特征值的和为1。这使得softmax的输出可以被解释为每个样本属于每个类别的概率。

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
def softmax(X):
X_exp=torch.exp(X)
print("X_exp",X_exp.shape,X_exp)
"""
X_exp torch.Size([2, 5])
tensor([[0.6880, 0.8210, 2.1784, 1.2788, 4.2303],
[1.2565, 0.1625, 0.7192, 0.3345, 0.6678]])
"""
partition=X_exp.sum(1,keepdim=True) #对行求和保留列
partition1=X_exp.sum(0,keepdim=True) #对列求和保留行
print("partition",partition.shape,partition)
print("partition1",partition1.shape,partition1)
"""
partition torch.Size([2, 1])
tensor([[9.1965],
[3.1404]])

partition1 torch.Size([1, 5])
tensor([[1.9445, 0.9834, 2.8976, 1.6133, 4.8981]])
"""
print("X_exp/partition",(X_exp/partition).shape,X_exp/partition)
"""
X_exp/partition torch.Size([2, 5])
tensor([[0.0748, 0.0893, 0.2369, 0.1391, 0.4600],
[0.4001, 0.0517, 0.2290, 0.1065, 0.2126]])
"""
return X_exp/partition


import torch

# 初始化权重W和偏置b
W = torch.normal(0, 1, (5, 10))
b = torch.zeros(10)


X = torch.normal(0, 1, (2, 5))
X_prob = softmax(X)
print(X)
print(X_prob, X_prob.sum(1))

花式索引:"

y 是一个包含两个类别标签的张量,而 y_hat 是一个包含两个样本对每个类别的预测概率的张量。

y_hat[[0, 1], y] 这行代码的作用是选择 y_hat 中对应于真实标签的预测概率。具体来说:

  • [0, 1] 是样本的索引。
  • y 是每个样本的真实标签。

因此,y_hat[[0, 1], y] 选择了第0个样本的类别0的预测概率和第1个样本的类别2的预测概率,即 [y_hat[0,0], y_hat[1,2]]

1
2
3
4
y = torch.tensor([0, 2])
y_hat = torch.tensor([[0.1, 0.3, 0.6], [0.3, 0.2, 0.5]])
#y_hat[[0,1],[0,2]] --> [y_hat[0,0],y_hat[1,2]]
print(y_hat[[0, 1], y])