8 多输出预测与多标签分类pytorch网络搭建


前言

前面我们搭建的无论是分类还是回归都只能预测一个标签,这显然效果很局限。下面我们想做到下面这两种效果:

  • 多输出预测(回归):例如训练网络拟合北东天坐标转机体坐标的关系,输入是三坐标,输出也是三坐标
  • 多标签分类:例如,输入图像数据,训练网络判断图片里面有猫,有狗,还是只有其中一种这样

【注】:在介绍pytorch的内置损失函数博客中已经介绍了pytorch的损失函数是支持这个功能的。

一、多输出预测(回归)

1 坐标数据生成

# 本示例演示如何使用 PyTorch 实现多标签回归模型。
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np

# 构建数据集
# 假设您有一些经纬高度和对应的地心地固坐标的数据
# 这里只是一个示例,您需要根据实际情况准备您自己的数据集
X = np.random.rand(100, 3)  # 100个样本,每个样本有3个特征(经度、纬度、高度)
y = np.random.rand(100, 3)  # 每个样本有3个目标值(地心地固坐标)
print('y:\n',y)

在这里插入图片描述

2 网络搭建训练预测

# 转换数据为 PyTorch 的 Tensor 类型
X_tensor = torch.tensor(X, dtype=torch.float32)
y_tensor = torch.tensor(y, dtype=torch.float32)

# 定义模型
class MultiLabelRegressionModel(nn.Module):
    def __init__(self, input_size, output_size):
        super(MultiLabelRegressionModel, self).__init__()
        self.fc = nn.Linear(input_size, output_size)
        
    def forward(self, x):
        out = self.fc(x)
        return out

# 初始化模型
input_size = 3   # 输入特征的数量
output_size = 3  # 输出目标值的数量
model = MultiLabelRegressionModel(input_size, output_size)

# 定义损失函数和优化器
criterion = nn.MSELoss()  # 均方误差损失函数
optimizer = optim.SGD(model.parameters(), lr=0.01)  # 随机梯度下降优化器

# 训练模型
num_epochs = 100
for epoch in range(num_epochs):
    # Forward pass
    outputs = model(X_tensor)
    loss = criterion(outputs, y_tensor)
    
    # Backward pass and optimization
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    
    if (epoch+1) % 10 == 0:
        print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')

# 测试模型
with torch.no_grad():
    predicted = model(X_tensor).detach().numpy()
    print("Predicted Values:")
    print(predicted)

输出:
在这里插入图片描述

二、多标签分类

1 多标签数据生成

# 多标签分类示例: 在多标签分类任务中,每个样本可以属于多个类别。例如,一个图片分类任务中,一张图片可能同时包含猫、狗和鸟等多种物体。这种情况下,每个样本的标签可以用一个多维张量表示,其中每个元素代表一个类别,如果样本属于该类别则为1,否则为0。用pytorch搭建这个网络(给出生成的数据);显然这是多个二分类问题,最后层用sigmoid函数

import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np

# 生成示例数据
num_samples_train = 1000
num_samples_test = 200
num_classes = 5

# 随机生成多标签分类示例数据
labels_multi_train = np.random.randint(2, size=(num_samples_train, num_classes))
print(f'labels_multi_train:\n{labels_multi_train}')
# 这里标签可以是多个类别,所以是一个二维数组,每一行代表一个样本,每一列代表一个类别,如果该样本属于该类别则为1,否则为0;因为损失函数不同,和多分类不同,这里就不用非要是一维数组了,二维数组才能够表示多标签分类的情况(与demo224)进行对比----后面demo223,224,225都要总结一下写到博客里
labels_multi_test = np.random.randint(2, size=(num_samples_test, num_classes))
features_train = torch.randn(num_samples_train, 3)  # 假设有3个特征
print(f'features_train:\n{features_train}')
features_test = torch.randn(num_samples_test, 3)
print(f'features_test:\n{features_test}')

在这里插入图片描述
在这里插入图片描述

2 网络搭建训练

# 定义多标签分类网络
class MultiLabelClassifier(nn.Module):
    def __init__(self, input_size, output_size):
        super(MultiLabelClassifier, self).__init__()
        self.fc = nn.Linear(input_size, output_size)
        self.sigmoid = nn.Sigmoid()  # 用于多标签分类任务的激活函数

    def forward(self, x):
        x = self.fc(x)
        x = self.sigmoid(x)
        return x

# 初始化网络和损失函数
model = MultiLabelClassifier(input_size=3, output_size=num_classes)
criterion = nn.BCELoss()  # 二分类交叉熵损失函数
#  torch.nn.BCEWithLogitsLoss()  # BCELoss的改进版,将sigmoid和BCELoss合并到一起,可以提高数值稳定性,如果要用最后一层不要加sigmoid,输出值直接用线性输出,这个损失函数会自动加sigmoid进行优化,但最后的predict的时候要手动加sigmoid在判断概率选择类别。
optimizer = optim.Adam(model.parameters(), lr=0.01)

# 将示例数据转换为张量
features_train_tensor = features_train
labels_train_tensor = torch.tensor(labels_multi_train, dtype=torch.float32)
features_test_tensor = features_test
labels_test_tensor = torch.tensor(labels_multi_test, dtype=torch.float32)

# 训练模型
num_epochs = 50
for epoch in range(num_epochs):
    # Forward pass
    outputs = model(features_train_tensor)
    loss = criterion(outputs, labels_train_tensor)

    # Backward pass and optimization
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    if (epoch+1) % 10 == 0:
        print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')

print("训练完成!")

# 测试模型
with torch.no_grad():
    model.eval()
    outputs_test = model(features_test_tensor)
    predicted_labels = (outputs_test > 0.5).float()
    print(f'预测标签: {predicted_labels[0:5, :]}')

# 计算准确率
accuracy = (predicted_labels == labels_test_tensor).all(dim=1).float().mean().item()
print(f'模型准确率: {accuracy:.4f}')

在这里插入图片描述

总结

以上都只构建了一层网络,所以效果很差,这里只是做一个简单的记录而已。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>