Python----机器学习(基于PyTorch框架的逻辑回归)

逻辑回归是一种广泛使用的统计学习方法,主要用于处理二分类问题。它基于线性回归模型,通过Sigmoid函数将输出映射到[0, 1]范围内,表示实例属于正类别的概率。尽管逻辑回归适用于二分类任务,但在多分类问题中常使用Softmax函数,它将多个类别的概率输出为和为1的正值,允许模型进行多类别预测。PyTorch是一个灵活且强大的深度学习框架,以其动态计算图和易用性受到广泛欢迎,适用于研究和生产环境中的各种机器学习任务。

一、sigmoid激活函数

1.1、输入散点

python 复制代码
import numpy as np

class1_points = np.array([[1.9, 1.2],
                          [1.5, 2.1],
                          [1.9, 0.5],
                          [1.5, 0.9],
                          [0.9, 1.2],
                          [1.1, 1.7],
                          [1.4, 1.1]])
 
class2_points = np.array([[3.2, 3.2],
                          [3.7, 2.9],
                          [3.2, 2.6],
                          [1.7, 3.3],
                          [3.4, 2.6],
                          [4.1, 2.3],
                          [3.0, 2.9]])
x_train = np.concatenate((class1_points, class2_points))
y_train = np.concatenate((np.zeros(len(class1_points)), np.ones(len(class2_points))))

1.2、转换为Tensor张量

python 复制代码
import torch
inputs=torch.tensor(x_train,dtype=torch.float32)
labels=torch.tensor(y_train,dtype=torch.float32).unsqueeze(1)

1.3、定义模型

python 复制代码
import torch
import torch.nn as nn
torch.manual_seed(42)
class LogisticRegreModel(nn.Module):
    def __init__(self,inputsizes):
        super().__init__()
        self.linear=nn.Linear(inputsizes,1)
    def forward(self,x):
        return torch.sigmoid(self.linear(x))
model=LogisticRegreModel(x_train.shape[1])

1.4、定义损失函数和优化器

python 复制代码
from torch.optim import SGD
cri=torch.nn.BCELoss()
optimizer=SGD(model.parameters(),lr=0.05)

1.5、开始迭代

python 复制代码
for i in range(1,1001):
    output=model(inputs)
    loss=cri(output,labels)

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if i%100==0 or i==1:
        print(i,loss.item()) 

1.6、可视化

python 复制代码
from matplotlib import pyplot as plt
fig,(ax1,ax2)=plt.subplots(1,2)
epoch_list=[]
loss_list=[]

for i in range(1,1001):
    inputs=torch.tensor(x_train,dtype=torch.float32)
    labels=torch.tensor(y_train,dtype=torch.float32).unsqueeze(1)

    output=model(inputs)
    loss=cri(output,labels)

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if i%100==0 or i==1:
        print(i,loss.item())
        w1,w2=model.linear.weight.data.flatten()
        b=model.linear.bias.data[0]

        slope=-w1/w2
        intercept=-b/w2
        x_min,x_max=0,5
        x=np.array([x_min,x_max])
        y=slope*x+intercept

        ax1.clear()
        ax1.scatter(class1_points[:,0],class1_points[:,1])
        ax1.scatter(class2_points[:,0],class2_points[:,1])
        ax1.plot(x,y)

        ax2.clear()
        epoch_list.append(i)
        loss_list.append(loss.item())
        ax2.plot(epoch_list,loss_list)
plt.show()

1.7、完整代码

python 复制代码
import numpy as np  # 导入 NumPy 库以进行数组和数学运算  
from matplotlib import pyplot as plt  # 导入 Matplotlib 库以绘制图形  
import torch  # 导入 PyTorch 库  
import torch.nn as nn  # 导入 PyTorch 的神经网络模块  
from torch.optim import SGD  # 导入随机梯度下降优化器  

# 定义类1的数据点  
class1_points = np.array([[1.9, 1.2],  
                          [1.5, 2.1],  
                          [1.9, 0.5],  
                          [1.5, 0.9],  
                          [0.9, 1.2],  
                          [1.1, 1.7],  
                          [1.4, 1.1]])  
   
# 定义类2的数据点  
class2_points = np.array([[3.2, 3.2],  
                          [3.7, 2.9],  
                          [3.2, 2.6],  
                          [1.7, 3.3],  
                          [3.4, 2.6],  
                          [4.1, 2.3],  
                          [3.0, 2.9]])  

# 合并类1和类2的数据点,作为训练特征  
x_train = np.concatenate((class1_points, class2_points))  
# 合并类1和类2的标签,类1为 0,类2为 1  
y_train = np.concatenate((np.zeros(len(class1_points)), np.ones(len(class2_points))))  

# 将训练特征和标签转换为 PyTorch 张量  
inputs = torch.tensor(x_train, dtype=torch.float32)  
labels = torch.tensor(y_train, dtype=torch.float32).unsqueeze(1)  

# 设置随机种子以便复现结果  
torch.manual_seed(42)  

# 定义逻辑回归模型类  
class LogisticRegreModel(nn.Module):  
    def __init__(self, input_sizes):  
        super().__init__()  # 继承父类的初始化方法  
        self.linear = nn.Linear(input_sizes, 1)  # 定义线性层,输入大小为 input_sizes,输出为 1  

    def forward(self, x):  
        return torch.sigmoid(self.linear(x))  # 前向传播,应用 Sigmoid 函数  

# 实例化逻辑回归模型,输入特征的维度为 x_train 的列数  
model = LogisticRegreModel(x_train.shape[1])  

# 定义二元交叉熵损失函数  
cri = torch.nn.BCELoss()  
# 使用随机梯度下降算法作为优化器  
optimizer = SGD(model.parameters(), lr=0.05)  

# 创建子图用于展示  
fig, (ax1, ax2) = plt.subplots(1, 2)  
epoch_list = []  # 存储每次训练的epoch数  
loss_list = []   # 存储每次训练的损失值  

# 训练模型,进行 1000 次迭代  
for i in range(1, 1001):  
    inputs = torch.tensor(x_train, dtype=torch.float32)  # 再次定义输入张量  
    labels = torch.tensor(y_train, dtype=torch.float32).unsqueeze(1)  # 再次定义标签张量  

    output = model(inputs)  # 前向传播计算模型输出  
    loss = cri(output, labels)  # 计算损失值  

    optimizer.zero_grad()  # 清空之前的梯度  
    loss.backward()  # 反向传播计算梯度  
    optimizer.step()  # 更新参数  

    # 每 100 次迭代打印损失并更新图形  
    if i % 100 == 0 or i == 1:  
        print(i, loss.item())  # 打印当前epoch和损失值  

        # 获取当前模型参数  
        w1, w2 = model.linear.weight.data.flatten()  # 权重参数  
        b = model.linear.bias.data[0]  # 偏置参数  

        # 计算决策边界的斜率和截距  
        slope = -w1 / w2  
        intercept = -b / w2  
        x_min, x_max = 0, 5  # 决定x轴的范围  
        x = np.array([x_min, x_max])  # 创建x值的数组  
        y = slope * x + intercept  # 根据斜率和截
                # 根据斜率和截距计算决策边界的y值  
        y = slope * x + intercept  

        ax1.clear()  # 清空第一张子图  
        # 绘制类1和类2的数据点  
        ax1.scatter(class1_points[:, 0], class1_points[:, 1], color='blue', label='Class 1')  
        ax1.scatter(class2_points[:, 0], class2_points[:, 1], color='orange', label='Class 2')  
        # 绘制当前的决策边界  
        ax1.plot(x, y, color='green', label='Decision Boundary')  
        ax1.legend()  # 显示图例  

        ax2.clear()  # 清空第二张子图  
        epoch_list.append(i)  # 将当前epoch添加到列表  
        loss_list.append(loss.item())  # 将当前损失值添加到列表  
        ax2.plot(epoch_list, loss_list, color='red')  # 绘制损失变化曲线  

# 显示绘制的图形  
plt.show()  

二、Softmax激活函数

2.1、输入散点

python 复制代码
import numpy as np

class1_points = np.array([[1.9, 1.2],
                          [1.5, 2.1],
                          [1.9, 0.5],
                          [1.5, 0.9],
                          [0.9, 1.2],
                          [1.1, 1.7],
                          [1.4, 1.1]])
 
class2_points = np.array([[3.2, 3.2],
                          [3.7, 2.9],
                          [3.2, 2.6],
                          [1.7, 3.3],
                          [3.4, 2.6],
                          [4.1, 2.3],
                          [3.0, 2.9]])
x_train = np.concatenate((class1_points, class2_points))
y_train = np.concatenate((np.zeros(len(class1_points)), np.ones(len(class2_points))))

2.2、转换为Tensor张量

python 复制代码
import torch
inputs=torch.tensor(x_train,dtype=torch.float32)
labels=torch.tensor(y_train,dtype=torch.long)

2.3、定义模型

python 复制代码
class LogisticRegreModel(torch.nn.Module):
    def __init__(self):
        super(LogisticRegreModel, self).__init__()
        self.fc = torch.nn.Linear(2, 2)
 
    def forward(self, x):
        x = self.fc(x)
        # dim 指定了softmax在哪个维度上进行
        # dim = 1第二个维度上进行,列
        # example:x  (sample, num_classes)
        # torch.softmax(x, dim=1), pytorch在每个样本上的类别进行softmax,保证每个样本的所有类别的概率和为1。
        return torch.softmax(x, dim=1)
 
model = LogisticRegreModel()

2.4、定义损失函数和优化器

python 复制代码
cri = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.05)

2.5、开始迭代

python 复制代码
for epoch in range(1, 1001):
 
    outputs = model(inputs)
    loss = cri(outputs, labels)

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
 
    if epoch % 50 == 0 or epoch == 1:
        print(f"epoch: {epoch}, loss: {loss}")

2.6、可视化

python 复制代码
plt.figure(figsize=(12, 6))

xx, yy = np.meshgrid(np.arange(0, 6, 0.1), np.arange(0, 6, 0.1))
grid_points = np.c_[xx.ravel(), yy.ravel()]

epoches = 1000
for epoch in range(1, epoches + 1):

    outputs = model(inputs)
    loss = cri(outputs, labels)

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
 
    if epoch % 50 == 0 or epoch == 1:
        print(f"epoch: {epoch}, loss: {loss}")
        grid_tensor = torch.tensor(grid_points, dtype=torch.float32)
        Z = model(grid_tensor).detach().numpy()
        Z = Z[:, 1]
        Z = Z.reshape(xx.shape)
 
        plt.cla()
        plt.scatter(class1_points[:, 0], class1_points[:, 1])
        plt.scatter(class2_points[:, 0], class2_points[:, 1])
        plt.contour(xx, yy, Z, levels=[0.5])
        plt.pause(1)
 
plt.show()

2.7、完整代码

python 复制代码
import numpy as np  # 导入 NumPy 库进行数组和数学运算  
import torch  # 导入 PyTorch 库  
import matplotlib.pyplot as plt  # 导入 Matplotlib 用于绘图  

# 定义类1的数据点  
class1_points = np.array([[1.9, 1.2],  
                          [1.5, 2.1],  
                          [1.9, 0.5],  
                          [1.5, 0.9],  
                          [0.9, 1.2],  
                          [1.1, 1.7],  
                          [1.4, 1.1]])  

# 定义类2的数据点  
class2_points = np.array([[3.2, 3.2],  
                          [3.7, 2.9],  
                          [3.2, 2.6],  
                          [1.7, 3.3],  
                          [3.4, 2.6],  
                          [4.1, 2.3],  
                          [3.0, 2.9]])  

# 合并类1和类2的数据点,作为训练特征  
x_train = np.concatenate((class1_points, class2_points))  
# 合并类1和类2的标签,类1为 0,类2为 1  
y_train = np.concatenate((np.zeros(len(class1_points)), np.ones(len(class2_points))))  

# 将训练特征和标签转换为 PyTorch 张量  
inputs = torch.tensor(x_train, dtype=torch.float32)  # 输入特征  
labels = torch.tensor(y_train, dtype=torch.long)  # 标签应为长整型  

# 定义逻辑回归模型类  
class LogisticRegreModel(torch.nn.Module):  
    def __init__(self):  
        super(LogisticRegreModel, self).__init__()  # 继承父类的初始化方法  
        self.fc = torch.nn.Linear(2, 2)  # 定义线性层,输入大小为 2,输出类别数为 2  

    def forward(self, x):  
        x = self.fc(x)  # 进行前向传播,计算线性层输出  
        # 使用 softmax 函数将输出转换为概率  
        return torch.softmax(x, dim=1)  # dim=1 表示在列上进行 softmax 操作  

# 实例化逻辑回归模型  
model = LogisticRegreModel()  

# 定义交叉熵损失函数,适用于多分类问题  
cri = torch.nn.CrossEntropyLoss()  
# 定义优化器为随机梯度下降  
optimizer = torch.optim.SGD(model.parameters(), lr=0.05)  

# 创建绘图窗口  
plt.figure(figsize=(12, 6))  

# 创建网格点用于绘制决策边界  
xx, yy = np.meshgrid(np.arange(0, 6, 0.1), np.arange(0, 6, 0.1))  # 生成网格坐标  
grid_points = np.c_[xx.ravel(), yy.ravel()]  # 将网格点展平为 (样本数, 特征数) 的形式  

epoches = 1000  # 定义训练的轮数  
for epoch in range(1, epoches + 1):  
    outputs = model(inputs)  # 前向传播获得模型输出  
    loss = cri(outputs, labels)  # 计算损失  

    optimizer.zero_grad()  # 清空之前的梯度  
    loss.backward()  # 反向传播计算梯度  
    optimizer.step()  # 更新模型参数  

    # 每 50 个 epoch 更新绘图  
    if epoch % 50 == 0 or epoch == 1:  
        print(f"epoch: {epoch}, loss: {loss.item()}")  # 打印当前 epoch 和损失值  
        grid_tensor = torch.tensor(grid_points, dtype=torch.float32)  # 将网格点转换为张量  
        Z = model(grid_tensor).detach().numpy()  # 前向传播获得每个网格点的输出  
        Z = Z[:, 1]  # 取出第二类的概率,用于绘制决策边界  
        Z = Z.reshape(xx.shape)  # 重塑为网格形状  

        plt.cla()  # 清除当前图形  
        plt.scatter(class1_points[:, 0], class1_points[:, 1], label='Class 1')  # 绘制类1数据点  
        plt.scatter(class2_points[:, 0], class2_points[:, 1], label='Class 2')
        plt.contour(xx, yy, Z, levels=[0.5])
        plt.legend()
        plt.pause(1)
 
plt.show()
相关推荐
用户8356290780516 分钟前
Python 删除 Excel 工作表中的空白行列
后端·python
Json_7 分钟前
使用python-fastApi框架开发一个学校宿舍管理系统-前后端分离项目
后端·python·fastapi
CoovallyAIHub2 小时前
开源的消逝与新生:从 TensorFlow 的落幕到开源生态的蜕变
pytorch·深度学习·llm
数据智能老司机7 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机8 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机8 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机8 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i8 小时前
drf初步梳理
python·django
每日AI新事件8 小时前
python的异步函数
python
这里有鱼汤9 小时前
miniQMT下载历史行情数据太慢怎么办?一招提速10倍!
前端·python