- ✨本文收录于【深度学习】:《PyTorch入门到项目实战》专栏,此专栏主要记录如何使用
PyTorch
实现深度学习笔记,尽量坚持每周持续更新,欢迎大家订阅! - 🌸个人主页:JoJo的数据分析历险记
- 📝个人介绍:小编大四统计在读,目前保研到统计学top3高校继续攻读统计研究生
- 💌如果文章对你有帮助,欢迎✌
关注
、👍点赞
、✌收藏
、👍订阅
专栏
参考资料:本专栏主要以沐神《动手学深度学习》为学习资料,记录自己的学习笔记,能力有限,如有错误,欢迎大家指正。同时沐神上传了的教学视频和教材,大家可以前往学习。
logistic回归
虽然名字是回归,但实际上是一个分类算法,主要处理二分类问题,具体理论部分大家可以看我的这篇文章。机器学习算法:分类算法详解
基本模型如下:
$$ H(x) = \frac{1}{1+e^{-W^TX}} $$
损失函数:
$$ cost(W) = -\frac{1}{m}\sum ylog(H(x))+(1-y)(log(1-H(x)) $$
其中y=1或0
.从损失函数可以看出,如果$y$和$H(x)$很接近,则损失函数越小,下面我们来看看如何使用pytorch实现logistic回归
🥝1.创建数据集
import torch
import torch.nn as nn
import torch.nn.functional as F#神经网络内置函数
import torch.optim as optim
# 设计随机数,为了结果的可复现性
torch.manual_seed(1)
<torch._C.Generator at 0x23225f75f78>
x = torch.tensor([[1, 2], [2, 3], [3, 1], [4, 3], [5, 3], [6, 2]],dtype=torch.float)
y = torch.tensor([[0], [0], [0], [1], [1], [1]],dtype=torch.float)
考虑以下分类问题:给定每个学生观看讲座和在代码实验室工作的小时数,预测学生是否通过了课程。例如,第一个(索引0)学生看了一个小时的讲座,在实验课上花了两个小时([1,2]),结果课程不及格([0])。
🍆2.初始化参数
和之前一样,我们初始化两个参数
W = torch.zeros((2, 1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)
🍇3.计算模型
h = 1 / (1 + torch.exp(-(torch.matmul(x,W) + b)))
tensor([[0.5000],
[0.5000],
[0.5000],
[0.5000],
[0.5000],
[0.5000]], grad_fn=<SigmoidBackward0>)
在torch
中,我们也可以使用torch.sigmoid()
函数得到一样的结果
h = torch.sigmoid(torch.matmul(x,W)+b)
🍓4.定义损失函数
def loss_fun(y,h):
return (-(y * torch.log(h) +
(1 - y) * torch.log(1 - h))).mean()
在nn
中,包含许多内置函数,其中包含了计算交叉熵函数F.binary_cross_entropy
,可以实现与上述代码一样的结果
F.binary_cross_entropy(h, y)
tensor(0.6931, grad_fn=<BinaryCrossEntropyBackward0>)
🍅5.梯度下降求解
optim
中包含了常见的优化算法,包括Adam
,SGD
等,这里我们还是和之前一样使用==随机梯度下降==,后续会介绍其他的优化算法
optimizer = optim.SGD([W, b], lr=0.05)
🍊6.模型训练完整代码
'''
生成数据集
'''
x = torch.tensor([[1, 2], [2, 3], [3, 1], [4, 3], [5, 3], [6, 2]],dtype=torch.float)
y = torch.tensor([[0], [0], [0], [1], [1], [1]],dtype=torch.float)
'''
初始化参数
'''
W = torch.zeros((2, 1), requires_grad=True)
b = torch.zeros(1, requires_grad=True)
'''
训练模型
'''
optimizer = optim.SGD([W, b], lr=0.5)
nb_epochs = 1000
for epoch in range(nb_epochs + 1):
#计算h
h = torch.sigmoid(x.matmul(W) + b)
#计算损失函数
cost = -(y * torch.log(h) +
(1 - y) * torch.log(1 - h)).mean()
# 梯度下降优化
optimizer.zero_grad()
cost.backward()
optimizer.step()
if epoch % 100 == 0:
print('Epoch {:4d}/{} Cost: {:.6f}'.format(
epoch, nb_epochs, cost.item()
))
Epoch 0/1000 Cost: 0.693147
Epoch 100/1000 Cost: 0.232941
Epoch 200/1000 Cost: 0.147042
Epoch 300/1000 Cost: 0.107431
Epoch 400/1000 Cost: 0.084848
Epoch 500/1000 Cost: 0.070247
Epoch 600/1000 Cost: 0.060012
Epoch 700/1000 Cost: 0.052428
Epoch 800/1000 Cost: 0.046575
Epoch 900/1000 Cost: 0.041916
Epoch 1000/1000 Cost: 0.038117
🍒7.评估模型
在我们完成模型的训练后,我们想检查我们的模型是否适合训练集。
# 首先根据估计的参数结果计算h
h = torch.sigmoid(x.matmul(W) + b)
print(h)
tensor([[0.0033],
[0.0791],
[0.1106],
[0.8929],
[0.9880],
[0.9968]], grad_fn=<SigmoidBackward0>)
# 大于0.5的为True,小于0.5的为False
prediction = h >= torch.FloatTensor([0.5])
print(prediction)
tensor([[False],
[False],
[False],
[ True],
[ True],
[ True]])
# 注意在python中0=False,1=True
print(prediction)
print(y)
tensor([[False],
[False],
[False],
[ True],
[ True],
[ True]])
tensor([[0.],
[0.],
[0.],
[1.],
[1.],
[1.]])
# 计算预测值和真实值相同的个数
correct_prediction = prediction.float() == y
print(correct_prediction)
tensor([[True],
[True],
[True],
[True],
[True],
[True]])
# 计算预测正确的数量占总数量的比例
accuracy = correct_prediction.sum().item() / len(correct_prediction)
print('The model has an accuracy of {:2.2f}% for the training set.'.format(accuracy * 100))
The model has an accuracy of 100.00% for the training set.
🥤8.使用nn.Module实现logistic回归
上面为了演示logistic回归
的具体实现原理,我们是使用一步一步实现的,但是在实际中,往往会使用nn.module
或者nn
实现,下面是实现logistic
的简化代码。
'''
定义二元分类器
'''
class BinaryClassifier(nn.Module):
def __init__(self):
super().__init__()
self.linear = nn.Linear(2, 1)
self.sigmoid = nn.Sigmoid()
def forward(self, x):
return self.sigmoid(self.linear(x))
model = BinaryClassifier()
'''
定义随机梯度下降
'''
optimizer = optim.SGD(model.parameters(), lr=0.7)
'''
模型训练
'''
nb_epochs = 100
for epoch in range(nb_epochs + 1):
#计算h
hypothesis = model(x)
# 计算损失函数
cost = F.binary_cross_entropy(hypothesis, y)
# 梯度下降
optimizer.zero_grad()
cost.backward()
optimizer.step()
# 输出结果
if epoch % 10 == 0:
prediction = hypothesis >= torch.FloatTensor([0.5])
correct_prediction = prediction.float() == y
accuracy = correct_prediction.sum().item() / len(correct_prediction)
print('Epoch {:4d}/{} Cost: {:.6f} Accuracy {:2.2f}%'.format(
epoch, nb_epochs, cost.item(), accuracy * 100,
))
Epoch 0/100 Cost: 0.734527 Accuracy 50.00%
Epoch 10/100 Cost: 0.446570 Accuracy 66.67%
Epoch 20/100 Cost: 0.448868 Accuracy 66.67%
Epoch 30/100 Cost: 0.375859 Accuracy 83.33%
Epoch 40/100 Cost: 0.318583 Accuracy 83.33%
Epoch 50/100 Cost: 0.268096 Accuracy 83.33%
Epoch 60/100 Cost: 0.222295 Accuracy 100.00%
Epoch 70/100 Cost: 0.183465 Accuracy 100.00%
Epoch 80/100 Cost: 0.158036 Accuracy 100.00%
Epoch 90/100 Cost: 0.144541 Accuracy 100.00%
Epoch 100/100 Cost: 0.134652 Accuracy 100.00%
本章的介绍到此介绍,如果文章对你有帮助,请多多点赞、收藏、评论、关注支持!!