Linear回归与Logistic回归

回归问题与分类问题

回归问题

回归问题主要关注的是预测一个数值型的目标变量(因变量)。这种预测是基于一个或多个输入特征(自变量)的。回归模型的目标是找到一个最佳拟合线或曲面,使得预测值与实际值之间的误差最小。常见的回归问题包括房价预测、股票价格预测、销售额预测等。在这些例子中,输出变量(如房价、股票价格、销售额)都是连续的数值

分类问题

分类问题则关注于预测一个离散型的目标变量。这意味着输出变量只能取有限个离散值,通常用于识别或分类。例如,在电子邮件分类中,模型可能需要将邮件标记为“垃圾邮件”或“非垃圾邮件”;在图像识别中,模型可能需要将图像分类为“猫”、“狗”或“其他”。这些输出变量(如邮件类别、图像类别)都是离散的,且通常表示为标签或类别。

线性回归模型(Linear Regression)

线性回归模型是一种常用的统计方法,用于探索变量之间的关系,特别是当一个变量(因变量)受一个或多个变量(自变量)影响时。该模型的基本假设是因变量与自变量之间存在线性关系。通过拟合一条最佳直线(回归线),模型能够描述这种关系,并用于预测因变量的值

一元线性回归:

y = β0 + β1x + ε

β0是常数项(截距项),β1是回归系数,ε是随机误差项

多元线性回归:

线性回归模型的主要特点包括:

  1. 线性关系:模型假设自变量与因变量之间存在线性或近似线性的关系。这意味着当自变量发生变化时,因变量会按照一个恒定的速率增加或减少。
  2. 参数估计:通过最小二乘法等方法,模型可以估计出回归线的斜率和截距等参数。这些参数表示了自变量对因变量的影响程度。
  3. 预测能力:基于估计出的参数,模型可以用于预测新的数据点。当新的自变量值输入时,模型可以输出一个预测的因变量值。
  4. 统计检验:线性回归模型还提供了一系列的统计检验方法,用于评估模型的拟合效果、参数的显著性以及预测的准确性。

需要注意的是,线性回归模型有其适用条件和局限性。例如,它要求自变量和因变量之间的关系是线性的,且误差项应满足一定的分布假设(如正态分布)。在实际应用中,需要根据数据的特点和研究目的来选择合适的模型,并进行必要的模型验证和修正。

用numpy实现线性回归模型

import matplotlib.pyplot as plt
import numpy as np

x_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]

#定义forward函数,用于计算预测值y_pred
#定义线性模型y_pred=wx
def forward(x):
    return x * w

#定义loss函数,用于计算预测值y_pred与实际值y之间的平方误差
def loss(x,y):
    y_pred = forward(x)
    return (y_pred - y) ** 2

#存储权重w
w_list = []
#对应的平均平方误差
mes_list = []

#使用for循环遍历权重w的范围(0.0到4.0,步长为0.1)
for w in np.arange(0.0,4.1,0.1):
    print("w=",w)#打印当前权重w的值
    l_sum = 0#初始化一个变量l_sum,用于累加每个样本的损失值
    for x_val,y_val in zip(x_data,y_data):#使用zip函数将x_data和y_data组合成元组,然后遍历这些元组
        y_pred_val = forward(x_val)
        loss_val = loss(x_val,y_val)
        l_sum += loss_val#将损失值累加到l_sum中
        print("x_val=" , x_val, "y_val", y_val, "y_pred=", y_pred_val, "loss=", loss_val)
    print("MES=",l_sum / 3)
    w_list.append(w)
    mes_list.append(l_sum / 3)

plt.plot(w_list,mes_list)
plt.ylabel('Loss')
plt.xlabel('w')
plt.show()

梯度下降算法

梯度下降是一种迭代法,主要被用于求解损失函数的最小值。在机器学习算法中,尤其是深度学习中,梯度下降法常被用于求解模型参数,即无约束优化问题。

具体来说,梯度下降法通过不断迭代计算函数的梯度,判断该点的某一方向和目标之间的距离,最终求得最小的损失函数和相关参数。损失函数是一个自变量为算法参数的函数,其函数值为误差值,因此梯度下降就是找让误差值最小时算法取的参数。

梯度下降法的中心思想在于通过迭代次数的递增,调整使得损失函数最小化的权重。在每一次迭代中,它都会沿着梯度的反方向(即函数在该点处变化率最大的负方向)进行搜索,以找到使函数值下降最快的点。通过逐步调整参数,梯度下降法能够逐渐逼近损失函数的最小值,从而优化目标函数

请注意,梯度下降法只能保证找到梯度为0的点,但不能保证找到极小值点。此外,迭代终止的判定依据是梯度值充分接近于0,或者达到最大指定迭代次数。

梯度下降算法

import matplotlib.pyplot as plt

x_data = [1.0,2.0,3.0]
y_data = [2.0,4.0,6.0]

w = 1.0
def predict(x):
    return x * w

def cost(xs,ys):
    cost = 0
    for x,y in zip(xs,ys):
        y_pred = predict(x)
        cost+=(y_pred - y)**2
    return cost/len(xs)

#计算梯度
def gradient(xs, ys):
    grad = 0
    for x,y in zip(xs,ys):
        grad += 2*x*(predict(x) - y)
    return grad/len(xs)

epoch_list = []
cost_list = []
print('predict(before training): ',4, predict(4))
#epoch:训练轮次,表示重复训练的次数
for epoch in range(100):
    cost_val = cost(x_data,y_data)
    grad_val = gradient(x_data, y_data)
    w -= 0.01 * grad_val  #学习率设为0.01
    print('epoch:',epoch,'w=',w,'loss=',cost_val)
    epoch_list.append(epoch)
    cost_list.append(cost_val)

print('w=',w)
print('predict(after training)',4,predict(4))
#绘制图像
plt.plot(epoch_list,cost_list)
plt.ylabel('cost')
plt.xlabel('epoch')
plt.show()

随机梯度下降算法

import matplotlib.pyplot as plt

x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]
w = 1.0

# 定义线性模型y=wx
def forward(x):
    return x * w

def loss(x, y):
    y_pred = forward(x)
    return (y_pred - y) ** 2

# 计算梯度SGD
def gradient(x, y):
    return 2 * x * (x * w - y)

epoch_list = []
loss_list = []
print("predict(after training", 4, forward(4))
for epoch in range(100):
    for x, y in zip(x_data, y_data):
        grad = gradient(x, y)
        w = w - 0.01 * grad
        print("\tgrad:", x, y, grad)
        l=loss(x,y)
    print("epoch", epoch, "w=", w, "loss=", l)
    epoch_list.append(epoch)
    loss_list.append(l)

# 画图
print("predict(after training", 4, forward(4))
plt.plot(epoch_list, loss_list)
plt.ylabel('Loss')
plt.xlabel('epoch')
plt.show()

反向传播算法

反向传播算法(Back Propagation)是神经网络中最常用的学习算法,它通过误差反向传播,调整网络权重使误差最小化,实现网络的学习与训练。

反向传播算法的基本原理是,根据训练样本的输入和期望输出之间的误差,逐层逆向计算每个神经元的权重和偏置的梯度,进而更新网络参数以减小误差。具体来说,它首先初始化神经网络的权重,然后提供训练样本进行前向传播计算输出结果。接着,根据损失函数计算输出结果与真实值的误差。从输出层开始,反向传播算法根据误差计算每个节点的误差项(误差与激活函数的导数乘积),然后根据误差项计算每个连接的权重梯度(误差项与前一节点输出的乘积),最后根据梯度更新权重(减小梯度)。这个过程会重复多次,直到误差最小化或达到最大迭代次数。

通过反向传播算法,我们可以更快速地求解目标函数对各个参数的梯度,从而利用梯度下降法来优化神经网络的参数。

import matplotlib.pyplot as plt
import torch

x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]

w = torch.Tensor([1.0])
w.requires_grad = True

# 定义线性模型y=wx
def forward(x):
    return x * w #w是一个Tensor,x*w强制转化为Tensor

def loss(x, y):
    y_pred = forward(x)
    return (y_pred - y) ** 2

epoch_list = []
loss_list = []
print("predict(after training", 4, forward(4).item())

for epoch in range(100):
    for x, y in zip(x_data, y_data):
        l=loss(x,y)
        l.backward()
        #backward:将w梯度存起来后,释放计算图,因此每一层的计算图可能不一样,所以每次backward后释放计算图,准备下一次计算
        print("\tgrad:", x, y, w.grad.item()) # w.grad.item():将梯度直接取出来作为一个标量
        w.data = w.data - 0.01 * w.grad.data # 权重更新,不能直接使用tensor。注意grad也是一个tensor,因此获取梯度需要w.grad.data

        w.grad.data.zero_()#梯度清零

    print("epoch", epoch, "loss=",l.item())
    epoch_list.append(epoch)
    loss_list.append(l.item())

# 画图
print("predict(after training", 4, forward(4).item())
plt.plot(epoch_list, loss_list)
plt.ylabel('Loss')
plt.xlabel('epoch')
plt.show()

线性回归模型的代码运用

步骤

  1. 数据准备:首先,需要准备用于训练的数据集。这通常包括输入特征(X)和对应的目标值(y)。
  2. 定义模型:在PyTorch中,模型通常是通过继承nn.Module类来定义的。对于线性回归,可以定义一个简单的线性层。
  3. 定义损失函数:损失函数用于衡量模型预测值与实际值之间的差距。对于线性回归,常用的损失函数是均方误差(Mean Squared Error, MSE
  4. 定义优化器:优化器用于更新模型的权重,以最小化损失函数。常用的优化器有SGD、Adam等。
  5. 训练模型:通过多次迭代(epochs)来训练模型。在每个迭代中,前向传播计算预测值,计算损失,然后进行反向传播以更新权重
  6. 评估模型:使用测试集来评估模型的性能。

原理

  1. 线性回归模型:线性回归模型试图找到一条直线(在多维空间中可能是超平面),使得数据点尽可能接近这条直线。模型的形式为 y = w * x + b,其中w是权重(在决策过程中,权重是不同评价因素或影响因素分配的相对重要性系数),b是偏置项(与线性方程y=wx+b中的b具有相同的意义,表示函数在y轴上的截距,控制着函数偏离原点的距离
  2. 前向传播:从网络的输入层开始,通过一系列的计算,将数据沿着网络的层级结构向前传递,直到得到最终的输出结果。在训练过程中,模型接收输入数据,通过定义的线性层计算预测值。
  3. 损失函数:均方误差损失函数计算预测值与实际值之间的平方差的平均值。目标是最小化这个损失
  4. 反向传播:通过计算损失函数关于模型参数的梯度,使用链式法则将梯度从输出层传播到输入层,从而更新模型的权重
  5. 优化器:优化器使用计算出的梯度来更新模型的权重。不同的优化器有不同的更新策略,如SGD使用固定的学习率进行更新,而Adam则使用自适应的学习率。

神经网络训练算法

  1. 前向传播:首先,给网络输入一组训练数据,并逐层进行计算,得到网络的预测输出。
  2. 计算损失:将网络的预测输出与真实标签进行比较,计算损失函数的值,衡量模型预测与实际情况的差异。
  3. 反向传播:从损失函数开始,逆向传播梯度,计算每个参数对于损失函数的梯度。这是通过应用链式法则来实现的,将梯度从输出层逐层传递回输入层。
  4. 参数更新:使用计算得到的梯度,按照梯度下降法或其变种来更新网络的权重和偏置项

通过多次迭代前向传播和反向传播,网络逐渐优化参数,提高预测准确性,并使其适应特定的任务需求。反向传播是深度学习训练中的关键步骤,它使得网络能够自动学习并调整其内部参数,以更好地拟合训练数据并提升泛化能力。

损失函数: MSE loss:计算数值之间的差异

import torch
from matplotlib import pyplot as plt

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): #定义了一个名为LinearModel的类,继承自torch.nn.Module
    def __init__(self):
        super(LinearModel,self).__init__()
        #super() 函数用于调用父类
        #super(LinearModel, self) 返回一个临时对象
        #该对象绑定到LinearModel的父类(即torch.nn.Module),并且会将self(即LinearModel的一个实例)作为第一个参数传入。
        #.__init__() 调用该临时对象(即父类torch.nn.Module)的__init__方法。
        self.linear = torch.nn.Linear(1,1)
        #定义了一个线性层self.linear,用于将输入数据映射到输出数据
        #1是输入特征的数量,另一个1是输出特征的数量
    def forward(self,x):
        y_pred = self.linear(x)
        #将输入数据x传递给线性层,得到预测值y_pred
        return y_pred

#LinearModel()类的一个新实例
model = LinearModel()

#设置了损失函数(均方误差损失)和优化器(随机梯度下降)
criterion = torch.nn.MSELoss(size_average=False)
# optimizer = torch.optim.SGD(model.parameters(),lr=0.01)
# optimizer = torch.optim.ASGD(model.parameters(),lr=0.01)
# optimizer = torch.optim.Adamax(model.parameters(),lr=0.01)
# optimizer = torch.optim.LBFGS(model.parameters(),lr=0.01)
# optimizer = torch.optim.RMSprop(model.parameters(),lr=0.01)
# optimizer = torch.optim.Rprop(model.parameters(),lr=0.01)
# optimizer = torch.optim.Adagrad(model.parameters(),lr=0.01)
optimizer = torch.optim.Adam(model.parameters(),lr=0.01)
#model.parameters():获取到一个生成器,它会遍历模型的所有参数(包括权重和偏置等),并将它们作为张量返回。
#lr=0.01:学习率为0.01

epoch_list = []
loss_list = []

for epoch in range(1000):
    y_pred = model(x_data)
    loss = criterion(y_pred,y_data)
    print(epoch,loss.item())
    epoch_list.append(epoch)
    loss_list.append(loss.item())
    loss.backward()
    optimizer.step()
    #在反向传播过程中,优化器会累积梯度,然后调用step()方法一次性更新所有参数。
    optimizer.zero_grad()
    #将优化器的梯度缓存清零,以便下一次计算梯度时不会受到上一次计算的影响。

print("w = ", model.linear.weight.item(), "b = ", model.linear.bias.item())

x_test = torch.Tensor([[4.0]])
y_test = model(x_test)
print("y_pred =",y_test.data)

plt.plot(epoch_list, loss_list)
plt.ylabel('Loss')
plt.xlabel('epoch')
plt.show()

逻辑回归模型(Logistic regressions)

逻辑回归模型是一种基于概率的分类模型,通过将输入特征映射到一个概率值来预测离散输出变量。虽然名称中包含“回归”,但实际上它主要用于解决分类问题,特别是二分类问题。

逻辑回归模型的核心思想是将线性回归模型的输出结果通过一个非线性函数(通常是sigmoid函数)进行映射,将连续值转化为概率值。sigmoid函数的作用是将线性回归模型的输出结果限制在0到1之间,从而实现对数据的分类。当模型预测的概率值超过某个阈值(通常为0.5)时,样本被分类为某一类别;否则,被分类为另一类别。

逻辑回归模型的参数可以通过最大似然估计或梯度下降等方法来学习。最大似然估计是一种常用的参数估计方法,旨在最大化训练数据的似然函数,从而使模型更好地拟合训练数据。

逻辑回归模型在人工智能领域有着广泛的应用,例如信用评估、医疗诊断、金融预测和电商推荐等。在信用评估中,逻辑回归可以根据用户的信用信息预测其是否会违约;在医疗诊断中,它可以帮助医生根据病人的症状和其他指标预测疾病的可能性。

需要注意的是,逻辑回归模型虽然简单且有效,但也有其适用条件和局限性。例如,它假设数据之间存在线性关系,并且要求误差项满足一定的分布假设。因此,在使用逻辑回归模型时,需要对数据进行适当的预处理和模型验证,以确保模型的准确性和可靠性。

损失函数:BCE loss:计算分布之间的差异

逻辑回归模型的代码运用

import torch
import torch.nn.functional as F
import numpy as np
import matplotlib.pyplot as plt

#x_data表示小时数,y_data表示是否通过(0表示未通过,1表示通过)
x_data = torch.Tensor([[1.0], [2.0], [3.0]])
y_data = torch.Tensor([[0], [0], [1]])

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))#sigmid激活函数
        return y_pred

model = LogisticRegressionModel()

#BCELoss是用于二分类问题的损失函数,它计算真实标签和预测标签之间的二进制交叉熵
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)
    #loss.item()将张量转换为标量值
    print(epoch, loss.item())
    loss.backward()
    optimizer.step()
    optimizer.zero_grad()

x = np.linspace(0, 10, 200)
x_t = torch.Tensor(x).view((200, 1))#将转换为tensor,变成200行,1列
y_t = model(x_t)
y = y_t.data.numpy()#tensor转化为numpy形式
plt.plot(x, y)
plt.plot([0, 10], [0.5, 0.5], c='r')#在概率=0.5时画一条红色直线(决策边界)
plt.xlabel('Hours')
plt.ylabel('Probability of Pass')
plt.grid()
plt.show()

使用PyTorch进行逻辑回归模型的简单实现

数据准备

生成和可视化两个二维的正态分布样本

1.定义均值和协方差矩阵
import matplotlib.pyplot as plt
import numpy as np
import torch
from torch import nn
from torch.distributions import MultivariateNormal
from torch import optim
#数据准备
#设置两组不同的均值向量和协方差矩阵
#定义了两个均值向量mu1和mu2,它们都是二维的,分别是[-3, -3]和[3, 3]
mu1 = -3 * torch.ones(2)
mu2 = 3 * torch.ones(2)

均值向量:均值向量用于表示多维随机变量或数据集中各个维度的平均值。

#定义了两个协方差矩阵sigma1和sigma2
#为单位矩阵(对角线上为1,其余为0)乘以一个常数
sigma1 = torch.eye(2) * 0.5
sigma2 = torch.eye(2) * 2

协方差矩阵:协方差矩阵的对角线元素表示各维度的方差,非对角线元素表示各维度之间的协方差。协方差矩阵描述了数据集中各个维度之间的线性相关性以及各维度上的变异程度。

例子:
使用上述身高和体重数据计算协方差矩阵。

2.创建多元正态分布对象并采样
#各从两个多元高斯分布中生成100个样本
#使用PyTorch的MultivariateNormal类,根据前面定义的均值和协方差矩阵创建了两个多元正态分布对象。
m1 = MultivariateNormal(mu1, sigma1)
m2 = MultivariateNormal(mu2, sigma2)
x1 = m1.sample((100,))
x2 = m2.sample((100,))
3.定义标签并混合数据
#设置正负样本的标签
#定义了一个标签向量y,前100个样本的标签为0,后100个样本的标签为1
y = torch.zeros((200,1))
y[100:] = 1
#组合、打乱样本(为了使数据在训练时更加随机化)
#将两个样本集x1和x2在第一个维度(即行的方向)上连接起来,形成一个200x2的矩阵。
x = torch.cat([x1,x2],dim=0)
idx = np.random.permutation(len(x))
x = x[idx]
y = y[idx]
4.绘制散点图
#分别绘制了x1和x2两个样本集
plt.scatter(x1.numpy()[:,0],x1.numpy()[:,1])
plt.scatter(x2.numpy()[:,0],x2.numpy()[:,1])
plt.show()

线性方程

展示了如何使用PyTorch定义一个线性层,并比较了这个线性层与一个自定义线性函数在相同输入和权重下的输出

1.定义线性层:
#D_in 和 D_out 分别表示输入和输出的维度
D_in,D_out = 2,1
#nn.Linear 是PyTorch中定义线性层的类。bias=True 表示这个线性层包含一个偏置项。
linear = nn.Linear(D_in,D_out,bias=True)
2.线性层的前向传播:
#linear(x) 通过矩阵乘法执行线性变换
output = linear(x)
3.打印形状:
#打印了输入数据 x、线性层的权重 linear.weight、偏置 linear.bias 和输出 output 的形状
print(x.shape,linear.weight.shape,linear.bias.shape,output.shape)
4.自定义线性函数:
def my_linear(x,w,b):
    return torch.mm(x,w.t())+b
#torch.mm(x,w.t()) 是矩阵乘法操作。w.t() 是权重的转置
5.比较两个线性操作的结果:
#打印它们的差的总和
print(torch.sum((output - my_linear(x,linear.weight,linear.bias))))

计算了使用PyTorch的线性层 linear 和自定义的线性函数 my_linear 得到的输出之间的差异。如果这两个操作是完全相同的,那么这个和应该是非常接近0的(可能由于数值误差略有不同)。

激活函数

展示了如何使用PyTorch的内置sigmoid函数和如何手动实现一个sigmoid函数,然后比较两者的输出差异

1.使用PyTorch的内置sigmoid函数:
#使用了PyTorch的nn.Sigmoid类来创建一个Sigmoid函数对象,可以直接对张量应用
sigmoid = nn.Sigmoid()
#将之前通过线性层得到的output作为输入,传递给sigmoid函数,得到经过Sigmoid激活后的输出scores
scores = sigmoid(output)
2.自定义sigmoid函数:
def my_sigmoid(x):
    x = 1 / (1 + torch.exp(-x))
    return x
#Sigmoid函数的数学表达式为1 / (1 + exp(-x))
3.比较两个Sigmoid函数的输出:
print(torch.sum(sigmoid(output) - my_sigmoid(output)))

这行代码计算了使用PyTorch的内置sigmoid函数和自定义的my_sigmoid函数得到的输出之间的差异,并打印它们的差的总和。如果这两个函数的实现是完全相同的,那么这个和应该是非常接近0的(可能由于数值误差略有不同)。

损失函数

1.使用PyTorch的nn.BCELoss类:
#使用了PyTorch的nn.BCELoss类来创建一个二元交叉熵损失函数对象
loss = nn.BCELoss()
#计算了经过Sigmoid激活后的output与真实标签y之间的二元交叉熵损失
loss(sigmoid(output),y)
2.自定义损失函数:
def my_loss(x,y):
    loss = - torch.mean(torch.log(x) * y + torch.log(1 - x)* (1 - y))
    return loss
3.比较内置和自定义损失函数的输出:
print(loss(sigmoid(output),y) - my_loss(my_sigmoid(output),y))

这行代码计算了使用PyTorch的内置BCELoss函数和自定义的my_loss函数得到的损失之间的差异,并打印这个差异。如果两个函数的实现是完全相同的,那么这个差异应该是非常接近0的。

接下来我们用nn.Module来实现逻辑回归:
#定义了一个逻辑回归模型LogisticRegression,它继承自nn.Module
class LogisticRegression(nn.Module):
    def __init__(self, D_in):
        super(LogisticRegression,self).__init__()
        #包含一个线性层
        self.linear = nn.Linear(D_in,1)
        #包含一个Sigmoid激活函数
        self.sigmoid = nn.Sigmoid()
    def forward(self, x):
        #输入数据首先经过线性层变换
        x = self.linear(x)
        #应用Sigmoid激活函数得到输出
        output = self.sigmoid(x)
        return output

#创建了一个逻辑回归模型的实例lr_model
lr_model = LogisticRegression(2)
#定义了一个二元交叉熵损失函数对象
loss = nn.BCELoss()
#使用模型对输入数据x进行前向传播得到输出,并计算输出与真实标签y之间的损失
print(loss(lr_model(x), y))

当通过继承nn.Module实现自已的模型时,forward方法是必须被子类覆写的,在forward内部应当定义每次调用模型时执行的计算。从代码中我们可以看出,nn.Module 类的主要作用就是接收Tensor然后计算并返回结果。

在一个Module中,还可以嵌套其他的Module,被嵌套的Module的属性就可以被自动获取,比如可以调用nn.Module.pramers方法获取Module所有保留的参数,调用nn.Module.to方法将模型的参数放置到GPU上等。

class MyModel(nn.Module):
    def __init__(self):
        super(MyModel,self).__init__()
        self.linear1= nn.Linear(1,1,bias=False)
        self.linear2= nn.Linear(1,1,bias=False)
    def forward(self):
        pass

for param in MyModel().parameters():
    print(param)

优化算法

展示了如何使用PyTorch来训练一个逻辑回归模型,并计算模型在测试数据上的精确率

#定义一个随机梯度下降(SGD)优化器
#lr_model.parameters()返回模型中所有可训练的参数,lr=0.03设置了学习率为0.03
optimizer = optim.SGD(lr_model.parameters(),lr=0.03)

#每个批次的大小为10,总的迭代次数为10次
batch_size = 10
iters = 10
for i in range(iters):
    for j in range(0, len(x), batch_size):
        input = x[i*batch_size:(j+1)*batch_size]
        target = y[i*batch_size:(j+1)*batch_size]
        optimizer.zero_grad()#清除之前计算的梯度
        output = lr_model(input)#前向传播,得到模型的输出
        l = loss(output,target)#计算损失
        l.backward()#进行反向传播,计算梯度
        optimizer.step()#根据计算出的梯度更新模型的参数

output = lr_model(x)

# 计算模型精确率并输出
correct = (lr_model(x).round() == y).float().sum()
accuracy = correct / len(y)
print("模型精确率为:", accuracy.item())
# lr_model(x)对整个数据集x进行前向传播。
# .round()将模型的输出四舍五入到最接近的整数,因为逻辑回归的输出是概率,我们需要将其转换为0或1的预测标签。
# (lr_model(x).round() == y)比较模型的预测标签和真实标签,得到一个布尔值的张量。
# .float().sum()将布尔值转换为浮点数(True为1.0,False为0.0),并求和,得到预测正确的样本数量。
# accuracy = correct / len(y)计算精确率。
# 使用.item()来获取标量值

模型可视化

绘制逻辑回归模型的决策边界

#负类(pred_neg),正类(pred_pos)
#.view(-1) 是将张量转换为一维形式,便于索引
pred_neg = (output<=0.5).view(-1)
pred_pos = (output>0.5).view(-1)
#x[pred_neg,0] 和 x[pred_neg,1] 分别表示负类样本的特征值,同理 x[pred_pos,0] 和 x[pred_pos,1] 表示正类样本的特征值
plt.scatter(x[pred_neg,0],x[pred_neg,1])
plt.scatter(x[pred_pos,0],x[pred_pos,1])
#提取权重和偏置
w = lr_model.linear.weight[0]
b = lr_model.linear.bias[0]

#定义绘制决策边界的函数:
def draw_decision_boundary(w,b,x0):
    x1 = (-b - w[0] * x0) / w[1]
    plt.plot(x0.detach().numpy(),x1.detach().numpy(),'r')
    plt.show()
#调用函数绘制决策边界:
draw_decision_boundary(w,b,torch.linspace(x.min(),x.max(),50))

  • 47
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值