我们都知道sklearn有一个datasets的子库,里面有许多可以直接调取的小型数据集。我们可以通过PyTorch来在这些数据集上做训练和预测。

只是无聊。测试速度。如果你是一个刚刚上手pytorch的新手玩家,你也可以通过这个来刷刷题,练练手。

看看从数据集的调用,网络的建立到训练评估你要花多长时间。
本文并没有什么技术含量,只是单纯为了熟悉。你完全可以端着一杯咖啡边喝边利用PyTorch消解“无聊”的weekend


波士顿房价预测

使用线性层在波士顿房价数据集上建立模型

先导入相关库,因为数据量小,我们可以一次性学习一整个数据集,所以此处我们就不构建数据加载器了。

 from sklearn.datasets import load_bostonimport torch.nn as nnimport torchimport matplotlib.pyplot as pltimport pandas as pd​X, 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:

v2-962fad8c6e62996203f3e12290fec65a_b.jpg

手写数字集识别

手写数字集,这个你可以认为是小型的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 shuffle​X, 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:

v2-ec302e981c422f0dbac948104da45f2a_b.jpg

定义数据加载器:

 # 原数据可能会把相近的类别放在一起,所以分割数据前最好要打乱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:

v2-d05db4f7b072a98a3365e1bae57fdc33_b.jpg

下面尝试使用线性算子、卷积算子,循环神经网络来建立模型

线性层的效果

先使用线性层预测,首先定义网络:

 # 定义网络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:

v2-7751680e570f75ef089f82d5ea5bafdd_b.jpg

模型最终收敛了,但是显然很不稳定

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:

v2-7ce8e8f95db000dbdcef0fd43ba966a1_b.jpg

效果看起来没有线性算子好,因为处理的图片还是很小的且通道数只有一,等到处理的图片较大,且有多个颜色通道时,卷积算子的优势就会体现得比较明显了。

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:

v2-3e3ea346b722ff0203161420f37facaa_b.jpg

鸢尾花数据集分类

该数据集为三分类数据集。每条数据有4个特征。

先导入需要的库,并导入数据集:

 import torchfrom torch import nnfrom sklearn.datasets import load_irisfrom sklearn.metrics import accuracy_score, classification_reportimport numpy as npimport matplotlib.pyplot as plt​X, 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:

v2-510357681bf1b87a438fe46b1a4eb161_b.jpg

out:

               precision    recall  f1-score   support​0       1.00      1.00      1.00        121       1.00      1.00      1.00        112       1.00      1.00      1.00         7​micro 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 np​X, 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:

v2-7b220730526825c808edb653657994dc_b.jpg

这个模型好像很不稳定,随着初始数据随机划分的结果不同,网络acc有时会收敛到65%,有时会收敛到90%,若有更好的网络方案,欢迎在评论区提出。

to be continued...

pytorch argmax_一起无聊地用PyTorch刷爆sklearn的内置数据集吧(`?ω?′)相关推荐

  1. pytorch argmax_轻松学Pytorch使用ResNet50实现图像分类

    点击上方蓝字关注我们 微信公众号:OpenCV学堂 关注获取更多计算机视觉与深度学习知识 Hello大家好,这篇文章给大家详细介绍一下pytorch中最重要的组件torchvision,它包含了常见的 ...

  2. pytorch 模型可视化_高效使用Pytorch的6个技巧:为你的训练Pipeline提供强大动力

    点击上方"AI公园",关注公众号,选择加"星标"或"置顶" 作者:Eugene Khvedchenya 编译:ronghuaiyang 导读 ...

  3. Python深度学习:基于PyTorch [Deep Learning with Python and PyTorch]

    作者:吴茂贵,郁明敏,杨本法,李涛,张粤磊 著 出版社:机械工业出版社 品牌:机工出版 出版时间:2019-11-01 Python深度学习:基于PyTorch [Deep Learning with ...

  4. pytorch 指定卡1_[原创][深度][PyTorch] DDP系列第一篇:入门教程

    引言 DistributedDataParallel(DDP)是一个支持多机多卡.分布式训练的深度学习工程方法.PyTorch现已原生支持DDP,可以直接通过torch.distributed使用,超 ...

  5. pytorch 矩阵相乘_深度学习 — — PyTorch入门(三)

    点击关注我哦 autograd和动态计算图可以说是pytorch中非常核心的部分,我们在之前的文章中提到:autograd其实就是反向求偏导的过程,而在求偏导的过程中,链式求导法则和雅克比矩阵是其实现 ...

  6. 从零开始学Pytorch(零)之安装Pytorch

    本文首发于公众号"计算机视觉cv" Pytorch优势   聊聊为什么使用Pytorch,个人觉得Pytorch比Tensorflow对新手更为友善,而且现在Pytorch在学术界 ...

  7. 【深度之眼PyTorch框架班第五期】作业打卡01:PyTorch简介及环境配置;PyTorch基础数据结构——张量

    文章目录 任务名称 任务简介 详细说明 作业 1. 安装anaconda,pycharm, CUDA+CuDNN(可选),虚拟环境,pytorch,并实现hello pytorch查看pytorch的 ...

  8. Pytorch 学习(7):Pytorch中的Non-linear Activations (非线性层)实现

    Pytorch 学习(7):Pytorch中的Non-linear Activations (非线性层)实现 Pytorch中的Non-linear Activations (非线性层)包括以下激活函 ...

  9. Stanford CS224N: PyTorch Tutorial (Winter ‘21) —— 斯坦福CS224N PyTorch教程 (第二部分)

    本教程译文的第一部分,请见我的上一篇博文: Stanford CS224N: PyTorch Tutorial (Winter '21) -- 斯坦福CS224N PyTorch教程 (第一部分)_放 ...

最新文章

  1. 【新手向】什么是“框架”?
  2. linux 线程--内核线程、用户线程实现方法
  3. css中单位em和rem
  4. 字符设备驱动程序的传统写法
  5. 区块链100问 第一问
  6. String案例 获取一个字符串在另一个字符串中出现的次数(两种方法)
  7. LeetCode 756. 金字塔转换矩阵(回溯)
  8. nodejs核心模块fs删除文件_用 NodeJS 重命名系统文件
  9. 微软将允许Epic Games等App登上微软商店
  10. 万人云峰会DevSecOps论坛:数字化浪潮下,安全开发与运维该如何破局?
  11. ros 发布信息频率_ROS入门笔记二基础
  12. php到岗第一天都做什么,十天学会php之第一天
  13. python3带tkinter窗口的ftp服务器,并使用pyinstaller打包成exe
  14. 日新测试软件,禁Ping多线程批量检测工具V2.6,功能强大,你值得拥有【2020.05.09日更新】...
  15. 小甲鱼 C语言 15课
  16. Spark环境搭建(保姆级教程)
  17. 常见动词的过去式和过去分词
  18. 我的新书《Flutter 开发之旅从南到北》终于和大家见面了(抽奖送书啦)。
  19. 计步器java计算月平均,我们行走时,计步器都会纪录,那计步器是怎么计算我们的步数的?...
  20. 一文看懂25个神经网络模型,神经网络模型结构图

热门文章

  1. 小波的秘密8_图像处理应用:图像降噪
  2. 万字长文带你一文读完Effective C++
  3. go语言buffio与继承
  4. 简介I/O向量、sendv、writev
  5. 「 每日一练,快乐水题 」191. 位1的个数
  6. 2021总结,2022展望
  7. SpringBoot应用日志通过logstash远程上传到ES
  8. 汽车雷达 -- 车载ADAS常用中英文对照
  9. 【译】Everything You Need to Know About Decentralized AI
  10. 从0到1,了解NLP中的文本相似度 1