日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

旷视MegEngine数据加载与处理

發布時間:2023/11/28 生活经验 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 旷视MegEngine数据加载与处理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

曠視MegEngine數據加載與處理
在網絡訓練與測試中,數據的加載和預處理往往會耗費大量的精力。 MegEngine 提供了一系列接口來規范化這些處理工作。
利用 Dataset 封裝一個數據集
數據集是一組數據的集合,例如 MNIST、Cifar10等圖像數據集。 Dataset 是 MegEngine 中表示數據集的抽象類。自定義的數據集類應該繼承 Dataset 并重寫下列方法:
? init() :一般在其中實現讀取數據源文件的功能。也可以添加任何其它的必要功能;
? getitem() :通過索引操作來獲取數據集中某一個樣本,使得可以通過 for 循環來遍歷整個數據集;
? len() :返回數據集大小;
下面是一個簡單示例。 根據下圖所示的二分類數據,創建一個 Dataset 。每個數據是一個二維平面上的點,橫坐標和縱坐標在 [-1, 1] 之間。共有兩個類別標簽(圖1中的藍色 * 和紅色 +),標簽為0的點處于一、三象限;標簽為1的點處于二、四象限。

圖1
該數據集的創建過程如下:
? 在 init() 中利用 NumPy 隨機生成 ndarray 作為數據;
? 在 getitem() 中返回 ndarray 中的一個樣本;
? 在 len() 中返回整個數據集中樣本的個數;
import numpy as np
from typing import Tuple

導入需要被繼承的 Dataset 類

from megengine.data.dataset import Dataset

class XORDataset(Dataset):
def init(self, num_points):
“”"
生成如圖1所示的二分類數據集,數據集長度為 num_points
“”"
super().init()

    # 初始化一個維度為 (50000, 2) 的 NumPy 數組。# 數組的每一行是一個橫坐標和縱坐標都落在 [-1, 1] 區間的一個數據點 (x, y)self.data = np.random.rand(num_points, 2).astype(np.float32) * 2 - 1# 為上述 NumPy 數組構建標簽。每一行的 (x, y) 如果符合 x*y < 0,則對應標簽為1,反之,標簽為0self.label = np.zeros(num_points, dtype=np.int32)for i in range(num_points):self.label[i] = 1 if np.prod(self.data[i]) < 0 else 0# 定義獲取數據集中每個樣本的方法
def __getitem__(self, index: int) -> Tuple:return self.data[index], self.label[index]# 定義返回數據集長度的方法
def __len__(self) -> int:return len(self.data)

np.random.seed(2020)

構建一個包含 30000 個點的訓練數據集

xor_train_dataset = XORDataset(30000)
print(“The length of train dataset is: {}”.format(len(xor_train_dataset)))

通過 for 遍歷數據集中的每一個樣本

for cor, tag in xor_train_dataset:
print(“The first data point is: {}, {}”.format(cor, tag))
break

print(“The second data point is: {}”.format(xor_train_dataset[1]))
輸出:
The length of train dataset is: 30000
The first data point is: [0.97255366 0.74678389], 0
The second data point is: (array([ 0.01949105, -0.45632857]), 1)
MegEngine 中也提供了一些已經繼承自 Dataset 的數據集類,方便使用,比如 ArrayDataset 。 ArrayDataset 允許通過傳入單個或多個 NumPy 數組,對它進行初始化。其內部實現如下:
? init() :檢查傳入的多個 NumPy 數組的長度是否一致;不一致則無法成功創建;
? getitem() :將多個 NumPy 數組相同索引位置的元素構成一個 tuple 并返回;
? len() :返回數據集的大小;
以圖1所示的數據集為例,可以通過坐標數據和標簽數據的數組直接構造 ArrayDataset ,無需用戶自己定義數據集類。
from megengine.data.dataset import ArrayDataset

準備 NumPy 形式的 data 和 label 數據

np.random.seed(2020)
num_points = 30000
data = np.random.rand(num_points, 2).astype(np.float32) * 2 - 1
label = np.zeros(num_points, dtype=np.int32)
for i in range(num_points):
label[i] = 1 if np.prod(data[i]) < 0 else 0

利用 ArrayDataset 創建一個數據集類

xor_dataset = ArrayDataset(data, label)
通過 Sampler 從 Dataset 中采樣
Dataset 僅能通過一個固定的順序(其 getitem 實現)訪問所有樣本, 而 Sampler 使得可以以所期望的方式從 Dataset 中采樣,生成訓練和測試的批(minibatch)數據。 Sampler 本質上是一個數據集中數據索引的迭代器,接收 Dataset 的實例和批大小(batch_size)來進行初始化。
MegEngine 中提供各種常見的采樣器,如 RandomSampler (通常用于訓練)、 SequentialSampler (通常用于測試) 等。
下面示例,來熟悉 Sampler 的基本用法:

導入 MegEngine 中采樣器

from megengine.data import RandomSampler

創建一個隨機采樣器

random_sampler = RandomSampler(dataset=xor_dataset, batch_size=4)

獲取迭代sampler時每次返回的數據集索引

for indices in random_sampler:
print(indices)
break
輸出:
[19827, 2614, 8788, 8641]
可以看到,在 batch_size 為4時,每次迭代 sampler 返回的是長度為4的列表,列表中的每個元素是隨機采樣出的數據索引。
如果創建的是一個序列化采樣器 SequentialSampler ,那么每次返回的就是順序索引。
from megengine.data import SequentialSampler

sequential_sampler = SequentialSampler(dataset=xor_dataset, batch_size=4)

獲取迭代sampler時返回的數據集索引信息

for indices in sequential_sampler:
print(indices)
break
輸出:
[0, 1, 2, 3]
用戶也可以繼承 Sampler 自定義采樣器,這里不做詳述。
用 DataLoader 生成批數據
MegEngine 中,DataLoader 本質上是一個迭代器,它通過 Dataset 和 Sampler 生成 minibatch 數據。
下列代碼通過 for 循環獲取每個 minibatch 的數據。
from megengine.data import DataLoader

創建一個 DataLoader,并指定數據集和順序采樣器

xor_dataloader = DataLoader(
dataset=xor_dataset,
sampler=sequential_sampler,
)
print(“The length of the xor_dataloader is: {}”.format(len(xor_dataloader)))

從 DataLoader 中迭代地獲取每批數據

for idx, (cor, tag) in enumerate(xor_dataloader):
print("iter %d : " % (idx), cor, tag)
break
輸出:
The length of the xor_dataloader is: 7500
iter 0 : [[ 0.97255366 0.74678389]
[ 0.01949105 -0.45632857]
[-0.32616254 -0.56609147]
[-0.44704571 -0.31336881]] [0 1 0 0]
DataLoader 中的數據變換(Transform)
在深度學習模型的訓練中,經常需要對數據進行各種轉換,比如,歸一化、各種形式的數據增廣等。 Transform 是數據變換的基類,其各種派生類提供了常見的數據轉換功能。 DataLoader 構造函數可以接收一個 Transform 參數, 在構建 minibatch 時,對該批數據進行相應的轉換操作。
接下來通過 MNIST 數據集(MegEngine 提供了 MNIST Dataset)來熟悉 Transform 的使用。 首先構建一個不做 Transform 的 MNIST DataLoader,并可視化第一個 minibatch 數據。

從 MegEngine 中導入 MNIST 數據集

from megengine.data.dataset import MNIST

若是第一次下載 MNIST 數據集,download 需設置成 True

若已經下載 MNIST 數據集,通過 root 指定 MNIST數據集 raw 路徑

通過設置 train=True/False 獲取訓練集或測試集

mnist_train_dataset = MNIST(root="./dataset/MNIST", train=True, download=True)

mnist_test_dataset = MNIST(root="./dataset/MNIST", train=False, download=True)

sequential_sampler = SequentialSampler(dataset=mnist_train_dataset, batch_size=4)

mnist_train_dataloader = DataLoader(
dataset=mnist_train_dataset,
sampler=sequential_sampler,
)

for i, batch_sample in enumerate(mnist_train_dataloader):
batch_image, batch_label = batch_sample[0], batch_sample[1]
# 下面可以將 batch_image, batch_label 傳遞給網絡做訓練,這里省略
# trainging code …
# 中斷
break

print(“The shape of minibatch is: {}”.format(batch_image.shape))

導入可視化 Python 庫,若沒有,安裝

import matplotlib.pyplot as plt

def show(batch_image, batch_label):
for i in range(4):
plt.subplot(1, 4, i+1)
plt.imshow(batch_image[i][:,:,-1], cmap=‘gray’)
plt.xticks([])
plt.yticks([])
plt.title(“label: {}”.format(batch_label[i]))
plt.show()

可視化數據

show(batch_image, batch_label)
輸出:
The shape of minibatch is: (4, 28, 28, 1)
可視化第一批 MNIST 數據:

圖2
然后,構建一個做 RandomResizedCrop transform 的 MNIST DataLoader,并查看此時第一個 minibatch 的圖片。

導入 MegEngine 已支持的一些數據增強操作

from megengine.data.transform import RandomResizedCrop

dataloader = DataLoader(
mnist_train_dataset,
sampler=sequential_sampler,
# 指定隨機裁剪后的圖片的輸出size
transform=RandomResizedCrop(output_size=28),
)

for i, batch_sample in enumerate(dataloader):
batch_image, batch_label = batch_sample[0], batch_sample[1]
break

show(batch_image, batch_label)
可視化第一個批數據:

圖3
可以看到,此時圖片經過了隨機裁剪并 resize 回原尺寸。
組合變換(Compose Transform)
經常需要做一系列數據變換。比如:
? 數據歸一化:可以通過 Transform 中提供的 Normalize 類來實現;
? Pad:對圖片的每條邊補零以增大圖片尺寸,通過 Pad 類來實現;
? 維度轉換:將 (Batch-size, Hight, Width, Channel) 維度的 minibatch 轉換為 (Batch-size, Channel, Hight, Width)(因為這是 MegEngine 支持的數據格式),通過 ToMode 類來實現;
? 其它的轉換操作
為了方便使用,MegEngine 中的 Compose 類允許組合多個 Transform 并傳遞給 DataLoader 的 transform 參數。
接下來通過 Compose 類將之前的 RandomResizedCrop 操作與 Normalize 、 Pad 和 ToMode 操作組合起來, 實現多種數據轉換操作的混合使用。運行如下代碼查看轉換 minibatch 的維度信息。
from megengine.data.transform import RandomResizedCrop, Normalize, ToMode, Pad, Compose

利用 Compose 組合多個 Transform 操作

dataloader = DataLoader(
mnist_train_dataset,
sampler=sequential_sampler,
transform=Compose([
RandomResizedCrop(output_size=28),
# mean 和 std 分別是 MNIST 數據的均值和標準差,圖片數值范圍是 0~255
Normalize(mean=0.1307255, std=0.3081255),
Pad(2),
# 'CHW’表示把圖片由 (height, width, channel) 格式轉換成 (channel, height, width) 格式
ToMode(‘CHW’),
])
)

for i, batch_sample in enumerate(dataloader):
batch_image, batch_label = batch_sample[0], batch_sample[1]
break

print(“The shape of the batch is now: {}”.format(batch_image.shape))
輸出:
The shape of the batch is now: (4, 1, 32, 32)
可以看到,此時 minibatch 數據的 channel 維換了位置,且圖片尺寸變為32。
DataLoader 中其他參數的用法請參考 DataLoader 文檔。

總結

以上是生活随笔為你收集整理的旷视MegEngine数据加载与处理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。