PyTorch 深度学习实践-基于SoftMax的多分类

视频指路
参考博客笔记
参考笔记二

文章目录

  • 上课内容
  • 代码实现
  • 作业实现

上课内容

softmax能输出一个分布:每一个输出值>=0,且和=1

说明: 1、softmax的输入不需要再做非线性变换,也就是说softmax之前不再需要激活函数(relu)。softmax两个作用,如果在进行softmax前的input有负数,通过指数变换,得到正数。所有类的概率求和为1。

2、y的标签编码方式是one-hot。我对one-hot的理解是只有一位是1,其他位为0。(但是标签的one-hot编码是算法完成的,算法的输入仍为原始标签)

3、多分类问题,标签y的类型是LongTensor。比如说0-9分类问题,如果y = torch.LongTensor([3]),对应的one-hot是[0,0,0,1,0,0,0,0,0,0].(这里要注意,如果使用了one-hot,标签y的类型是LongTensor,糖尿病数据集中的target的类型是FloatTensor)

4、CrossEntropyLoss <==> LogSoftmax + NLLLoss。也就是说使用CrossEntropyLoss最后一层(线性层)是不需要做其他变化的;使用NLLLoss之前,需要对最后一层(线性层)先进行SoftMax处理,再进行log操作。

在这里插入图片描述
Y是经过独热编码后的值,只有一个概率最大的为1,计算损失只要计算Y为1的Y_hat的损失

在这里插入图片描述

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

import torch
y = torch.LongTensor([0])
z = torch.Tensor([0.2, 0.1, -0.1])
criterion = torch.nn.CrossEntropyLoss()
loss = criterion(z, y)
print(loss)

代码流程:

1.prepare dataset 2.design model using class 3.construct loss and optimizer 4.training cycle + test

import torch
from torchvision import transforms #用来处理图像
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F #用relu()函数
import torch.optim as optim

在这里插入图片描述

transform = transforms.Compose([transforms.ToTensor(), #把输入的图像转变为pytorch张量:c*w*h,将px映射到[0,1]transforms.Normalize((0.1307,), (0.3081,))]) # 归一化,均值和方差,基于经验 

标准化之后让数据变成标准分布,从而可以解决一些问题比如,多层传递之后梯度爆炸的问题

在这里插入图片描述

关于x,view(-1, 784)的说明

在PyTorch中,x.view(-1, 784)是一个非常常见的操作,用于重塑(reshape)张量(tensor)x的形状。这里的view方法不会改变张量的数据,而是返回一个新的张量,这个新张量的数据与原始张量共享内存空间,但具有不同的形状。具体来说,x.view(-1, 784)的作用是将张量x重塑为一个新的二维张量,其中这个新张量的第二维(列数)是784,而第一维(行数)是自动计算的,以确保重塑后的张量总元素数与原始张量x相同。这里的-1是一个特殊的值,它告诉PyTorch自动计算该维度的大小,以保持元素总数不变。这种操作在处理图像数据时特别有用,特别是在处理MNIST数据集时。MNIST数据集中的每个图像是一个28x28的灰度图像,总共784个像素点。如果你有一个包含多个图像的一维张量(比如,每个图像都被展平成了一个784维的向量,并存储在一个一维张量中),你可能想要将这些图像重塑回它们原始的28x28二维形状以便于处理。但是,如果你只是想将这些图像作为特征向量输入到神经网络中,你可能会选择保持它们为784维的向量,并通过x.view(-1, 784)将它们组织成一个二维张量,其中每一行都是一个图像的特征向量。举个例子,假设你有一个包含60000个MNIST图像的一维张量x,每个图像都被展平成了一个784维的向量。那么x的形状将是[60000, 784](如果它已经是二维的,那么你就不需要重塑它)。但是,如果x是一个一维张量,形状为[46800000](因为60000 * 784 = 46800000),那么你可以通过x.view(-1, 784)将其重塑为形状[60000, 784]的二维张量,这样每一行就代表了一个图像的特征向量。

同理,如果想要784行列自动计算则用:x,view(784, -1)

知识点:SoftMax激活函数,多分类交叉熵CrossEntropyLoss,图像transform预处理,训练测试单独封装,torchvision

问题描述:dataset中MINIST数据集读取方式为PIL不能直接输入网络,同时多分类问题输出需要为一个分布

主要思路:利用transform进行预处理,将图片拉直后进入线性网络,利用多分类交叉熵CrossEntropyLoss计算损失值(线性层传入即可,CrossEntropyLoss = SoftMax + NLLLoss)

代码实现

数据处理:transforms构建Compose时用ToTensor转为张量,用Normalize进行标准化(涉及到的函数都来自于torchvision.transforms)
利用dataset中MINIST数据集指定下载、路径、是否为训练集、transform
利用Dataloader整理成分批数据集
由于用线性网络实现,前向传播时先利用view将图像拉直过线性层(注意最后一层不用过激活函数),采用CrossEntropyLoss损失函数
训练:内层循环单独拿出来(传入epoch)记录batch数,进行输出(loss存的是item(),同时输出后记得置零)
测试:
不用计算梯度,利用with torch.no_grad():
利用正确数除以总数记录精确度
总数:累加每个batch的size(0)
正确数:利用``torch.max找到最大概率值,获取其索引于真实值进行比较,利用sum()`汇总数据

import torch
from torchvision import transforms
from torchvision import datasets
from torch.utils.data import DataLoader
import torch.nn.functional as F
import torch.optim as optim# prepare datasetbatch_size = 64
transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.1307,), (0.3081,))]) # 归一化,均值和方差train_dataset = datasets.MNIST(root='../dataset/mnist/', train=True, download=True, transform=transform)
train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size)
test_dataset = datasets.MNIST(root='../dataset/mnist/', train=False, download=True, transform=transform)
test_loader = DataLoader(test_dataset, shuffle=False, batch_size=batch_size)# design model using classclass Net(torch.nn.Module):def __init__(self):super(Net, self).__init__()self.l1 = torch.nn.Linear(784, 512)self.l2 = torch.nn.Linear(512, 256)self.l3 = torch.nn.Linear(256, 128)self.l4 = torch.nn.Linear(128, 64)self.l5 = torch.nn.Linear(64, 10)def forward(self, x):x = x.view(-1, 784)  # -1其实就是自动获取mini_batch# print("x_view ", x.shape)#x_view  torch.Size([64, 784])x = F.relu(self.l1(x))x = F.relu(self.l2(x))x = F.relu(self.l3(x))x = F.relu(self.l4(x))return self.l5(x)  # 最后一层不做激活,不进行非线性变换 softmax+NLLloss等于Cross Entropy softmax在后面使用的损失函数里面包含了,后面会定义自带的crossEntropy交叉熵函数,里面会计算model = Net()# construct loss and optimizer
criterion = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)#冲量(动量)会累加梯度,从而回收上一次计算影响,形象称呼会惯性# training cycle forward, backward, updatedef train(epoch):running_loss = 0.0for batch_idx, data in enumerate(train_loader, 0):# 获得一个批次的数据和标签inputs, target = dataoptimizer.zero_grad()# 获得模型预测结果(64, 10)outputs = model(inputs)# 交叉熵代价函数outputs(64,10),target(64)loss = criterion(outputs, target)loss.backward()optimizer.step()running_loss += loss.item()if batch_idx % 300 == 299:print('[%d, %5d] loss: %.3f' % (epoch+1, batch_idx+1, running_loss/300))running_loss = 0.0#test里面不需要进行反向传播 
def test():correct = 0total = 0with torch.no_grad():for data in test_loader:images, labels = dataoutputs = model(images)_, predicted = torch.max(outputs.data, dim=1) # dim = 1 列从上到下是第0个维度,行从左到右是第1个维度,取值最大的下标正好就是输出的0-9的最大可能total += labels.size(0)correct += (predicted == labels).sum().item() # 张量之间的比较运算print('accuracy on test set: %d %% ' % (100*correct/total))if __name__ == '__main__':for epoch in range(10):train(epoch)test()

在这里插入图片描述

处理图像时更关注一些比较高抽象级别的特征,上面用的是非常原始的特征,所以如果用某些特征提取做分类训练可能效果会更好一点,考虑图像自动提取特征:CNN

作业实现

数据集下载地址

import pandas as pd
import torch
from torch.utils.data import DataLoader, Dataset
import torch.nn.functional as F
import torch.optim as optim# 自定义数据集
class OttoDataset(Dataset):def __init__(self, data, targets=None, transform=None):self.data = dataself.targets = targetsself.transform = transformdef __len__(self):return len(self.data)def __getitem__(self, idx):x = self.data[idx]if self.targets is not None:y = self.targets[idx]return torch.tensor(x, dtype=torch.float32), torch.tensor(y, dtype=torch.long)else:return torch.tensor(x, dtype=torch.float32)# 加载数据
train_df = pd.read_csv('./dataset/otto_train.csv')
test_df = pd.read_csv('./dataset/otto_test.csv')# 提取特征和标签
X_train = train_df.drop(['id', 'target'], axis=1).values
y_train = train_df['target'].map(lambda x: int(x.split('_')[1]) - 1).values  # target 转换为 0-8
X_test = test_df.drop(['id'], axis=1).values
test_ids = test_df['id'].values# 转换为数据集
train_dataset = OttoDataset(X_train, y_train)
test_dataset = OttoDataset(X_test)batch_size = 64
train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size)
test_loader = DataLoader(test_dataset, shuffle=False, batch_size=batch_size)# 设计模型
class Net(torch.nn.Module):def __init__(self):super(Net, self).__init__()self.l1 = torch.nn.Linear(93, 512)self.l2 = torch.nn.Linear(512, 256)self.l3 = torch.nn.Linear(256, 128)self.l4 = torch.nn.Linear(128, 64)self.l5 = torch.nn.Linear(64, 9)  # 输出9类def forward(self, x):x = F.relu(self.l1(x))x = F.relu(self.l2(x))x = F.relu(self.l3(x))x = F.relu(self.l4(x))return self.l5(x)model = Net()# 构造损失函数和优化器
criterion = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)# 训练循环
def train(epoch):running_loss = 0.0for batch_idx, (inputs, target) in enumerate(train_loader, 0):optimizer.zero_grad()outputs = model(inputs)loss = criterion(outputs, target)loss.backward()optimizer.step()running_loss += loss.item()if batch_idx % 300 == 299:print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))running_loss = 0.0# 生成测试集结果并保存为CSV
def generate_test_results():model.eval()results = []with torch.no_grad():for data in test_loader:inputs = dataoutputs = model(inputs)probabilities = F.softmax(outputs, dim=1)results.extend(probabilities.cpu().numpy())# 将结果转换为 DataFrameresults_df = pd.DataFrame(results, columns=[f'Class_{i+1}' for i in range(9)])results_df.insert(0, 'id', test_ids)# 保存为 CSV 文件results_df.to_csv('otto_predictions.csv', index=False, float_format='%.1f')# 主函数
if __name__ == '__main__':for epoch in range(10):train(epoch)generate_test_results()

gpt改进版本:

import pandas as pd
import torch
from torch.utils.data import DataLoader, Dataset
import torch.nn.functional as F
import torch.optim as optim
import numpy as np# 自定义数据集
class OttoDataset(Dataset):def __init__(self, data, ids, targets=None):self.data = dataself.ids = idsself.targets = targetsdef __len__(self):return len(self.data)def __getitem__(self, idx):x = self.data[idx]id = self.ids[idx]if self.targets is not None:y = self.targets[idx]return torch.tensor(x, dtype=torch.float32), torch.tensor(y, dtype=torch.long), idelse:return torch.tensor(x, dtype=torch.float32), id# 加载数据
train_df = pd.read_csv('./dataset/otto_train.csv')
test_df = pd.read_csv('./dataset/otto_test.csv')# 提取特征和标签
X_train = train_df.drop(['id', 'target'], axis=1).values
y_train = train_df['target'].map(lambda x: int(x.split('_')[1]) - 1).values  # target 转换为 0-8
X_test = test_df.drop(['id'], axis=1).values
test_ids = test_df['id'].values# 数据标准化
from sklearn.preprocessing import StandardScalerscaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)# 转换为数据集
train_dataset = OttoDataset(X_train, ids=np.arange(len(X_train)), targets=y_train)
test_dataset = OttoDataset(X_test, ids=test_ids)batch_size = 64
train_loader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size)
test_loader = DataLoader(test_dataset, shuffle=False, batch_size=batch_size)# 设计模型
class Net(torch.nn.Module):def __init__(self):super(Net, self).__init__()self.l1 = torch.nn.Linear(93, 512)self.l2 = torch.nn.Linear(512, 256)self.l3 = torch.nn.Linear(256, 128)self.l4 = torch.nn.Linear(128, 64)self.l5 = torch.nn.Linear(64, 9)  # 输出9类self.dropout = torch.nn.Dropout(0.5)  # Dropoutdef forward(self, x):x = F.relu(self.l1(x))x = self.dropout(F.relu(self.l2(x)))x = self.dropout(F.relu(self.l3(x)))x = F.relu(self.l4(x))return self.l5(x)model = Net()# 构造损失函数和优化器
criterion = torch.nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)# 学习率调度器
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)# 训练循环
def train(epoch):model.train()running_loss = 0.0for batch_idx, (inputs, target, _) in enumerate(train_loader, 0):optimizer.zero_grad()outputs = model(inputs)loss = criterion(outputs, target)loss.backward()optimizer.step()running_loss += loss.item()if batch_idx % 300 == 299:print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))running_loss = 0.0# 测试函数并生成csv
def test():model.eval()results = []with torch.no_grad():for data, ids in test_loader:outputs = model(data)probabilities = F.softmax(outputs, dim=1).numpy()for id, probs in zip(ids, probabilities):results.append([id.item()] + probs.tolist())# 生成csv文件columns = ['id'] + [f'Class_{i+1}' for i in range(9)]df = pd.DataFrame(results, columns=columns)df.to_csv('otto_predictions2.csv', index=False, float_format='%.1f')# 主函数
if __name__ == '__main__':for epoch in range(30):train(epoch)scheduler.step()test()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/47611.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于X86+FPGA+AI的远程医疗系统,支持12/13代 Intel Core处理器

工控主板&#xff1a;支持12/13代 Intel Core处理器&#xff0c;适用于远程医疗系统 顺应数字化、网络化、智能化发展趋势&#xff0c;国内医疗产业改革正在积极推进&#xff0c;远程医疗、智慧医疗等新模式新业态创新发展和应用&#xff0c;市场空间不断扩大&#xff0c;而基…

Web前端Promise

Promise介绍与使用 Promise是什么&#xff1f; 1.抽象表达&#xff1a; Promise是一门新的技术&#xff08;ES6规范&#xff09;Promise是JS中进行异步编程的新解决方案备注&#xff1a;旧方案是单纯使用回调函数 2.具体表达&#xff1a; 从语法上来说&#xff1a;Promise…

Android SurfaceView 组件介绍,挖洞原理详解

文章目录 组件介绍基本概念关键特性使用场景 SurfaceHolder介绍主要功能使用示例 SurfaceView 挖洞原理工作机制 使用SurfaceView展示图片示例创建一个自定义的 SurfaceView类在 Activity 中使用 ImageSurfaceView注意事项效果展示 组件介绍 在 Android 开发中&#xff0c;Sur…

HiFi-GAN——基于 GAN 的声码器,能在单 GPU 上生成 22 KHz 音频

拟议的 HiFiGAN 可从中间表征生成原始波形 源码地址&#xff1a;https://github.com/NVIDIA/DeepLearningExamples 论文地址&#xff1a;https://arxiv.org/pdf/2010.05646.pdf 研究要点包括 **挑战&#xff1a;**基于 GAN 的语音波形生成方法在质量上不及自回归模型和基于流…

纯前端小游戏,4096小游戏,有音效,Html5,可学习使用

// 游戏开始运行create: function(){this.fieldArray [];this.fieldGroup this.add.group();this.score 0;//4096 增加得分this.bestScore localStorage.getItem(gameOptions.localStorageName) null ? 0 : localStorage.getItem(gameOptions.localStorageName);for(var …

vscode及pycharm配置Python文件模板

一、vscode配置方法 第一步&#xff0c;依次点击“File”->“preference”->“Configure User Snippets”&#xff0c;在弹出的框中输入Python&#xff0c;打开python.json 文件 第二步&#xff0c;python.json 文件中输入以下内容&#xff1a; {"Python Template…

QtC++ 设计模式(五)——状态模式

状态模式 序言理解源码 序言 设计模式只是一个抽象的设计模式方法&#xff0c;并不是一个固定使用的搭配&#xff0c;就算是普通switch语句&#xff0c;Map&#xff0c;乃至状态机都是状态模式的其中一种实现方法 状态模式看起来好像和策略模式差不多&#xff0c;主要是其的侧…

Java记事本工具Notepad++

常见的高级记事本 Editplus、Notepad、Sublime Notepad软件的安装和使用 安装&#xff1a;傻瓜式安装 1、选择中文-->【OK】 2、点击【下一步】 3、协议点击【我接受】 4、选择安装路径-->【下一步】 5、点击【下一步】 6、最后点击【安装】 7、将运行取消-->点击…

戴尔电脑开机出现no boot device found错误提示原因分析及解决方法

戴尔电脑是一款不的品牌,戴尔电脑一直以来都是以IT直销享誉全球的。而旗下的戴尔笔记本&#xff0c;更是深受用户们的追捧和喜爱。最近有网友反馈戴尔电脑开机出现no boot device found错误提示是怎么回事&#xff1f;后来发现有很多网友将引导模式改成legacymbr后发现启动时出…

2024-07-18 Unity插件 Odin Inspector8 —— Type Specific Attributes

文章目录 1 说明2 特定类型特性2.1 AssetList2.2 AssetSelector2.3 ChildGameObjectsOnly2.4 ColorPalette2.5 DisplayAsString2.6 EnumPaging2.7 EnumToggleButtons2.8 FilePath2.9 FolderPath2.10 HideInInlineEditors2.11 HideInTables2.12 HideMonoScript2.13 HideReferenc…

对消息队列进行深入学习

目录 1.什么是消息队列。1.1消息队列1.1.1同步的理解1.1.2异步的理解 1.2消息传递与消息队列 2. 消息队列应用场景2.1 异步处理2.2 流量削锋2.3 应用解耦2.4 日志处理2.5 消息通讯2.6 延时任务2.7 广播消费2.8 分布式事务 3. 主流消息队列3.1 RabbitMQ3.1.1 RabbitMQ工作原理3.…

仅两家!云原生向量数据库 PieCloudVector 全项通过信通院「可信数据库」评测

7月16日&#xff0c;2024 可信数据库发展大会在北京隆重举行。大会以“自主、创新、引领”为主题&#xff0c;近百位数据库领域的专家、学者齐聚一堂&#xff0c;带来高质量的数据库技术洞察与实战经验。 本次可信数据库发展大会中&#xff0c;中国信通院正式公布 2024 年上半年…

紫光展锐5G安卓核心板T760__国产手机芯片方案

展锐T760安卓核心板是具备续航和性能更加均衡的5G移动平台。其主要特点包括主流的6400万像素摄像头和高达120Hz的刷新率。 平台采用多模融合的创新架构和AI智能调节技术&#xff0c;从而在5G数据场景下降低了37%的整体功耗&#xff0c;在5G待机场景下降低了18%的整体功耗。 多…

qml 实现一个listview

主要通过qml实现listvie功能&#xff0c;主要包括右键菜单&#xff0c;滚动条&#xff0c;拖动改变内容等&#xff0c;c 与 qml之间的变量和函数的调用。 main.cpp #include <QQuickItem> #include <QQmlContext> #include "testlistmodel.h" int main…

js vue axios post 数组请求参数获取转换, 后端go参数解析(gin框架)全流程示例

今天介绍的是前后端分离系统中的请求参数 数组参数的生成&#xff0c;api请求发送&#xff0c;到后端请求参数接收的全过程示例。 为何会有这个文章&#xff1a;后端同一个API接口同时处理单条或者多条数据&#xff0c;这样就要求我们在前端发送请求参数的时候需要统一将请…

C/C++ xml库

文章目录 一、介绍1.1 xml 介绍1.2 xml 标准1.3 xml 教程1.4 xml 构成 二、C/C xml 库选型2.1 选型范围2.2 RapidXML2.3 tinyxml22.4 pugixml2.5 libxml 五、性能比较5.1 C xml 相关的操作有哪些5.2 rapidxml、Pugixml、TinyXML2 文件读取性能比较 六、其他问题6.1 version和 e…

网络编程-TCP 协议的三次握手和四次挥手做了什么

TCP 协议概述 1. TCP 协议简介 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议。 TCP 协议提供可靠的通信服务&#xff0c;通过校验和、序列号、确认应答、重传等机制保证数据传输…

MYSQL——库表操作

MYSQL——库表操作 1.1 SQL语句基础1.1.1. SQL简介1.1.2. SQL语句分类1.1.3. SQL语句的书写规范 1.2数据库的操作1.2.1 数据库的登录及退出1.2.2查看数据库 作业 1.1 SQL语句基础 1.1.1. SQL简介 SQL:结构化查询语言(Structured Query Language)&#xff0c;在关系型数据库上…

【ffmpeg入门】安装CUDA并使用gpu加速

文章目录 前言CUDACUDA是什么CUDA 的主要组成部分CUDA 的优点CUDA 的基本编程模型安装CUDA ffmpeg使用gpu加速为什么需要使用gpu加速1. 提高处理速度2. 减少 CPU 负载3. 提高实时处理能力4. 支持高分辨率和复杂编码格式5. 提供更好的可扩展性6. 提高能效 ffmpeg使用gpu加速常用…

【CMU博士论文】结构化推理增强大语言模型(Part 0)

问题 &#xff1a;语言生成和推理领域的快速发展得益于围绕大型语言模型的用户友好库的普及。这些解决方案通常依赖于Seq2Seq范式&#xff0c;将所有问题视为文本到文本的转换。尽管这种方法方便&#xff0c;但在实际部署中存在局限性&#xff1a;处理复杂问题时的脆弱性、缺乏…