PyTrch深度学习简明实战2 -逻辑回归

2023-03-07  本文已影响0人  薛东弗斯
# credit-a.csv
     0      1       2   3   4   5   6   ...  9   10  11  12   13     14  15
0     0  30.83   0.000   0   0   9   0  ...   0   1   1   0  202    0.0  -1
1     1  58.67   4.460   0   0   8   1  ...   0   6   1   0   43  560.0  -1
2     1  24.50   0.500   0   0   8   1  ...   1   0   1   0  280  824.0  -1
3     0  27.83   1.540   0   0   9   0  ...   0   5   0   0  100    3.0  -1
4     0  20.17   5.625   0   0   9   0  ...   1   0   1   2  120    0.0  -1
..   ..    ...     ...  ..  ..  ..  ..  ...  ..  ..  ..  ..  ...    ...  ..
648   0  21.08  10.085   1   1  11   1  ...   1   0   1   0  260    0.0   1
649   1  22.67   0.750   0   0   0   0  ...   0   2   0   0  200  394.0   1
650   1  25.25  13.500   1   1  13   7  ...   0   1   0   0  200    1.0   1
651   0  17.92   0.205   0   0  12   0  ...   1   0   1   0  280  750.0   1
652   0  35.00   3.375   0   0   0   1  ...   1   0   0   0    0    0.0   1

[653 rows x 16 columns]
# 信用卡欺诈数据分类

import torch
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from torch import nn

data = pd.read_csv('./credit-a.csv', header=None)
# print(data)

X = data.iloc[:,:-1]   # 提取数据集的前15列,即除了最后一列以外的所有列
Y = data.iloc[:,-1].replace(-1,0)    # 提取数据集的最后一列,目标值,并将-1替换为0

# 数据预处理,转化为tensor的形式
X = torch.from_numpy(X.values).type(torch.FloatTensor)      # 653行/15列,共15个特征
Y = torch.from_numpy(Y.values.reshape(-1,1)).type(torch.float32)    # reshape(-1,1) 表示变换成不限制行,只有1列,1个特征

# 创建模型
# nn.Sequential可以将多个层顺序连接在一起,形成模型
# 入门代码,用nn.Linear返回模型,因为那个模型是线性模型。
# 现在的模型已经非线性,给每个变量初始化一个权重与特征,之后再传入sigmoid。 线性回归的输出 加上 sigmoid,成为逻辑回归
model = nn.Sequential(
    nn.Linear(15,1),  # nn.Linear in_features=15, out_features=1; 第1层,线性层。   653行15列
    nn.Sigmoid()      # nn.Sigmoid  添加激活层,第2层; 将输入转换为概率;所有的层顺序链接
)
# 用nn.Sequential创建模型,里面可以添加多个层。nn.Sigmod适用的场景,是所有层都顺序链接,前一层的输出交给下一层,一次连接。
# print(model)
# Sequential(
#   (0): Linear(in_features=15, out_features=1, bias=True)
#   (1): Sigmoid()
# )

# 初始化损失函数,二元交叉熵损失
loss_fn = nn.BCELoss()

# 优化函数
# opt = torch.optim.SGD(model.parameters(), lr=0.00001)   # SGD是随机梯度下降,不考虑前面下降了多少。
opt = torch.optim.Adam(model.parameters(), lr=0.00001)   # 会综合考虑前面下降了多少。

# 训练,只是取出一部分数据进行训练。 小批次逐个batch进行训练,不可能将数据全部放下去训练,那样参数过多,硬件无法承受。
# 为什么不一张图片一张图片的训练? 如果这样,就会对异常值极为敏感,导致loss剧烈震荡,用batch就可以避免这一点。
batches = 16
no_of_batches = 653//16    # 全部数据训练一边,需要653//16个批次

# epochs=1000: 将全部数据训练一遍,称之为一个epoch
for epoch in range(1000):
    for batch in range(no_of_batches):   # 一个批次一个批次进行训练
        start = batch*batches            # 第一轮从第0个batch开始,下一轮batch就变成1,...
        end = start + batches            # 每次的结束是start+batches
        x = X[start: end]
        y = Y[start: end]
        y_pred = model(x)
        loss = loss_fn(y_pred, y)
        opt.zero_grad()                 # 调用backward之前,需要将模型中所有变量的当前梯度置为0
        loss.backward()                 # 调用反向更新,计算每个变量的梯度
        opt.step()                      # 使用opt.step() 进行优化。

# 查看训练完后,模型的参数
print(model.state_dict())
# OrderedDict([('0.weight', tensor([[-8.2753e-02, -4.2353e-02,  1.2353e-02,  1.3594e-01,  3.9754e-01,
#           1.7541e-02,  3.7226e-01, -7.6392e-02,  4.3159e-01,  4.3930e-01,
#          -1.1473e-01,  1.2118e-01,  2.5670e-01,  3.3495e-03, -3.9232e-04]])), ('0.bias', tensor([0.1405]))])
# 输出15个weight,1个bias
# sigmoid(w1*x1 + w2*x2 + ... + w15*x15 + b)   这就是这个模型做的事情。

# 获取准确率
accu = ((model(X).data.numpy() > 0.5).astype('int') == Y.numpy()).mean()
# astype('int') numpy转换为int的方法
# 模型调用预测值X,并用.data取出预测值,.numpy()转换为numpy 就获得预测结果,为从0-1之间的小数值。
# (model(X).data.numpy() > 0.5) 大于0.5输出为1,小于0.5输出为0,.astype('int') 转换为int
# (model(X).data.numpy() > 0.5).astype('int')获得预测结果
# Y.numpy()为真实结果
# ((model(X).data.numpy() > 0.5).astype('int') == Y.numpy())  预测错误则值为0,预测正确值为1
# .mean()  直接求均值,获取的就是准确率。  所有的结果相加,再除以结果的数量

print(accu)
# 0.7932618683001531
上一篇下一篇

猜你喜欢

热点阅读