线性回归和分类问题

线性回归:

 

利用PyTorch 的框架进行线性回归。

1.数据集:x,y数据集有三个样本,一个维度。

维度就是特征,几个维度就是几个特征。比如说数据集是雪糕,100个不同雪糕就是100个不同的样本。雪糕的颜色,形状,价格等等就是特征。

2.模型:y=w*x+b模型,使用linear()函数就可以计算。

构造LinearModel类,继承父类nn.Module的属性和方法。

为什么使用super()函数?

如果直接在子类LinearMode添加__init__(self)函数,会覆盖掉父类的属性和方法,使用super函数能继承所有父类的属性和方法。Python 继承 (w3school.com.cn)

3.损失函数 nn.MSELoss(size_average=True,reduce=True),默认值都是True。

size_average均值,reduce是否求和降维。

4.优化器 optim.ASGD(model.parameters(),lr)

optim里面有很多不同的优化器,效果不同。

model.parameters()可以找到所有的梯度值,lr是学习率。

 5.训练过程:计算预测值,计算损失值,梯度清零,反向传播计算梯度值,更新权重。

import torch 
#数据集 列是样本,行是特征,只有一个特征
x_data=torch.Tensor([[1.0],[2.0],[3.0]])
y_data=torch.Tensor([[2.0],[4.0],[6.0]])
#设计类
class LinearModel(torch.nn.Module):
    def __init__(self):
        #super(class,self).xxx(形参)
        #当前的类继承父类__init__()
        #当您添加 __init__() 函数时,子类将不再继承父的 __init__() 函数。

        #注释:子的 __init__() 函数会覆盖对父的 __init__() 函数的继承。

        #如需保持父的 __init__() 函数的继承,请添加对父的 __init__() 函数的调用:
        #通过使用 super() 函数,您不必使用父元素的名称,它将自动从其父元素继承方法和属性。
        super(LinearModel,self).__init__()
        #用父类初始化的方法初始化linear
        #torch.nn.Linear是一个类,()表示x,y是一维的,即只有一个特征
        #用nn.Linear()给linear赋值
        #Linear内部有weight和bias
        self.linear = torch.nn.Linear(1,1)
    #计算预测值y
    def forward(self,x):
        #self 参数是对类的当前实例的引用,用于访问属于该类的变量。
        y_pred = self.linear(x)
        return y_pred
#用LinearModel的类创建新的对象model
model = LinearModel()

#损失函数
criterion = torch.nn.MSELoss(size_average=False)

#优化器(w,学习率)
#param是权重 
#data (Tensor) – parameter tensor.
#requires_grad (bool, optional) – 默认为True,
optimizer = torch.optim.ASGD(model.parameters(),lr=0.01)
#训练过程
for epoch in range(1000):
    y_pred = model(x_data)
    #loss不是值,而是对象
    loss = criterion(y_pred,y_data)
    print(epoch,loss.item())  
    
    optimizer.zero_grad()
    #反向传播
    loss.backward()
    #得到新的,更新w
    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.item())
w: 1.9996113777160645
b: 0.0008697551093064249
y_pred: 7.99931526184082

logistic模型:

分类问题与线性回归基本一致,不同的地方在于:

1、输出,不是输出一个值,而是输出一个类别的概率;

2、损失函数:线性回归是MSELoss,分类是BCELoss;

这边的log的底数应该是大于0的,logy是增函数。

交叉熵是用来衡量两个概率分布差别。

数据集是作为正确结果(如[0,0,1]),把输出作为预测结果(如[0.1,0.1,0.4]),通过BSELoss函数计算,如果交叉熵的值小说明概率接近真实值。损失函数之交叉熵(一般用于分类问题)_ZJE_ANDY的博客-CSDN博客_信息量计算公式https://blog.csdn.net/u014453898/article/details/81559462

交叉熵公式:

当数据集也就是真实值y=1时,预测值\widehat{y}越接近1,损失值越接近0;

当数据集也就是真实值y=0时,预测值\widehat{y}越接近0,损失值越接近0。 

3、在前馈的过程中,需要输出送入sigmoid函数中(y_pred =torch.sigmoid(self.linear(x))),目的是将输出值映射到0到1之间。

测试:

np.linspace(start, end, num,endpoint,retstep)

start:起始值。end:结束值。num:取数的数量。endpoint:是否取结束值。restep:步长

>>> np.linspace(2.0, 3.0, num=5)
    array([ 2.  ,  2.25,  2.5 ,  2.75,  3.  ])
>>> np.linspace(2.0, 3.0, num=5, endpoint=False)
    array([ 2. ,  2.2,  2.4,  2.6,  2.8])
>>> np.linspace(2.0, 3.0, num=5, retstep=True)
    (array([ 2.  ,  2.25,  2.5 ,  2.75,  3.  ]), 0.25)

numpy.linspace使用详解_有一种宿命叫无能为力的博客-CSDN博客icon-default.png?t=M85Bhttps://blog.csdn.net/you_are_my_dream/article/details/53493752

import torch
import numpy as np
import matplotlib.pyplot as plt
#数据集
#与线性回归不同的是:y只有0或1两种输出
#x—_data表示学习时间,单位是小时
#y_data:0是不及格,1是及格
#y_pred=0.5对应的x是2.5
x_data = torch.Tensor([[1.0],[2.0],[3.0]])
y_data = torch.Tensor([[0],[0],[1]])
epoch1=[]
item=[]
#模型的构造
class Logisitic(torch.nn.Module):
    def __init__(self):
        super(Logisitic,self).__init__()
        self.linear = torch.nn.Linear(1,1)
    def forward(self,x):
        #老师代码y_pred = F.sigmoid()不能使用
        #在预测值y的基础上计算激活函数,是输出y的范围能在【0,1】之间
        y_pred = torch.sigmoid(self.linear(x))
        return y_pred
model = Logisitic()
#和线性回归所用的损失函数不同,这里使用的是交叉熵。
criterion = torch.nn.BCELoss(size_average=False)
optimizer = torch.optim.SGD(model.parameters(),lr=0.01)
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()
    epoch1.append(epoch)
    item.append(loss.item())
#在【0,10】之间取200个值
x = np.linspace(0,10,200)
#将x变成矩阵200*1
x_t = torch.Tensor(x).view(200,1)
y_t = model(x_t)
#拿到数组
y= y_t.data.numpy()
plt.plot(x,y)
#y_pred=0.5对应的x是2.5,0.5是分界线。
plt.plot([0,10],[0.5,0.5],c='r')
plt.xlabel('Hours')
#概率
plt.ylabel('p')
plt.show()

输出概率0.5以上 就是类1,及格。

输出概率0.5以下 就是类0,不及格。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值