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