深度学习实践——逻辑斯蒂回归

感谢学习视频:https://www.bilibili.com/video/BV1Y7411d7Ys?p=6&vd_source=2314316d319741d0a2bc13b4ca76fae6
本节考虑分类问题,建立模型是逻辑斯蒂回归,虽然名字叫回归,但处理分类问题的。

标题

在这里插入图片描述
这是之前用线性回归模型。
在这里插入图片描述
在这里我们估计的y是属于连续空间,像这种任务叫回归分析
但机器学习中做的多的是分类问题。
在这里插入图片描述
MNIST是一个手写数字数据集,有10个类别,如果用回归方法做分类问题,比如说:第0个类别,就让y=0;第1个类别就让y=1,这种思想是不好的。因为这些0-9的类别没有一维实数空间数值大小的含义,即类别之间不是数值比较,即图片中的9没有比图片中的0抽象概念(类别)大。所以,分类问题不能用线性回归这种模型简单的输出0-9来做。
分类问题的核心是概率:根绝输入x,得到y输出为0的概率,输出为2的概率…。概率是满足一个分布的,概率之和为1,从概率值里找最大概率值。
在这里插入图片描述
MNIST是最基础的数据集,用来测量学习器的性能指标,所以在pytorch框架中有一个 torchvison 包,这个包里有一个模块提供相应的数据集,一些比较流行的数据集都有。但,安装torchvison时他不会把数据集包含在包里面,如果你没有下载该数据集,可用上面的程序自动下载。【少部分不支持自动下载】
参数1:数据集存储路径;参数2:train=True表示训练集,False表示测试集;参数3:download=True联网自动下载,False表示已下载了。
在这里插入图片描述
CIFAR数据集:32*32的图片,10个类别,
下载过程和参数设置与上面一致。
在这里插入图片描述
在这个数据集下,原来是回归问题,就是学习时间与他最后拿多少分?而在分类任务里,就是他最后是否通过考试?【过;不过,两个类别的分类问题 = 二分类问题】
二分类问题最终要计算的就是两个概率【实际计算一个即可,因为两者加和等于1】
如果计算出来的概率非常接近0.5,意味着我们的学习器对这个数据样本的类别并无十足把握。
在这里插入图片描述
在这里插入图片描述
之前用线性模型,y_hat=wx+b 输出为一个实数,而分类问题我们需要的是概率属于【0,1】,所以我们需要把实数映射到【0,1】,即找一个函数来实现: logistic 函数
可以观察到这个函数有个特点: 超过某一阈值后,剩余一段增长的很慢,他的导数会变得越来越小。
这种函数数学中称之为饱和函数
logistic 函数的导数图像像正态分布的分布函数。【它就是因正态分布而产生的函数】
sigmoid Function

  1. 函数值有极限
  2. 单调增
  3. 饱和函数
    在这里插入图片描述
    这些函数是【-1,1】
    在所有sigmoid函数中最出名的就是logistic 函数,所以,现在在一些框架中,直接把logistic 函数称为sigmoid 【约定俗称】。
    模型的不同:
    在这里插入图片描述
    损失函数改变
    在这里插入图片描述
    loss原来用的是MSE,y_hat-y是有意义的,是数轴上两者的距离,目的是让这个距离最小化。而现在输出是分布分布不是数轴上的距离,实际表示的是在这里插入图片描述
    数据集的y有可能为0或1,
    在这里插入图片描述
    想比较的是两个分布之间的差异。计算分布的差异。
    计算两个分布直接差异,在概率论中,比如:KL散度、cross-entropy【交叉熵】等。
    交叉熵公式:
    在这里插入图片描述
    假如有两个分布,Pd和Pt
    在这里插入图片描述
    用这个公式来表示两个分布之间差异性的大小,越大越好。
    在这里,我们用了一个二分类的交叉熵:
    在这里插入图片描述
    相当于y分布和y_hat分布,两者的差异。加个负号,表示越小越好
    在这里插入图片描述
    当y=1时,要想最小,y_hat必须要大,但又不能超过1,所以接近1就是最大。
    当y=0时,要想最小,y_hat必须小,所以越接近0越好。
    所以根据这样一个目标函数,求最小值时就可以让分布项尽可能去和它的真实分类去接近。
    这个二分类函数称为:BSE函数
    在这里插入图片描述
    可以看到 预测越接近,BSCloss越小。
    在这里插入图片描述
    这个模型名字叫LogisticRegressionModel,在构造函数部分基本一致,因为sigmoid函数李米娜没有参数,即不需要再构造函数里去初始化它 ,因为没有参数去训练,后面直接调用即可。
    sigmoid函数定义在 torch.nn.functional 函数包里。先进行linear变换,将输出应用到sigmoid中。
    F.sigmoid(self.linear(x))和torch.sigmoid(self.linear(x)) 两者计算结果同,前者是方法,后者是一层。
    在这里插入图片描述
    其次就是loss的变化,用BCE交叉熵求loss,初始化只需要设置是否要求每个批量的均值,求不求的关键影响到将来学习率的设置,因为如果求均值,前面有一个小常数,而后面求导也会乘上小常数。
    这个框架可胜任大部分的网络模型的编写,编写任何一个网络模型都是四步:1.准备数据【有可能读数据部分很复杂,封装一下,封装到一个模块里,提供一些工具函数或工具类,然后把数据读出来】2. 模型构造,定义相应模型【如果模型比较复杂,单独放在一个文件夹,然后构造这些模型,通过主程序 import 进来】 3. loss和优化器【可以自己进行设计】4.训练循环。
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述

整体代码:

import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE" #这是因为anaconda的环境下存在多个libiomp5md.dll文件,如果不加,画图报错
import numpy as np 
import matplotlib.pyplot as plt
import torch
import torch.nn.functional as F 
# 现在用 torch的 Tensor,用mini-batch的风格
x_data = torch.Tensor([[1.0], [2.0], [3.0]])
y_data = torch.Tensor([[0.0], [0.0], [1.0]])

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))
        return y_pred

model = LogisticRegressionModel() #实例化模型

criterion = torch.nn.BCELoss(size_average =False) # BCE损失
optimizer = torch.optim.ASGD(model.parameters(), lr=0.01) #优化器
for epoch in range(100): #训练循环
    y_pred = model(x_data) #计算y_hat
    loss = criterion(y_pred, y_data) # 计算loss
    print(epoch, loss.item()) 

    optimizer.zero_grad() #清梯度
    loss.backward() #反向传播
    optimizer.step()
# output weight and bias
# print('w = ', model.linear.weight.item())
# print('b = ', model.linear.bias.item())
# 测试集
# test model
x_test = torch.Tensor([[4.0]])
y_test = model(x_test)
print('y_pred = ', y_test.data)
# 做测试 画图
x = np.linspace(0,10,200) # 0-10h采200个点
x_t = torch.Tensor(x).view((200,1)) #将200个点编程200*1的矩阵 ;类似于numpy中的reshape
y_t = model(x_t)# 将得到的张量送到模型里
y = y_t.data.numpy() # 将y数据拿出
plt.plot(x, y) # 绘图
plt.plot([0,10],[0.5,0.5],c='r')
plt.xlabel('Hours')
plt.ylabel('Probability of Pass')
plt.grid()
plt.show()

在这里插入图片描述
可以看到这个图像非常像logsitc 函数,因为数据经过线性变换,就是缩放、上下平移,然后放入logstic函数,肯定出来就是和logstic函数图像差不多的。
可以看到差不多2.5左右概率就到50%,即过与不过的分界线了。即低于2.5小时,肯定判定不过“0”,超过2.5小时,判定过“1”.

参考:
http://biranda.top/Pytorch%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0007%E2%80%94%E2%80%94%E5%88%86%E7%B1%BB%E9%97%AE%E9%A2%98/#%E7%86%B5

猜你喜欢

转载自blog.csdn.net/qq_41175681/article/details/129698498