pytorch argmax_一起无聊地用PyTorch刷爆sklearn的内置数据集吧(`?ω?′)
我们都知道sklearn有一个datasets的子库,里面有许多可以直接调取的小型数据集。我们可以通过PyTorch来在这些数据集上做训练和预测。
只是无聊。测试速度。如果你是一个刚刚上手pytorch的新手玩家,你也可以通过这个来刷刷题,练练手。
看看从数据集的调用,网络的建立到训练评估你要花多长时间。
本文并没有什么技术含量,只是单纯为了熟悉。你完全可以端着一杯咖啡边喝边利用PyTorch消解“无聊”的weekend
波士顿房价预测
使用线性层在波士顿房价数据集上建立模型
先导入相关库,因为数据量小,我们可以一次性学习一整个数据集,所以此处我们就不构建数据加载器了。
from sklearn.datasets import load_bostonimport torch.nn as nnimport torchimport matplotlib.pyplot as pltimport pandas as pdX, y = load_boston(return_X_y=True)# X.shape : (506, 13)# y.shape : (506,)# type : <class 'numpy.ndarray'>
然后构建线性层类LR
:
class LR(nn.Module):def __init__(self, input_dim, output_dim):super(LR, self).__init__()self.fc = nn.Sequential(nn.Linear(input_dim, 64),nn.Linear(64, 128),nn.Linear(128, 32),)self.regression = nn.Linear(32, 1)def forward(self, x):out = self.fc(x)out = self.regression(out)return out
接下来,记得把输入数据转换成tensor,并获取训练需要的对象:
# 数据类型转换X_t = torch.tensor(X, dtype=torch.float32)y_t = torch.tensor(y, dtype=torch.float32)# 网络实例化net = LR(input_dim=13, output_dim=1)# 获取损失函数loss_func = nn.MSELoss()# 获取优化器对象optimizer = torch.optim.Adam(net.parameters(), lr=0.0001)loss_all = []
最后训练网络,并做数据可视化:
# 开始训练for epoch in range(25):# 前向传播output = net(X_t)# 计算损失loss = loss_func(output.flatten(), y_t.flatten())# 梯度清空optimizer.zero_grad()# 反向传播loss.backward()# 更新网络optimizer.step()loss_all.append(loss.item())data = pd.DataFrame({"loss" : loss_all}, columns=["loss"])data["loss"].plot(x="iteration", y="loss")plt.show()
out:
手写数字集识别
手写数字集,这个你可以认为是小型的MNIST,MNIST是28*28的,而sklearn中提供的是8*8,而且给了1797条,用来玩够了。
我会无聊地使用线性层,卷积层,循环层分别搭建网络来预测这个小型手写数字集。
先导入需要使用的手写数字集,并观察形状:
from sklearn.datasets import load_digitsfrom sklearn.metrics import accuracy_scoreimport matplotlib.pyplot as pltimport numpy as npimport pandas as pdimport torch.nn as nnimport torchimport torch.utils.data as Datafrom random import shuffleX, y = load_digits(return_X_y=True)# X.shape:(1797, 64)# y.shape:(1797,)# type : <class 'numpy.ndarray'># 构建数据加载器img = X[0].reshape([8, 8])plt.imshow(img, cmap=plt.cm.gray)plt.show()
out:
定义数据加载器:
# 原数据可能会把相近的类别放在一起,所以分割数据前最好要打乱choose_index = np.arange(X.shape[0])shuffle(choose_index)# 转换为tensorX_t = torch.tensor(X, dtype=torch.float32)y_t = torch.tensor(y, dtype=torch.int64)# 将数据和标签整合在一起train_data = Data.TensorDataset(X_t[choose_index[:1300]],y_t[choose_index[:1300]])test_data = Data.TensorDataset(X_t[choose_index[1300:]],y_t[choose_index[1300:]])# 构建数据加载器train_loader = Data.DataLoader(dataset=train_data,batch_size=64,shuffle=True,num_workers=0)test_loader = Data.DataLoader(dataset=test_data,batch_size=64,shuffle=True,num_workers=0)
我们测试一下loader,并可视化一个batch中的第一张图片及其对应的标签,看看loader是否正常工作:
for batch in train_loader:img = batch[0][1]label = batch[1][1]img = img.data.numpy().reshape([8,8])plt.imshow(img, cmap=plt.cm.gray)plt.title(f"label={label}")breakplt.show()
out:
下面尝试使用线性算子、卷积算子,循环神经网络来建立模型
线性层的效果
先使用线性层预测,首先定义网络:
# 定义网络class LinearLayerClassifier(nn.Module):def __init__(self, input_dim, output_dim):super(LinearLayerClassifier, self).__init__()self.linear_layer = nn.Sequential(nn.Linear(input_dim, 128),nn.Tanh(),nn.Linear(128, 256),nn.Tanh(),nn.Linear(256, 128),nn.Tanh(),nn.Linear(128, 64),nn.Tanh(),)self.output = nn.Sequential(nn.Linear(64, output_dim),nn.Tanh(),)def forward(self, x):out = self.linear_layer(x)out = self.output(out)# 最后对结果softmax一下softmax_result = nn.functional.softmax(out, dim=1)return softmax_result
然后获取训练需要的对象:
# 网络实例化net = LinearLayerClassifier(input_dim=64, output_dim=10)# 获取优化器optimizer = torch.optim.RMSprop(net.parameters(), lr=0.001)# 获取损失函数loss_func = nn.CrossEntropyLoss(reduction="mean")# 记录损失train_loss, train_acc = [], []test_loss, test_acc = [], []
训练并做数据可视化:
# 开始训练for epoch in range(8):# 遍历生成器net.train()epoch_loss, epoch_acc = [], [] # 记录当前epoch的loss和accuracyfor batch in train_loader:data, label = batch# 前向传播output = net(data)# 预测标签predict_label = torch.argmax(output, dim=1)# 计算损失loss = loss_func(output, label)# 梯度清空optimizer.zero_grad()# 反向传播loss.backward()# 更新参数optimizer.step()# 记录训练结果epoch_loss.append(loss.item())epoch_acc.append(accuracy_score(predict_label, label))train_loss.append(np.mean(epoch_loss))train_acc.append(np.mean(epoch_acc))# 遍历测试集net.eval()epoch_loss, epoch_acc = [], []for batch in test_loader:data, label = batchoutput = net(data)predict_label = torch.argmax(output, dim=1)loss = loss_func(output, label)epoch_loss.append(loss.item())epoch_acc.append(accuracy_score(predict_label, label))test_loss.append(np.mean(epoch_loss))test_acc.append(np.mean(epoch_acc))# 可视化数据label_name = ["train_loss", "test_loss", "train_acc", "test_acc"]for index, name in enumerate([train_loss, test_loss, train_acc, test_acc]):plt.plot(name, "o-", label=label_name[index])plt.legend()plt.grid(True)plt.show()
out:
模型最终收敛了,但是显然很不稳定
CNN算子的效果
由于卷积和后续的循环神经网络都需要基于各自类型的数据维度,CNN的基本输入数据维度为[B, C, H, W],RNN的基本输入维度为[B, time_step, embedding_dim]。所以我们需要重构数据加载器。其实重构很简单,我们只要修改X的维度即可:
X, y = load_digits(return_X_y=True)# X.shape:(1797, 64)# y.shape:(1797,)# type : <class 'numpy.ndarray'>X = [x.reshape([1, 8, 8]).tolist() for x in X]# 原数据可能会把相近的类别放在一起,所以分割数据前最好要打乱choose_index = np.arange(1797)shuffle(choose_index)# 转换成tensorX_t = torch.tensor(X, dtype=torch.float32)y_t = torch.tensor(y, dtype=torch.int64)# 将数据和标签整合在一起train_data = Data.TensorDataset(X_t[choose_index[:1300]], y_t[choose_index[:1300]])test_data = Data.TensorDataset(X_t[choose_index[1300:]], y_t[choose_index[1300:]])# 构建数据加载器train_loader = Data.DataLoader(dataset=train_data,batch_size=64,shuffle=True,num_workers=0)test_loader = Data.DataLoader(dataset=test_data,batch_size=64,shuffle=True,num_workers=0)
其实上面只改了一行代码(第六行)
接下来搭建网络类:
# 定义网络class CNNClassifier(nn.Module):def __init__(self, input_channels, output_dim):super(CNNClassifier, self).__init__()self.conv = nn.Sequential(nn.Conv2d(in_channels=input_channels,out_channels=16,kernel_size=3,stride=1,padding=1), # [B, 16, 8, 8]nn.Tanh(),nn.Conv2d(16, 32, 3, 2, 1), # [B, 32, 4, 4]nn.Tanh(),nn.Conv2d(32, 16, 3, 2, 1), # [B, 16, 2, 2]nn.Tanh(),nn.Conv2d(16, 8, 3, 1, 1) # [B, 8, 2, 2])self.output = nn.Linear(32, 10)def forward(self, x):out = self.conv(x)# out : [B, 8, 2, 2]out = self.output(out.flatten(start_dim=1))out = nn.functional.softmax(out, dim=1)return out
接下来的训练和各种对象的获取和上面线性算子的过程一致,除了网络实例化:
# 网络实例化net = CNNClassifier(input_channels=1, output_dim=10)
out:
效果看起来没有线性算子好,因为处理的图片还是很小的且通道数只有一,等到处理的图片较大,且有多个颜色通道时,卷积算子的优势就会体现得比较明显了。
RNN算子的效果
此处的RNN的cell就使用GRU算子。首先还是修改数据输入维度,和CNN相比,RNN的数据维度少了通道这一维,所以我们在数据加载器这一步,我们只要改一步:
X = [x.reshape([8, 8]).tolist() for x in X]
定义RNN网络,我们使用GRU算子:
# 定义网络class RNNClassifier(nn.Module):def __init__(self, input_size, hidden_size, n_layers=1):super(RNNClassifier, self).__init__()self.gru = nn.GRU(input_size=input_size,hidden_size=hidden_size,num_layers=n_layers,batch_first=True)self.output = nn.Linear(hidden_size, 10)def forward(self, embedding):# embedding : [B, 8, 8]outputs, hidden = self.gru(embedding)# outputs : [B, 8, 32]# hidden : [1, B, 32]out = outputs[:,-1,:]out = self.output(out).softmax(dim=1)return out
然后最后的还是和上面一样,除了网络实例化:
# 网络实例化net = RNNClassifier(input_size=8, hidden_size=64)
out:
鸢尾花数据集分类
该数据集为三分类数据集。每条数据有4个特征。
先导入需要的库,并导入数据集:
import torchfrom torch import nnfrom sklearn.datasets import load_irisfrom sklearn.metrics import accuracy_score, classification_reportimport numpy as npimport matplotlib.pyplot as pltX, y = load_iris(return_X_y=True)# X.shape = (150,4)# y.shape = (150,)sample_num = X.shape[0]
由于原本的数据集中标签相同的数据是放在一起的,所以我们在使用前需要先打乱数据:
# 分割获取训练集和测试集index = np.arange(sample_num)np.random.shuffle(index)split_ratio = 0.8 # 训练集的比例offline = int(split_ratio * sample_num) # 划分的索引界线# 训练集train_X = torch.tensor(X[index[:offline]], dtype=torch.float32)train_y = torch.tensor(y[index[:offline]], dtype=torch.int64)# 测试集test_X = torch.tensor(X[index[offline:]], dtype=torch.float32)test_y = torch.tensor(y[index[offline:]], dtype=torch.int64)
然后定义我们的网络,此时还是使用简单的MLP:
# 定义网络class MyNet(nn.Module):def __init__(self):super(MyNet, self).__init__()self.fc = nn.Sequential(nn.Linear(4, 32),nn.ReLU(),nn.Linear(32, 64),nn.ReLU(),nn.Linear(64, 3),nn.Tanh())def forward(self, x):out = self.fc(x)return out.softmax(dim=1)
接下来我们实例化网络并获取训练需要的损失函数与优化器对象,继而开始训练。由于数据量很小,所以我们直接一次性使用整个训练集做前馈:
# 网络实例化net = MyNet()# 获取损失函数和优化器loss_func = nn.CrossEntropyLoss()optimizer = torch.optim.RMSprop(net.parameters(), lr=1e-3)losses = []acc = []# 开始训练net.train()for epoch in range(20):# 前向传播output = net(train_X)# 计算预测标签值pre_label = torch.argmax(output, dim=1)# 计算损失loss = loss_func(output, train_y)# 梯度清空optimizer.zero_grad()# 反向传播loss.backward()# 更新参数optimizer.step()# 记录训练过程losses.append(loss.item())acc.append(accuracy_score(pre_label, train_y))# 可视化训练过程plt.style.use("seaborn")plt.plot(losses, label="loss")plt.plot(acc, label="acc")plt.legend()plt.show()
out:
out:
precision recall f1-score support0 1.00 1.00 1.00 121 1.00 1.00 1.00 112 1.00 1.00 1.00 7micro avg 1.00 1.00 1.00 30macro avg 1.00 1.00 1.00 30weighted avg 1.00 1.00 1.00 30
由于数据量太小了,所以训练结果会因为随机化分割数据集的结果而有较大的区别
癌症数据集分类
该数据集任务为二分类,输出是否为癌症患者。该数据的每条有30个特征。
引入库和数据集:
from sklearn.datasets import load_breast_cancerfrom sklearn.metrics import accuracy_score, classification_reportimport torchfrom torch import nnimport matplotlib.pyplot as pltimport numpy as npX, y = load_breast_cancer(return_X_y=True)# X.shape = (569, 30)# y.shape = (569, )
将数据转化为tensor,并打乱,切分:
index = np.arange(X.shape[0])np.random.shuffle(index)X_t = torch.tensor(X, dtype=torch.float32)y_t = torch.tensor(y, dtype=torch.int64)train_X, train_y = X_t[index[:500]], y_t[index[:500]]test_X, test_y = X_t[index[500:]], y_t[index[500:]]
分类器网络定义成一个简单的MLP:
class cancerClassifier(nn.Module):def __init__(self, input_dim, output_dim):super(cancerClassifier, self).__init__()self.fc = nn.Sequential(nn.Linear(input_dim, 64),nn.ReLU(),nn.Linear(64, 128),nn.ReLU(),nn.Linear(128, 64),nn.ReLU(),nn.Linear(64, 32),nn.ReLU(),nn.Linear(32, 16),nn.ReLU(),nn.Linear(16, 8),nn.ReLU(),nn.Linear(8, 2),nn.Tanh())def forward(self, x):out = self.fc(x)return out.softmax(dim=1)
实例化网络、获取优化器、训练、可视化、测试网络:
# 网络实例化net = cancerClassifier(input_dim=30,output_dim=2)# 获取优化器optimizer = torch.optim.RMSprop(net.parameters(), lr=1e-4)train_loss, train_acc = [], []for epoch in range(20):output = net(train_X)pre_label = torch.argmax(output, dim=1)loss = nn.functional.cross_entropy(output, train_y, reduction="mean")optimizer.zero_grad()loss.backward()optimizer.step()train_loss.append(loss.item())train_acc.append(accuracy_score(pre_label, train_y))plt.style.use("seaborn")plt.plot(train_loss, label="loss")plt.plot(train_acc, label="acc")plt.legend()plt.show()# 在测试集上检测结果net.eval()output = net(test_X)pre_label = torch.argmax(output, dim=1)print(classification_report(pre_label, test_y))
out:
这个模型好像很不稳定,随着初始数据随机划分的结果不同,网络acc有时会收敛到65%,有时会收敛到90%,若有更好的网络方案,欢迎在评论区提出。
to be continued...
pytorch argmax_一起无聊地用PyTorch刷爆sklearn的内置数据集吧(`?ω?′)相关推荐
- pytorch argmax_轻松学Pytorch使用ResNet50实现图像分类
点击上方蓝字关注我们 微信公众号:OpenCV学堂 关注获取更多计算机视觉与深度学习知识 Hello大家好,这篇文章给大家详细介绍一下pytorch中最重要的组件torchvision,它包含了常见的 ...
- pytorch 模型可视化_高效使用Pytorch的6个技巧:为你的训练Pipeline提供强大动力
点击上方"AI公园",关注公众号,选择加"星标"或"置顶" 作者:Eugene Khvedchenya 编译:ronghuaiyang 导读 ...
- Python深度学习:基于PyTorch [Deep Learning with Python and PyTorch]
作者:吴茂贵,郁明敏,杨本法,李涛,张粤磊 著 出版社:机械工业出版社 品牌:机工出版 出版时间:2019-11-01 Python深度学习:基于PyTorch [Deep Learning with ...
- pytorch 指定卡1_[原创][深度][PyTorch] DDP系列第一篇:入门教程
引言 DistributedDataParallel(DDP)是一个支持多机多卡.分布式训练的深度学习工程方法.PyTorch现已原生支持DDP,可以直接通过torch.distributed使用,超 ...
- pytorch 矩阵相乘_深度学习 — — PyTorch入门(三)
点击关注我哦 autograd和动态计算图可以说是pytorch中非常核心的部分,我们在之前的文章中提到:autograd其实就是反向求偏导的过程,而在求偏导的过程中,链式求导法则和雅克比矩阵是其实现 ...
- 从零开始学Pytorch(零)之安装Pytorch
本文首发于公众号"计算机视觉cv" Pytorch优势 聊聊为什么使用Pytorch,个人觉得Pytorch比Tensorflow对新手更为友善,而且现在Pytorch在学术界 ...
- 【深度之眼PyTorch框架班第五期】作业打卡01:PyTorch简介及环境配置;PyTorch基础数据结构——张量
文章目录 任务名称 任务简介 详细说明 作业 1. 安装anaconda,pycharm, CUDA+CuDNN(可选),虚拟环境,pytorch,并实现hello pytorch查看pytorch的 ...
- Pytorch 学习(7):Pytorch中的Non-linear Activations (非线性层)实现
Pytorch 学习(7):Pytorch中的Non-linear Activations (非线性层)实现 Pytorch中的Non-linear Activations (非线性层)包括以下激活函 ...
- Stanford CS224N: PyTorch Tutorial (Winter ‘21) —— 斯坦福CS224N PyTorch教程 (第二部分)
本教程译文的第一部分,请见我的上一篇博文: Stanford CS224N: PyTorch Tutorial (Winter '21) -- 斯坦福CS224N PyTorch教程 (第一部分)_放 ...
最新文章
- 【新手向】什么是“框架”?
- linux 线程--内核线程、用户线程实现方法
- css中单位em和rem
- 字符设备驱动程序的传统写法
- 区块链100问 第一问
- String案例 获取一个字符串在另一个字符串中出现的次数(两种方法)
- LeetCode 756. 金字塔转换矩阵(回溯)
- nodejs核心模块fs删除文件_用 NodeJS 重命名系统文件
- 微软将允许Epic Games等App登上微软商店
- 万人云峰会DevSecOps论坛:数字化浪潮下,安全开发与运维该如何破局?
- ros 发布信息频率_ROS入门笔记二基础
- php到岗第一天都做什么,十天学会php之第一天
- python3带tkinter窗口的ftp服务器,并使用pyinstaller打包成exe
- 日新测试软件,禁Ping多线程批量检测工具V2.6,功能强大,你值得拥有【2020.05.09日更新】...
- 小甲鱼 C语言 15课
- Spark环境搭建(保姆级教程)
- 常见动词的过去式和过去分词
- 我的新书《Flutter 开发之旅从南到北》终于和大家见面了(抽奖送书啦)。
- 计步器java计算月平均,我们行走时,计步器都会纪录,那计步器是怎么计算我们的步数的?...
- 一文看懂25个神经网络模型,神经网络模型结构图