线性回归:
利用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时,预测值越接近1,损失值越接近0;
当数据集也就是真实值y=0时,预测值越接近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博客https://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,不及格。