逻辑回归(Logistic Regression)
torchversion提供的数据集
import torchvision # PyTorch提供的工具包
# 手写数字识别集 0-9
# root:存储路径 train:训练集还是测试集 download:从网上下载
train_set = torchvision.datasets.MNIST(root='./dataset/mnist', train=True, download=True)
test_set = torchvision.datasets.MNIST(root='./dataset/mnist', train=False, download=True)
# 彩色小图片数据集 分成10个分类 猫、狗等...
train_set = torchvision.datasets.CIFAR10(root='./dataset/cifar10', train=True, download=True)
test_set = torchvision.datasets.CIFAR10(root='./dataset/cifar10', train=False, download=True)
Logistic Regression:
名字叫回归,却是一种用于解决二分类问题的机器学习方法,逻辑回归是以线性回归为理论支持的,但是逻辑回归通过Sigmoid函数引入了非线性因素,因此可以轻松解决0/1问题。
Sigmoid函数特征:
- 函数值有极限
- 单调增
- 饱和函数
常见的Sigmoid函数:
最出名的就是Logistic Function,因此有些地方直接将Logistic函数称为Sigmoid函数
逻辑回归就是在线性回归的基础上增加一个sigmod函数,保证输出值在0 ~ 1之间。
模型改变,损失函数也要相应地改变:
交叉熵:
详细介绍:详细介绍:https://www.scholat.com/teamwork/showPostMessage.html?id=8939&teamId=1263
假设有两个分布PD、PT
二分类可以使用交叉熵损失BCE函数,当y=1, y ˉ \bar{y} yˉ = 1时loss最小;当y=0, y ˉ \bar{y} yˉ=0时loss最大
torch.tensor()与torch.Tensor()的区别
-
torch.tensor()
是一个函数,用于根据给定的数据创建新的张量。
它接受一个数据(如 Python 列表、NumPy 数组等)作为输入,并返回一个新的张量对象。
torch.tensor() 函数默认会将输入数据进行拷贝,即创建新的数据副本。这意味着如果输入数据是可变的(例如 Python 列表),修改原始数据不会影响新创建的张量。
-
torch.Tensor():
torch.Tensor() 是一个构造函数,用于创建张量的实例。
它接受一个可选的参数 data,可以是一个数据(如 Python 列表、NumPy 数组等),也可以是一个形状(如元组)。
torch.Tensor() 构造函数不会对输入数据进行拷贝,而是直接使用给定的数据创建张量。因此,如果输入数据是可变的(例如 Python 列表),修改原始数据也会影响到新创建的张量。
总的来说,torch.tensor() 更像是一个函数式接口,接受数据并返回新的张量,而 torch.Tensor() 更像是一个构造函数,用于实例化张量对象,直接使用给定的数据创建张量。在大多数情况下,两者都可以用于创建张量,选择哪个取决于你的需求和习惯。如果需要避免原始数据被修改,可以使用 torch.tensor() 创建张量。如果希望直接使用原始数据创建张量,并且希望修改原始数据会影响到张量的值,可以使用 torch.Tensor() 构造函数。
torch.Tensor.view()
作用:返回一个新的张量,其数据与自张量相同,但形状不同。
代码实现:
import torch.nn
import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
# 设置显示中文字体
mpl.rcParams["font.sans-serif"] = ["SimHei"]
# 建立模型
class LogisticRegressionModel(torch.nn.Module):
def __init__(self, *args, **kwargs):
super(LogisticRegressionModel, self).__init__()
self.linear = torch.nn.Linear(1, 1)
def forward(self, x):
y_pred = torch.sigmoid(self.linear(x))
return y_pred
# 准备数据集
x_data = torch.tensor([[1.0], [2.0], [3.0]])
y_data = torch.tensor([[0.], [0.], [1.]])
# y_data = torch.tensor([[0], [0], [1]])
model = LogisticRegressionModel()
criterion = torch.nn.BCELoss(reduction='sum')
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
# 训练
for epoch in range(1000):
y_pred = model(x_data)
loss = criterion(y_pred, y_data)
print(epoch, loss.item())
optimizer.zero_grad()
loss.backward()
optimizer.step()
print('w = ', model.linear.weight.item())
print('b = ', model.linear.bias.item())
# 测试
x_test = torch.Tensor([[4.0]])
y_test = model(x_test)
print('y_pred = ', y_test.item())
# 画图
# np.linspace 生成一个指定大小,指定数据区间的均匀分布序列
x = np.linspace(0, 10, 200) # 返回0-10等间距的200个数
x_t = torch.Tensor(x).view((200, 1)) # 生成一个200行1列的矩阵tensor
y_t = model(x_t)
y = y_t.data.numpy() # 调用numpy将y_t变成n维数组
figure = plt.figure("逻辑回归")
ax = figure.add_subplot()
ax.set_title('逻辑回归')
ax.set_xlabel("Hours")
ax.set_ylabel("Probability of Pass")
ax.plot(x, y)
ax.plot([0, 10], [0.5, 0.5], c='r')
plt.grid(True) # 显示网格线 1=True=默认显示;0=False=不显示
plt.show()