Pytorch实现Logistic Regression

接上一个博客《Machine Learning In Action 学习笔记之 Logistic regression》,这使用的是Numpy进行回归,但我想改用Pytorch框架来写这个程序。

给定数据集(前两列为特征x1, x2,第三列为标签y) 如下所示:

-0.017612 14.053064 0
-1.395634 4.662541 1
-0.752157 6.538620 0
-1.322371 7.152853 0
0.423363 11.054677 0
0.406704 7.067335 1
0.667394 12.741452 0
-2.460150 6.866805 1
0.569411 9.548755 0
-0.026632 10.427743 0
0.850433 6.920334 1
1.347183 13.175500 0
1.176813 3.167020 1

原来是将数据转化为np.array形式,而为了使用Pytorch,就需要将numpy转化为tensor数据,使用torch.from_numpy()进行转化,数据导入与转换代码如下:

def loadData():
    fr = open('testSet.txt')
    X = []
    y = []
    for line in fr.readlines():
        lineArr = line.strip().split()
        X.append([float(lineArr[0]), float(lineArr[1])])
        y.append(int(lineArr[2]))
		X, y = loadData()
	    X = np.array(X)
	    y = np.array(y)
	    # 转为tensor类型
	    X = torch.from_numpy(X) 
	    y = torch.from_numpy(y)
    return X, y

但这里会出现一个问题:
在这里插入图片描述意思就是期望的数据类型为Float,但是给的数据类型是Double,所以报错。查了很久从这篇博客中发现了 from_numpy() 的一个问题:博客地址 , 其中,当 ndarray的类型是float64时,from_numpy(ndarray) 转化为 torch.DoubleTensor ,所以不能使用这样的转化函数,另辟蹊径,选择 torch.Tensor() 进行numpy的转化就没有错了。

X = torch.Tensor(X)

因为Logistics Regression 的原理就是这张图:
在这里插入图片描述
所以可以用Pytorch设计这样的神经网络:
在这里插入图片描述
一层为线性层,一层为sigmoid,
则代码如下:

class Logistic(nn.Module):
    def __init__(self, input_size, hidden_size):
        super(Logistic, self).__init__()
        self.layer = nn.Linear(input_size, hidden_size)
        self.sigmoid = nn.Sigmoid()

    def forward(self, X):
        out = self.layer(X)
        out = self.sigmoid(out)
        return out

然后开始 训练模型

def main():
    X, y = loadData()
    # print(y)
    # 一定要将y的shape转化一下
    y = y.reshape([100, 1])
    #print(X)
    #print(y)
    # m为数据个数,n为特征数即input_size
    m, n = X.shape
    h_size = 1
    # 模型为model
    model = Logistic(n, h_size)
    # 损失函数
    criterion = nn.MSELoss()
    # 优化器
    optimizer = optim.SGD(model.parameters(), lr = 0.01)

    for t in range(10000):
    	# 通过模型生成y_pred
        y_pred = model(X)
        #print(y_pred)
        # 如果不转换为float,会出ValueError: only one element tensors can be converted to Python scalars
        loss = criterion(y.float(), y_pred.float())
        # 统计正确预测的个数
        mask = y_pred.ge(0.5).float()
        correct = (mask == y.float()).sum()
        accuracy = correct.item()/X.size(0)
        if t % 100 == 99:
            print("第{}次损失为{},正确率为{}".format(t, loss.item(), accuracy))
        # 把梯度置零(必须要)
        optimizer.zero_grad()
        # 求loss
        loss.backward()
        # 反向传播求step
        optimizer.step()

运行一下,结果如下:
在这里插入图片描述
编写一下画图函数:

def plot(weights, bias):
    # 加载数据集
    dataMat, labelMat = loadData()
    # 转换成numpy的array数组
    dataArr = np.array(dataMat)
    #print(dataArr)
    # 数据个数
    # 例如建立一个4*2的矩阵c,c.shape[1]为第一维的长度2, c.shape[0]为第二维的长度4
    n = np.shape(dataMat)[0]
    # 正样本
    xcord1 = []
    ycord1 = []
    # 负样本
    xcord2 = []
    ycord2 = []
    # 根据数据集标签进行分类
    for i in range(n):
        if int(labelMat[i]) == 1:
            # 1为正样本
            xcord1.append(dataArr[i, 0])
            ycord1.append(dataArr[i, 1])
        else:
            # 0为负样本
            xcord2.append(dataArr[i, 0])
            ycord2.append(dataArr[i, 1])
    # 新建图框
    fig = plt.figure()
    # 添加subplot
    ax = fig.add_subplot(111)
    # 绘制正样本
    ax.scatter(xcord1, ycord1, s=20, c='red', marker='s', alpha=.5)
    # 绘制负样本
    ax.scatter(xcord2, ycord2, s=20, c='green', alpha=.5)
    # x轴坐标
    x = np.arange(-3.0, 3.0, 0.1)
    # w1*x1 + w2*x2 + b = 0
    # x1 = x, x2 = y
    y = (- bias - weights[0][0] * x ) / weights[0][1]
    ax.plot(x, y)
    # 绘制title
    plt.title('BestFit')
    # 绘制label
    plt.xlabel('x1')
    plt.ylabel('y2')
    # 显示
    plt.show()

从模型中取出线性层的参数,然后画图即可

# 取出线性层参数
    params=model.state_dict()
    weights = params['layer.weight']
    bias = params['layer.bias']
    #print(weights.numpy())
    #print(bias.numpy()[0])
    plot(weights.numpy(), bias.numpy()[0])

最后显示为:
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
### 回答1: PyTorch实现Logistic回归的步骤如下: 1. 导入必要的库和数据集。 2. 定义模型:Logistic回归模型通常由一个线性层和一个sigmoid函数组成。 3. 定义损失函数:Logistic回归使用二元交叉熵作为损失函数。 4. 定义优化器:使用随机梯度下降(SGD)作为优化器。 5. 训练模型:使用训练数据集训练模型,并在每个epoch后计算损失函数和准确率。 6. 测试模型:使用测试数据集测试模型,并计算准确率。 7. 可视化结果:使用matplotlib库可视化训练和测试的损失函数和准确率。 下面是一个简单的PyTorch实现Logistic回归的示例代码: ``` import torch import torch.nn as nn import torch.optim as optim import matplotlib.pyplot as plt # 导入数据集 from sklearn.datasets import load_breast_cancer data = load_breast_cancer() X = data.data y = data.target # 将数据转换为张量 X = torch.tensor(X, dtype=torch.float32) y = torch.tensor(y, dtype=torch.float32) # 定义模型 class LogisticRegression(nn.Module): def __init__(self): super(LogisticRegression, self).__init__() self.linear = nn.Linear(X.shape[1], 1) self.sigmoid = nn.Sigmoid() def forward(self, x): x = self.linear(x) x = self.sigmoid(x) return x model = LogisticRegression() # 定义损失函数和优化器 criterion = nn.BCELoss() optimizer = optim.SGD(model.parameters(), lr=.01) # 训练模型 losses = [] accuracies = [] for epoch in range(100): # 前向传播 y_pred = model(X) # 计算损失函数和准确率 loss = criterion(y_pred, y.view(-1, 1)) accuracy = ((y_pred > .5).float() == y.view(-1, 1)).float().mean() # 反向传播和优化 optimizer.zero_grad() loss.backward() optimizer.step() # 记录损失函数和准确率 losses.append(loss.item()) accuracies.append(accuracy.item()) # 打印训练过程 print('Epoch [{}/{}], Loss: {:.4f}, Accuracy: {:.4f}'.format(epoch+1, 100, loss.item(), accuracy.item())) # 测试模型 with torch.no_grad(): y_pred = model(X) accuracy = ((y_pred > .5).float() == y.view(-1, 1)).float().mean() print('Test Accuracy: {:.4f}'.format(accuracy.item())) # 可视化结果 plt.plot(losses) plt.title('Training Loss') plt.xlabel('Epoch') plt.ylabel('Loss') plt.show() plt.plot(accuracies) plt.title('Training Accuracy') plt.xlabel('Epoch') plt.ylabel('Accuracy') plt.show() ``` 在这个示例中,我们使用了乳腺癌数据集作为示例数据集。我们首先将数据集转换为张量,然后定义了一个Logistic回归模型。我们使用二元交叉熵作为损失函数,使用随机梯度下降(SGD)作为优化器。我们训练模型并记录损失函数和准确率,然后使用测试数据集测试模型并计算准确率。最后,我们使用matplotlib库可视化训练和测试的损失函数和准确率。 ### 回答2: Logistic回归是一种二元分类算法,其主要目的是根据给定的输入数据,预测其所属的类别。在本文中,我们将介绍如何使用PyTorch实现Logistic回归。 首先,我们需要导入必要的PyTorch库: import torch import torch.nn as nn import torch.optim as optim 然后,我们需要定义我们的数据集。这里我们假设我们有n个数据样本,每个样本包含m个特征和一个二元类别。我们可以将这些数据存储在两个PyTorch张量中:一个包含特征,一个包含类别标签。 x = torch.randn(n, m) # 特征张量 y = torch.randint(high=2, size=(n, 1)).float() # 类别标签张量 接下来,我们需要定义我们的Logistic回归模型。这里我们将使用一个包含单个线性层的简单神经网络,以及一个sigmoid激活函数。 class LogisticRegression(nn.Module): def __init__(self, input_size): super(LogisticRegression, self).__init__() self.linear = nn.Linear(input_size, 1) def forward(self, x): output = self.linear(x) output = torch.sigmoid(output) return output model = LogisticRegression(m) 接下来,我们需要定义我们的损失函数和优化器。对于Logistic回归,通常使用二元交叉熵作为损失函数,使用随机梯度下降作为优化器。 criterion = nn.BCELoss() optimizer = optim.SGD(model.parameters(), lr=0.1) 现在我们可以开始训练我们的模型了。首先,我们将定义训练的迭代次数。然后,我们将循环n_epochs次并在每次迭代中计算模型的损失和梯度,并使用优化器更新模型参数。 n_epochs = 1000 for epoch in range(n_epochs): # 前向传播 y_pred = model(x) # 计算损失 loss = criterion(y_pred, y) # 反向传播 optimizer.zero_grad() loss.backward() optimizer.step() # 输出当前损失 if epoch % 100 == 0: print('Epoch [{}/{}], Loss: {:.4f}'.format(epoch+1, n_epochs, loss.item())) 最后,我们可以使用训练好的模型预测新的数据。我们只需要将数据传递给模型,然后将输出映射到二元类别。 with torch.no_grad(): y_pred = model(new_data) prediction = (y_pred >= 0.5).float() print('Prediction:', prediction) 总的来说,使用PyTorch实现Logistic回归非常简单。我们只需要定义模型,损失函数和优化器,然后使用反向传播更新模型参数。当然,在实现Logistic回归模型时还有许多其他的考虑因素,例如数据预处理和超参数调整,但这些在这篇文章里并没有讨论。 ### 回答3: pytorch是一个开源的机器学习框架,它可以帮助我们快速实现各种机器学习算法。其中,logistic回归是一个经典的二分类算法,我们可以使用pytorch实现它。 首先,我们需要准备好数据集。通常情况下,我们会将数据集划分为训练集和测试集,用训练集来训练模型,用测试集来测试模型的性能。 然后,我们需要定义模型。对于logistic回归来说,模型通常只有一层线性层和一个sigmoid激活函数。这可以通过pytorch中的nn.Linear和nn.Sigmoid来实现。 接下来,我们需要定义损失函数和优化器。对于logistic回归来说,常用的损失函数是二元交叉熵损失函数。优化器可以选择随机梯度下降法。 然后,我们可以通过迭代训练集中的样本来训练模型。具体来说,对于每一个样本,我们需要调用模型来预测其所属类别,计算预测值和真实值之间的误差,并根据误差更新模型的参数。这可以通过pytorch中的backward和step方法来实现。 最后,我们可以使用测试集来测试模型的性能。具体来说,对于每一个样本,我们需要调用模型来预测其所属类别,并将预测结果和真实值进行比较,计算分类准确率。 以上就是用pytorch实现logistic回归的基本步骤。当然,实际应用中还有很多需要注意和优化的地方,比如数据预处理、超参数调整等等。但是掌握了基本的实现方法,我们就可以应用pytorch实现各种机器学习算法了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bread Sir

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值