OssMapDataset類型的Dataset適用於記憶體充足、資料量不大需要頻繁進行隨機訪問和平行處理的情境,本文為您介紹如何通過OssMapDataset構建Dataset。
前提條件
已安裝並配置OSS Connector for AI/ML。具體操作,請參見安裝OSS Connector for AI/ML和配置OSS Connector for AI/ML。
構建Dataset
構建方式
在使用OssMapDataset構建Dataset時,有三種構建方式:
OSS_URI首碼:適用於OSS儲存路徑具有統一規律的情境。
OSS_URI的列表:適用於OSS儲存路徑位置明確但分散的情境。
資訊清單檔:可以減少OSS list object開銷,適用於資料集檔案數量大(如千萬級)且有重複載入資料集需求,以及已開通資料索引OSS功能的Bucket。
通過OSS_URI首碼構建Dataset
以下樣本用於使用OssMapDataset的from_prefix方法從OSS中指定的首碼(OSS_URI)構建Dataset。
from osstorchconnector import OssMapDataset
ENDPOINT = "http://oss-cn-beijing-internal.aliyuncs.com"
CONFIG_PATH = "/etc/oss-connector/config.json"
CRED_PATH = "/root/.alibabacloud/credentials"
OSS_URI = "oss://ai-testset/EnglistImg/Img/BadImag/Bmp/Sample001/"
# 使用OssMapDataset的from_frefix方法構建Dataset
map_dataset = OssMapDataset.from_prefix(oss_uri=OSS_URI, endpoint=ENDPOINT, cred_path=CRED_PATH, config_path=CONFIG_PATH)
# 隨機訪問已建立Dataset中的對象
item = map_dataset[0]
print(item.key)
content = item.read()
print(item.size)
print(len(content))
# 遍曆Dataset中對象
for item in map_dataset:
print(item.key)
print(item.size)
content = item.read()
print(len(content))
通過OSS_URI列表構建Dataset
以下樣本用於使用OssMapDataset的from_objects方法從指定的OSS_URI列表構建Dataset。
from osstorchconnector import OssMapDataset
ENDPOINT = "http://oss-cn-beijing-internal.aliyuncs.com"
CONFIG_PATH = "/etc/oss-connector/config.json"
CRED_PATH = "/root/.alibabacloud/credentials"
# uris是一個包含多個OSS_URI的字串迭代器。
uris = [
"oss://ai-testset/EnglistImg/Img/BadImag/Bmp/Sample001/img001-00001.png",
"oss://ai-testset/EnglistImg/Img/BadImag/Bmp/Sample001/img001-00002.png",
"oss://ai-testset/EnglistImg/Img/BadImag/Bmp/Sample001/img001-00003.png"
]
# 使用OssMapDataset的from_objects方法構建Dataset
map_dataset = OssMapDataset.from_objects(object_uris=uris, endpoint=ENDPOINT, cred_path=CRED_PATH, config_path=CONFIG_PATH)
# 隨機訪問已建立Dataset中的對象
item = map_dataset[1]
print(item.key)
print(item.size)
content = item.read()
print(len(content))
# 遍曆Dataset中對象
for item in map_dataset:
print(item.key)
print(item.size)
content = item.read()
print(len(content))
通過資訊清單檔構建Dataset
使用資訊清單檔構建Dataset前,您需要建立資訊清單檔,然後通過manifest file構建Dataset。
建立資訊清單檔:
在任意位置執行
touch manifest_file
命令建立manifest file,然後根據樣本填寫manifest file。帶有oss對象名稱的manifest file樣本:
Img/BadImag/Bmp/Sample001/img001-00001.png Img/BadImag/Bmp/Sample001/img001-00002.png Img/BadImag/Bmp/Sample001/img001-00003.png
帶有oss對象名稱和label的manifest file樣本:
Img/BadImag/Bmp/Sample001/img001-00001.png label1 Img/BadImag/Bmp/Sample001/img001-00002.png label2 Img/BadImag/Bmp/Sample001/img001-00003.png label3
通過資訊清單檔構建Dataset。
以下樣本用於使用OssMapDataset的from_manifest_file方法從指定的manifest file檔案構建Dataset。
import io from typing import Iterable,Tuple,Union from osstorchconnector import OssMapDataset from osstorchconnector import imagenet_manifest_parser ENDPOINT = "http://oss-cn-beijing-internal.aliyuncs.com" CONFIG_PATH = "/etc/oss-connector/config.json" CRED_PATH = "/root/.alibabacloud/credentials" OSS_BASE_URI = "oss://ai-testset/EnglistImg/" MANIFEST_FILE_URI = "oss://manifest_fileai-testset/EnglistImg/manifest_file" # 使用 OssMapDataset 的 from_manifest_file 方法通過本地的檔案構建 Dataset # manifest_file_path 參數指定了資訊清單檔本地路徑 # manifest_parser 參數為解析資訊清單檔的方法,樣本中使用了內建的解析方法 imagenet_manifest_parser # oss_base_uri 參數指定了BASE_OSS_URI,用於與從 manifest中解析的URI拼接成 FULL_OSS_URI,FULL_OSS_URI = BASE_OSS_URI + URI MANIFEST_FILE_LOCAL = "/path/to/manifest_file.txt" iterable_dataset = OssMapDataset.from_manifest_file(manifest_file_path=MANIFEST_FILE_LOCAL, manifest_parser=imagenet_manifest_parser, oss_base_uri=OSS_BASE_URI, endpoint=ENDPOINT, cred_path=CRED_PATH, config_path=CONFIG_PATH) for item in iterable_dataset: print(item.key) print(item.size) print(item.label) content = item.read() print(len(content)) # 使用OssMapDataset的from_manifest_file方法通過OSS Bucket內的manifest_file檔案構建Dataset iterable_dataset = OssMapDataset.from_manifest_file(manifest_file_path=MANIFEST_FILE_URI, manifest_parser=imagenet_manifest_parser, oss_base_uri=OSS_BASE_URI, endpoint=ENDPOINT, cred_path=CRED_PATH, config_path=CONFIG_PATH)
OSS Connector for AI/ML中的資料類型
Dataset中對象的資料類型實現了常用的IO介面。更多資訊,請參見OSS Connector for AI/ML中的資料類型。
構建參數說明
使用OssMapDataset或OssIterableDataset構建Dataset時需要進行相應配置,具體配置項說明請參見下表。
參數名 | 參數類型 | 是否必選 | 說明 |
endpoint | string | 是 | 公用參數: OSS對外服務的訪問網域名稱。更多資訊,請參見訪問網域名稱和資料中心。 |
transform | object | 否 | 公用參數: 轉換函式,用於將DataObject(oss object)轉換成任意類型。可以根據需求自訂其方法,具體請參見transform。 重要 請勿在transform中直接返回 |
cred_path | string | 是 | 公用參數: 鑒權檔案預設路徑為 |
config_path | string | 是 | 公用參數: OSS Connector設定檔預設路徑為 |
oss_uri | string | 是 | from_prefix方法參數: OSS資源路徑,用於通過OSS_URI首碼構建Dataset。僅支援以 |
object_uris | string | 是 | from_objects方法參數: OSS資源路徑列表,通過列表中的路徑構建Dataset。僅支援以 |
manifest_file_path | string | 是 | from_manifest_file方法參數: 資訊清單檔的路徑,支援本地檔案路徑或以 |
manifest_parser | Callable Object | 是 | from_manifest_file方法參數: 解析資訊清單檔的內建方法,接收已開啟的資訊清單檔作為輸入,返回一個迭代器,每個元素為 |
oss_base_uri | string | 是 | from_manifest_file方法參數: OSS基礎URI,用於拼接資訊清單檔中可能不完整的OSS_URI,形成完整的OS_URI。如果沒有oss_base_uri,需要填寫為 |
內建方法
transform
構建Dataset時,Dataset會返回transform(DataObject) 的迭代器。其中DataObject是OSS Connector for AI/ML中的資料類型。
transform支援自訂其方法,在構建dataset時如果不指定transform,則會使用預設的transform方法。
預設transform方法
以下樣本為預設transfrom方法,在構建Dataset時無需指定。
#預設transform函數
def identity(obj: DataObject) -> DataObject:
if obj is not None:
return obj.copy()
else:
return None
自訂transform方法
以下樣本用於構建Dataset時使用自訂transform方法。
import sys
import io
import torchvision.transforms as transforms
from PIL import Image
from osstorchconnector import OssMapDataset
ENDPOINT = "http://oss-cn-beijing-internal.aliyuncs.com"
CONFIG_PATH = "/etc/oss-connector/config.test.json"
CRED_PATH = "/root/.alibabacloud/credentials"
OSS_URI = "oss://ai-testset/EnglistImg/Img/BadImag/Bmp/Sample001/"
# 定義映像資料的轉換操作
trans = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
# 建立transform方法對輸入的對象進行處理
def transform(object):
try:
img = Image.open(io.BytesIO(object.read())).convert('RGB')
val = trans(img)
except Exception as e:
raise e
return val, object.label
# 在構建dataset時使用transform=transform參數
iterable_dataset = OssMapDataset.from_prefix(OSS_URI, endpoint=ENDPOINT, transform=transform, cred_path=CRED_PATH, config_path=CONFIG_PATH)
manifest_parser
預設manifest_parser方法,在構建Dataset時需匯入樣本如下。
from osstorchconnector import imagenet_manifest_parser
以下樣本為預設manifest_parser方法。
def imagenet_manifest_parser(reader: io.IOBase) -> Iterable[Tuple[str, str]]:
lines = reader.read().decode("utf-8").strip().split("\n")
for i, line in enumerate(lines):
try:
items = line.strip().split('\t')
if len(items) >= 2:
key = items[0]
label = items[1]
yield (key, label)
elif len(items) == 1:
key = items[0]
yield (key, '')
else:
raise ValueError("format error")
except ValueError as e:
logging.error(f"Error: {e} for line {i}: {line}")
使用PyTorch通過Dataset建立資料載入器
以下樣本展示了如何根據OssMapDataset構建的Dataset作為資料來源來建立PyTorch資料載入器。
import torch
from osstorchconnector import OssMapDataset
ENDPOINT = "http://oss-cn-beijing-internal.aliyuncs.com"
CONFIG_PATH = "/etc/oss-connector/config.test.json"
CRED_PATH = "/root/.alibabacloud/credentials"
OSS_URI = "oss://ai-testset/EnglistImg/Img/BadImag/Bmp/Sample001/"
def transform(object):
data = object.read()
return object.key, object.label
# 使用OssMapDataset的from_frefix方法構建Dataset
map_dataset = OssMapDataset.from_prefix(OSS_URI, endpoint=ENDPOINT, transform=transform,cred_path=CRED_PATH, config_path=CONFIG_PATH)
# 基於map_dataset建立PyTorch資料載入器
loader = torch.utils.data.DataLoader(map_dataset, batch_size=256, num_workers=32, prefetch_factor=2, shuffle=True)
# 在訓練迴圈中使用資料
# for batch in loader:
# 進行訓練操作
...
相關文檔
如果您是在容器化環境中進行資料訓練任務,那麼OSS Connector for AI/ML同樣適用於容器化環境。具體操作,請參見構建含有OSS Connector for AI/ML環境的Docker鏡像。