针对分类问题,根据输入的 x 来估计输出 y 它是0,1,2,3……9的概率分别是多少,如果只有这10个分类的话,它们所有的概率值之和为1,然后再在这些概率值当中找最大的那个,即可判定当前 x 的所属分类
核心:【不是要让输出 y 去等于1-9这些实数,而是要计算它所对应的实数的概率,选择概率最大的那一项作为最后预测的结果】
回归任务的输出是将来能拿的分(point),分类任务不再关注这个,而转向未来能够通过考试(pass/fail)一个最基础的二分类问题,涉及只有 pass 和 fail ,只有0和1两个分类。
数学上表示为
若 ,即认为它能通过考试,即选择它是1这个分类,若概率为0.5,此时无法判断它到底属于哪个分类,分类问题中我们实际要计算的是
。
逻辑斯蒂函数能保证输出在0-1之间,而逻辑斯蒂回归和线性模型的明显区别是在线性模型的后面,添加了激活函数,属于一种非线性变换。没有激活函数的话,函数将一直是线性的。
线性回归:在数轴上计算 与
之间的距离,输出的是一个数值
二分类:输出的是两个分布之间的差异,用交叉熵衡量
最新版的话 F.sigmoid 可能会报错,直接用 torch.sigmoid 就行
之前线性回归的时候用的是MSE(均方根误差),现在逻辑斯蒂回归用的是BCE(交叉熵)
这节代码如下:
import torch
# import torch.nn.functional as F
# prepare dataset 原来y_data是2.0,4.0,6.0,现在是0,0,1的分类
x_data = torch.Tensor([[1.0], [2.0], [3.0]])
y_data = torch.Tensor([[0], [0], [1]])
#design model using class 在模型设计上只需要添加一个logistic的非线性变换
class LogisticRegressionModel(torch.nn.Module):
def __init__(self):
super(LogisticRegressionModel, self).__init__()
self.linear = torch.nn.Linear(1,1)
def forward(self, x):
# y_pred = F.sigmoid(self.linear(x))
y_pred = torch.sigmoid(self.linear(x))
return y_pred
model = LogisticRegressionModel()
# construct loss and optimizer 现在用BCE损失,不用MSE
# 默认情况下,loss会基于element平均,如果size_average=False的话,loss会被累加。
criterion = torch.nn.BCELoss(size_average = False)
optimizer = torch.optim.SGD(model.parameters(), lr = 0.01)
# training cycle forward, backward, update 训练循环没有变化
for epoch in range(1000):
y_pred = model(x_data)
loss = criterion(y_pred, y_data)
print(epoch, loss.item())
optimizer.zero_grad()
loss.backward()
optimizer.step()
print('w = ', model.linear.weight.item())
print('b = ', model.linear.bias.item())
x_test = torch.Tensor([[4.0]])
y_test = model(x_test)
print('y_pred = ', y_test.data)
这个框架的结构可以胜任大部分网络模型的编写
1.Prepare dataset——准备数据
2.Design model using Class——构造模型,一般从nn.Module继承
3.Construct loss and optimizer——损失和优化器
4.Training cycle——做训练循环