一、logistic回归原理及要点
(1)回归输出的是预测的数值,而二分类或者多分类输出的是属于某类别的概率,最后取最大概率的那一类别。
(2)两种实现神经网络中非线性化的方式:
- 高层API:使用
torch.nn.___
,例如torch.nn.Sigmoid()
- 低层API:使用
torch.nn.functional.___
,例如torch.nn.functional.sigmoid()
- 由于高层API是以类的形式调用,有关于全连接层的权重矩阵,偏置矩阵都可以作为类的属性保留,而底层API仅是调用类中的函数运算,不能保存这些信息。高层会依赖低层的计算功能,例如
torch.nn.Linear
依赖于F.linear()
。
参考:pytorch教程之nn.Module类详解——使用Module类来自定义网络层
(3)nn.Linear类可以建立一个线性层,来代替初始化的工作,用于实现
y
=
x
⋅
w
T
+
b
y=x·w^T+b
y=x⋅wT+b的功能。简单讲述一下nn.Linear()
这个函数的参数:
torch.nn.Linear(in_features, out_features, bias)
1> in_features:上一层的神经元个数(输入x的维度)
2> out_featurs:这一层的神经元个数(输出的维度)
3> bias:偏置,默认是True
Examples:
F = torch.nn.Linear(10, 20)
input = torch.randn(120, 10) #生成120×10的服从(0,1)正态分布的随机数矩阵
output = F(input) #经过一层线性变化
print(output.size()) #从120x10变成120x20
Out[1]:
torch.Size([120, 20])
(4)构造神经网络的基本步骤和线性回归一样,重点介绍一下二分类的损失函数(Binary Classification Error),该损失函数是基于交叉熵的概念得到的,交叉熵概念看第(5)点。
B
C
E
=
−
[
y
l
o
g
y
ˆ
+
(
1
−
y
)
l
o
g
(
1
−
y
ˆ
)
]
BCE=-\left[ylog\^y+(1-y)log(1-\^y)\right]
BCE=−[ylogyˆ+(1−y)log(1−yˆ)]
(5)交叉熵简单理解就是当已知真实值y与预测值y_hat的分布情况后,可以通过计算两者之间的相似度来判断预测的准确性,相似度越大越好,而上文的BCE则是加了一个负号,表示损失越小越好。例如下图中计算D分布和T分布的相似度:
二、完整代码
import torch
import numpy as np
import matplotlib.pyplot as plt
import torch.nn.functional as F
#1.Prepare training set
x_data = torch.Tensor([[1.0],[2.0],[3.0]]) #数据集是tensor,且写成矩阵的形式
y_data = torch.Tensor([[0],[0],[1]]) #二分类问题,y的取值是0、1
#2.Design model 构建计算图(Logistic Regression Unit)
class LogisticRegressionModel(torch.nn.Module):
def __init__(self):
super(LogisticRegressionModel, self).__init__()
self.linear = torch.nn.Linear(1, 1) #(in_features, out_features, bias = True)
def forward(self, x):
y_pred = F.sigmoid(self.linear(x)) #self.linear是callable的,是可调用的对象
return y_pred
#实例化
model = LogisticRegressionModel()
#3.Construct Loss and OPtimizer
criterion = torch.nn.BCELoss(size_average = False) #Binary Classification Error
optimizer = torch.optim.SGD(model.parameters(), lr = 0.01) #优化器
#4.Training Cycle 训练并更新
for epoch in range(1000):
y_pred = model(x_data) #使用了实例model,调用了前馈forward
loss = criterion(y_pred, y_data) #求损失loss
print(epoch, loss.item())
optimizer.zero_grad() #梯度归零??
loss.backward() #反向传播
optimizer.step() #更新
#5.Output weight and bias
print('w = ', model.linear.weight.item())
print('b = ', model.linear.bias.item())
#6.Test Model
x_test = torch.Tensor([[1.0]]) #用一个已知的数据来测试?
y_test = model(x_test)
print('y_pred = ', y_test.data) # 取tensor数值
#7.view
x = np.linspace(0, 10, 200)
x_t = torch.Tensor(x).view((200, 1)) #相当于reshape成200*1
y_t = model(x_t)
y = y_t.data.numpy() #将标量转换成矩阵的形式
plt.plot(x, y)
plt.plot([0, 10], [0.5, 0.5])
plt.ylabel('Probability of Pass')
plt.xlabel('Learning Hours')
plt.show()
运行结果: