網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
我們?cè)?《torch.utils.data.DataLoader與迭代器轉(zhuǎn)換操作》 中介紹了如何使用Pytorch內(nèi)置的數(shù)據(jù)集進(jìn)行論文實(shí)驗(yàn),如 torchvision.datasets 。下面是加載內(nèi)置訓(xùn)練數(shù)據(jù)集的常見(jiàn)操作:
from torchvision.datasets import FashionMNIST from torchvision.transforms import Compose, ToTensor, Normalize RAW_DATA_PATH = './rawdata' transform = Compose( ? ? ? ? [ToTensor(), ? ? ? ? ?Normalize((0.1307,), (0.3081,)) ? ? ? ? ?] ? ? ) train_data = FashionMNIST( ? ? ? ? root=RAW_DATA_PATH, ? ? ? ? download=True, ? ? ? ? train=True, ? ? ? ? transform=transform ? ? )
這里的train_data
做為 dataset
對(duì)象,它擁有許多熟悉,我們可以通過(guò)以下方法獲取樣本數(shù)據(jù)的分類類別集合、樣本的特征維度、樣本的標(biāo)簽集合等信息。
classes = train_data.classes num_features = train_data.data[0].shape[0] train_labels = train_data.targets print(classes) print(num_features) print(train_labels)
輸出如下:
['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']
28
tensor([9, 0, 0, ?..., 3, 0, 5])
但是,我們常常會(huì)在訓(xùn)練集的基礎(chǔ)上拆分出驗(yàn)證集(或者只用部分?jǐn)?shù)據(jù)來(lái)進(jìn)行訓(xùn)練)。我們想到的第一個(gè)方法是使用 torch.utils.data.random_split
對(duì) dataset
進(jìn)行劃分,下面我們假設(shè)劃分10000個(gè)樣本做為訓(xùn)練集,其余樣本做為驗(yàn)證集:
from torch.utils.data import random_split k = 10000 train_data, valid_data = random_split(train_data, [k, len(train_data)-k])
注意我們?nèi)绻蛴?train_data 和 valid_data
的類型,可以看到顯示:
已經(jīng)不再是torchvision.datasets.mnist.FashionMNIST
對(duì)象,而是一個(gè)所謂的 Subset 對(duì)象!此時(shí) Subset 對(duì)象雖然仍然還存有 data 屬性,但是內(nèi)置的 target
和 classes
屬性已經(jīng)不復(fù)存在,
比如如果我們強(qiáng)行訪問(wèn) valid_data 的 target 屬性:
valid_target = valid_data.target
就會(huì)報(bào)如下錯(cuò)誤:
'Subset' object has no attribute 'target'
但如果我們?cè)诤罄m(xù)的代碼中常常會(huì)將拆分后的數(shù)據(jù)集也默認(rèn)為 dataset 對(duì)象,那么該如何做到代碼的一致性呢?
這里有一個(gè)trick,那就是以繼承 SubSet 類的方式的方式定義一個(gè)新的 CustomSubSet 類,使新類在保持 SubSet 類的基本屬性的基礎(chǔ)上,擁有和原本數(shù)據(jù)集類相似的屬性,如 targets
和 classes
等:
from torch.utils.data import Subset class CustomSubset(Subset): ? ? '''A custom subset class''' ? ? def __init__(self, dataset, indices): ? ? ? ? super().__init__(dataset, indices) ? ? ? ? self.targets = dataset.targets # 保留targets屬性 ? ? ? ? self.classes = dataset.classes # 保留classes屬性 ? ? def __getitem__(self, idx): #同時(shí)支持索引訪問(wèn)操作 ? ? ? ? x, y = self.dataset[self.indices[idx]] ? ? ? ? ? ? ? return x, y? ? ? def __len__(self): # 同時(shí)支持取長(zhǎng)度操作 ? ? ? ? return len(self.indices)
然后就引出了第二種劃分方法,即通過(guò)初始化 CustomSubset
對(duì)象的方式直接對(duì)數(shù)據(jù)集進(jìn)行劃分(這里為了簡(jiǎn)化省略了shuffle的步驟):
import numpy as np from copy import deepcopy origin_data = deepcopy(train_data) train_data = CustomSubset(origin_data, np.arange(k)) valid_data = CustomSubset(origin_data, np.arange(k, len(origin_data))-k)
注意: CustomSubset
類的初始化方法的第二個(gè)參數(shù) indices 為樣本索引,我們可以通過(guò) np.arange()
的方法來(lái)創(chuàng)建。
然后,我們?cè)僭L問(wèn) valid_data 對(duì)應(yīng)的 classes 和 targes 屬性:
print(valid_data.classes) print(valid_data.targets)
此時(shí),我們發(fā)現(xiàn)可以成功訪問(wèn)這些屬性了:
['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot'] tensor([9, 0, 0, ?..., 3, 0, 5])
當(dāng)然, CustomSubset
的作用并不只是添加數(shù)據(jù)集的屬性,我們還可以自定義一些數(shù)據(jù)預(yù)處理操作。
我們將類的結(jié)構(gòu)修改如下:
class CustomSubset(Subset): ? ? '''A custom subset class with customizable data transformation''' ? ? def __init__(self, dataset, indices, subset_transform=None): ? ? ? ? super().__init__(dataset, indices) ? ? ? ? self.targets = dataset.targets ? ? ? ? self.classes = dataset.classes ? ? ? ? self.subset_transform = subset_transform ? ? def __getitem__(self, idx): ? ? ? ? x, y = self.dataset[self.indices[idx]] ? ? ? ?? ? ? ? ? if self.subset_transform: ? ? ? ? ? ? x = self.subset_transform(x) ? ? ?? ? ? ? ? return x, y ?? ? ?? ? ? def __len__(self):? ? ? ? ? return len(self.indices)
我們可以在使用樣本前設(shè)置好數(shù)據(jù)預(yù)處理算子:
from torchvision import transforms valid_data.subset_transform = transforms.Compose(\ ? ? [transforms.RandomRotation((180,180))])
這樣,我們?cè)傧裣铝羞@樣用索引訪問(wèn)取出數(shù)據(jù)集樣本時(shí),就會(huì)自動(dòng)調(diào)用算子完成預(yù)處理操作:
print(valid_data[0])
打印結(jié)果縮略如下:
(tensor([[[-0.4242, -0.4242, -0.4242, ......-0.4242, -0.4242, -0.4242, -0.4242, -0.4242]]]), 9)
原文鏈接:https://www.cnblogs.com/orion-orion/p/15906086.html
相關(guān)推薦
- 2022-06-06 前端怎么把px單位換成rem單位解決項(xiàng)目頁(yè)面適配問(wèn)題
- 2022-11-01 詳解golang中的閉包與defer_Golang
- 2022-10-07 C++結(jié)構(gòu)體中變長(zhǎng)數(shù)組的使用問(wèn)題分解刨析_C 語(yǔ)言
- 2022-07-16 mybatis的相同攔截器—切面執(zhí)行的順序
- 2022-07-13 Android?Studio實(shí)現(xiàn)簡(jiǎn)單繪圖板_Android
- 2022-03-17 詳解Golang函數(shù)式選項(xiàng)(Functional?Options)模式_Golang
- 2022-09-22 String和StringBuilder的用法
- 2022-03-16 ASP.NET?Core開(kāi)發(fā)Docker部署_基礎(chǔ)應(yīng)用
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支