机器学习的分类问题,使用logistics回归(虽然叫回归,但是是做分类任务的)
一:简介
MINIST Dataset 一个手写数字的数据集
其中有10分类,0,1,2,....,9
未来y得到的结果是属于一个集合,集合中的数值为{0,1,2,....,9},我们需要估算的是y是哪一个数字。
注意:如果是第一个类别让数值等于0,第二个类别数值等于1这种思路非常不好。举个例子,当我们给一个手写的7时,我们知道手写的7与9更接近,与8反而差的多,但是当我给出一个手写的7作为输入时,更接近7,9,此时8作为7后一个输出就比较尴尬,因此通常不使用这样的思想。
此时要注意,手写出的数字,其实在抽象上是没有大小之分的,不能说写的9就比写的0大,只有给他们附上数字的定义时,才有大小之分。
正确的思路应该是,更根据输入的x,输出为0的概率是多少,输出为1的概率是多少,以此类推,最终所有的概率值相加结果为1。最后找出最大的概率,就是我们的预测的最终结果。
下载MNIST Dataset
import torchvision
#root输入下载的地址 train训练集还是测试集 download表示是否在网上进行下载,如果第一次就设True 已经下载完就不会自动下载了
train_set = torchvision.datasets.MNIST(root="./dataset/mnist",train = True, download=True)
test_set = torchvision.datasets.MNIST(root="./dataset/mnist/",train = False, download=True)
但是由于网络限制,这种方法通常会报错,可以尝试下面解决方法:
【已解决】MNIST数据集下载失败:HTTP Error 403: Forbidden-CSDN博客
还有其他很多的分类的数据集,大家可以在网上自行了解。
二:回归任务和分类任务的区别
左边是回归任务,右边是分类任务。
回归任务:y表示在输入x的情况下,未来y可以得到的数值。
分类任务:y不表示可以拿多少数值,而是是否通过。如果只是二分类,就类似与我们数学中的01分布。所以在分类任务中,我们需要计算的每一个输入的概率。
三:logistics函数
由于我们在线性模型中得到的输出为一个实数,但是在分类任务中最后的结果是属于[0,1]范围内的,所以需要一个映射函v
那现在做分类的时候,工作就简单了。现在还是使用线性模型,得到的结果使用logistics函数再算一下。
当然还有其他的sigmoid函数(函数的极限是从-1到1)(都是单调增函数)(都是饱和函数):
四:logistics回归模型
整体过程没有发生变化,主要就是再线性回归模型外再加上了一个logistics函数操作。
模型变化后,相应的损失函数也会发生变化。损失函数变化导致的损失值如何变化?
那为什么下面一个函数可以进行分布间的差异呢?(下图中BC其实是BCE)
看一下BCE的值,发现y与y_hat相差越大时,loss值越大。Mini-batch 是几个损失值的平均值。
代码如下:(在看代码前,看一下本节四第一张图片,线性回归和logistics回归在计算y_hat的差别)
import torch.nn.functional as F
class LogisticRegressionModel(torch.nn.Module):
def __init__(self):
#与之前线性的一致,因为sigma 是没有数值的
super(LogisticRegressionModel,self).__init__()
self.linear = torch.nn.Linear(1,1)
def forward(self,x):
#logistic回归和线性回归就差F.sigmoid这一步的运算
y_pred = F.sigmoid(self.linear(x))#先进行一次线性变换,随后进行sigmoid运算
return y_pred
loss函数代码如下(之前线性选择MSE,现在选择BCE):
criterion = torch.nn.BCELoss(size_average=False)