note3

1 softmax 多分类问题

 

 多分类的交叉熵损失函数

 函数知识

1.给类别编码
pd.factorize(data.Species)  # 对species编码
# (array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#        0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
#        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
#        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
#        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
#        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], dtype=int64),
#        Index(['setosa', 'versicolor', 'virginica'], dtype='object'))

from sklearn.model_selection import train_test_split
train_x, test_x, train_y, test_y = train_test_split(X, Y) # 分训练和测试集

绘图
plt.plot(range(1, epochs+1), train_loss, label='train_loss')
plt.plot(range(1, epochs+1), test_loss, label='test_loss')
plt.legend()  # 添加图例
plt.show()

torch.argmax()函数

Pytorch中torch.argmax()函数解析_cv_lhp的博客-CSDN博客_argmax pytorch

# Softmax多分类

import torch
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import torch.nn.functional as F
from sklearn.model_selection import  train_test_split
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader
from torch import nn

data = pd.read_csv('daatset/iris.csv')
data.Species.unique()  # ['setosa' 'versicolor' 'virginica']
pd.factorize(data.Species)  # 对species编码
# (array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
#        0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
#        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
#        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
#        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
#        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], dtype=int64),
#        Index(['setosa', 'versicolor', 'virginica'], dtype='object'))
data['Species'] = pd.factorize(data.Species)[0]  # 把类别用对应编码替换
# print(data)
X = data.iloc[:, 1:-1].values  # 第一个‘:’不包括第一列,‘1:-1‘表示从第二列开始,最后一个不要
Y = data.Species.values

train_x, test_x, train_y, test_y = train_test_split(X, Y) # 分训练和测试集

train_x = torch.from_numpy(train_x).type(torch.float32)
test_x = torch.from_numpy(test_x).type(torch.float32)
train_y = torch.from_numpy(train_y).type(torch.int64)
test_y = torch.from_numpy(test_y).type(torch.int64)

batch = 8

train_ds = TensorDataset(train_x, train_y)
train_dl = DataLoader(train_ds, batch_size=batch, shuffle=True)
test_ds = TensorDataset(test_x, test_y)
test_dl = DataLoader(test_ds, batch_size=batch)


class Model(nn.Module):
    # 定义一个类,从nn.Module中继承
    def __init__(self):  # 初始化
        super().__init__()  # 继承父类中所有属性
        self.liner_1 = nn.Linear(4, 32)  # 输出20层  输出到隐藏层,创建64个隐藏层
        self.liner_2 = nn.Linear(32, 32)
        self.liner_3 = nn.Linear(32, 3)  # 输出层1

    def forward(self, input):
        # 在forward中使用上面的层,参数为self,对input进行处理
        x = F.relu(self.liner_1(input))  # 第一层调用,直接用F调用relu
        x = F.relu(self.liner_2(x))
        x = self.liner_3(x)              #
        return x
model = Model()
loss_fn = nn.CrossEntropyLoss()
optim = torch.optim.Adam(model.parameters(), lr=0.0001)

#如何将预测结果转换为真实对应数据
# input_batch, label_batch = next(iter(train_dl))
# input_batch.shape
# label_batch.shape # (torch.Size([8, 4]), torch.Size([8]))
# y_pred = model(input_batch)
# y_pred.shape # torch.Size([8, 3])
# y_pred
# # tensor([[ 0.2699, -0.0188, -0.0153],
# #         [ 0.2366, -0.0078, -0.0199],
# #         [ 0.0645,  0.0852,  0.0494],
# #         [ 0.0868,  0.0561,  0.0322],
# #         [ 0.2135,  0.0178, -0.0141],
# #         [ 0.0795,  0.0476,  0.0091],
# #         [ 0.3266, -0.0554,  0.0235],
# #         [ 0.0940,  0.0248, -0.0051]], grad_fn=<AddmmBackward>)
# torch.argmax(y_pred, dim=1) # tensor([0, 0, 1, 0, 0, 0, 0, 0])

# print(a)

# 创建训练函数
def accuracy(y_pred,y_true):
    y_pred = torch.argmax(y_pred, dim=1)  # 转换为实际的预测结果
    acc = (y_pred == y_true).float().mean()   # 计算平均正确率
    return acc

train_loss = []
train_acc = []
test_loss = []
test_acc = []

epochs = 20

for epoch in range(epochs):
    for x, y in train_dl:
        y_pred = model(x)
        loss = loss_fn(y_pred.to(torch.float32), y.to(torch.int64))
        optim.zero_grad()
        loss.backward()
        optim.step()  # 优化

    with torch.no_grad():
        epoch_accuracy = accuracy(model(train_x),train_y)
        epoch_loss = loss_fn(model(train_x).to(torch.float32), train_y.to(torch.int64)).data
        epoch_test_accuracy = accuracy(model(test_x), test_y)
        epoch_test_loss = loss_fn(model(test_x).to(torch.float32), test_y.to(torch.int64)).data

        print('epoch', epoch, 'loss: ', round(epoch_loss.item(), 3), 'accuracy:', round(epoch_accuracy.item(),3),
              'test_loss: ', round(epoch_test_loss.item(),3), 'test_accuracy:', round(epoch_test_accuracy.item(),3)
              )

        train_loss.append(epoch_loss)
        train_acc.append(epoch_accuracy)
        test_loss.append(epoch_test_loss)
        test_acc.append(epoch_test_accuracy)
plt.plot(range(1, epochs+1), train_loss, label='train_loss')
plt.plot(range(1, epochs+1), test_loss, label='test_loss')
plt.legend()  # 添加图例
plt.show()

 编写fit函数

输入模型、输入数据,对数据输入在模型上训练,并返回loss和acc

import torch
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import torch.nn.functional as F
from sklearn.model_selection import  train_test_split
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader
from torch import nn

def fit(epoch, model, trainloader, testloater):
    correct = 0  # correct预测成功数
    total = 0  # total训练总样本数
    running_loss = 0
    for x, y in trainloader:
        y_pred = model(x)
        loss = loss_fn(y_pred.to(torch.float32), y.to(torch.int64))
        optim.zero_grad()
        loss.backward()
        optim.step()  # 优化
        with torch.no_grad():
            y_pred = torch.argmax(y_pred, dim=1)  # argmax dim=1返回y_pred每一行最大数值对应的列号
            correct += (y_pred == y).sum().item()  # 累加正确样本个数
            total += y.size(0)                     # 总样本数
            running_loss += loss.item()            # 表示每一个batch的loss
    epoch_acc = correct / total
    epoch_loss = running_loss / len(trainloader.dataset)    # 平均loss    trainloader.dataset 返回对应的ds

    test_correct = 0  # correct预测成功数
    test_total = 0  # total训练总样本数
    test_running_loss = 0
    with torch.no_grad():
        for x, y in testloater:
            y_pred = model(x)
            loss = loss_fn(y_pred.to(torch.float32), y.to(torch.int64))
            y_pred = torch.argmax(y_pred, dim=1)  # argmax dim=1返回y_pred每一行最大数值对应的列号
            test_correct += (y_pred == y).sum().item()  # 累加正确样本个数
            test_total += y.size(0)  # 总样本数
            test_running_loss += loss.item()  # 表示每一个batch的loss
    epoch_test_loss = test_running_loss / len(testloater.dataset)
    epoch_test_acc = test_correct / test_total
    print('epoch', epoch,
          'loss: ', round(epoch_loss, 3),
          'accuracy:', round(epoch_acc, 3),
          'test_loss: ', round(epoch_test_loss, 3),
          'test_accuracy:', round(epoch_test_acc, 3)
             )

    return epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc

data = pd.read_csv('daatset/iris.csv')
data.Species.unique()  # ['setosa' 'versicolor' 'virginica']
pd.factorize(data.Species)  # 对species编码
data['Species'] = pd.factorize(data.Species)[0]  # 把类别用对应编码替换
# print(data)
X = data.iloc[:, 1:-1].values  # 第一个‘:’不包括第一列,‘1:-1‘表示从第二列开始,最后一个不要
Y = data.Species.values

train_x, test_x, train_y, test_y = train_test_split(X, Y) # 分训练和测试集

train_x = torch.from_numpy(train_x).type(torch.float32)
test_x = torch.from_numpy(test_x).type(torch.float32)
train_y = torch.from_numpy(train_y).type(torch.int64)
test_y = torch.from_numpy(test_y).type(torch.int64)

batch = 8

train_ds = TensorDataset(train_x, train_y)
train_dl = DataLoader(train_ds, batch_size=batch, shuffle=True)
test_ds = TensorDataset(test_x, test_y)
test_dl = DataLoader(test_ds, batch_size=batch)

class Model(nn.Module):
    # 定义一个类,从nn.Module中继承
    def __init__(self):  # 初始化
        super().__init__()  # 继承父类中所有属性
        self.liner_1 = nn.Linear(4, 32)  # 输出20层  输出到隐藏层,创建64个隐藏层
        self.liner_2 = nn.Linear(32, 32)
        self.liner_3 = nn.Linear(32, 3)  # 输出层1

    def forward(self, input):
        # 在forward中使用上面的层,参数为self,对input进行处理
        x = F.relu(self.liner_1(input))  # 第一层调用,直接用F调用relu
        x = F.relu(self.liner_2(x))
        x = self.liner_3(x)              #
        return x
model = Model()
loss_fn = nn.CrossEntropyLoss()
optim = torch.optim.Adam(model.parameters(), lr=0.0001)

train_loss = []
train_acc = []
test_loss = []
test_acc = []

epochs = 500
for epoch in range(epochs):
    epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc = fit(epoch, model, train_dl, test_dl)
    train_loss.append(epoch_loss)
    train_acc.append(epoch_acc)
    test_loss.append(epoch_test_loss)
    test_acc.append(epoch_test_acc)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值