728x90
반응형

Conversion transforms은
- 데이터 타입과 형식을 변환하며,
- 일부는 값 범위 스케일링(예: uint8 [0,255] ↔ float32 [0,1])을 포함함.
https://docs.pytorch.org/vision/main/transforms.html#conversion
Transforming and augmenting images — Torchvision main documentation
Shortcuts
docs.pytorch.org
관련 gist
https://gist.github.com/dsaint31x/d67286ee5ad15db9b2981119e43f1695
dl_conversion-torchvision-transforms-v2.ipynb
dl_conversion-torchvision-transforms-v2.ipynb. GitHub Gist: instantly share code, notes, and snippets.
gist.github.com
0. Prerequisites
사용할 이미지 다운로드등을 수행하는 다음의 코드를 수행하고 나서 예제를 실행할 것.
img_path = "assets/astronaut.jpg"
img_url = "https://raw.githubusercontent.com/pytorch/vision/main/gallery/assets/astronaut.jpg"
!mkdir -p assets/
!curl -o {img_path} {img_url}
from torchvision.io import decode_image
original_img = decode_image(img_path)
print(f" {type(original_img) = }\n \
{original_img.dtype = }\n \
{original_img.shape = }")
1. ToImage() - 주로 사용됨 **
1-1. 역할:
- Tensor, ndarray, PIL Image를
- torchvision의
ImageTVTensor로 변환 - 원본의 Meta Data가 조건부로 보존됨
ImageTVTensor 의 경우 100% 보존.- 단, PIL 의 Image객체가 입력([W,H,C])인 경우는 [C,H,W]로 변환됨:
- 엄밀히는 PIL의 Image 객체는 [W,H] + C 구조라고 볼 수 있음.
- PIL의 Image객체의 mode, info, exif 는 보존되지 않음
- 단, NumPy 의 ndarray객체가 입력([H,W,C])인 경우는 [C,H,W]로 변환됨.
ToImage는 ToDtype 과 함께,
가장 많이 애용됨
(과거의 ToTensor를 대체)
1-2. 파라미터:
ToImage() # 파라미터 없음
1-3. 주요 특징:
- Value Scaling 안함:
- 픽셀 값을 그대로 유지
- Meta Data 조건부 보존:
- 이미지 크기,
- dtype 등의 Meta Data 정보 조건부 보존
- v2 호환성:
v2transforms와 완전 호환
1-4. 성능 이슈:
- 입력이 PyTorch의 텐서(특히 TVTensor의 Image)인 경우,
- 매우 빠름:
- 이 경우엔 단순 wrapping에 해당
- 거의 오버헤드 없음
- 메모리 효율:
- 새로운 메모리 할당 없이 View 만 생성
- 메타데이터 오버헤드:
- TVTensor Wraping 으로 약간의 추가 메모리
- 매우 빠름:
- 입력이 PIL Image 이거나 NumPy의 array인 경우,
PILToTensor()와 유사한 부하가 발생.- 이들 입력의 경우 새로운
ImageTVTensor 생성이 이루어지기 때문임.
1-5. 사용 예시:
from torchvision.transforms.v2 import ToImage
import torch
import numpy as np
from PIL import Image
import time
transform = ToImage()
# 1. PyTorch 텐서 변환 (래핑만 - 빠름)
tensor = torch.randint(0, 255, (3, 224, 224), dtype=torch.uint8)
img_tensor = transform(tensor)
print(type(img_tensor)) # <class 'torchvision.datapoints._image.Image'>
print(torch.equal(tensor, img_tensor)) # True (동일한 값)
# 2. NumPy 배열 변환 (실제 변환 발생 - 중간 속도)
numpy_array = np.random.randint(0, 255, (224, 224, 3), dtype=np.uint8)
start = time.time()
img_from_numpy = transform(numpy_array)
numpy_time = time.time() - start
print(f"NumPy 변환 시간: {numpy_time:.6f}초")
# 3. PIL Image 변환 (실제 변환 발생 - 중간 속도)
pil_img = Image.fromarray(numpy_array)
start = time.time()
img_from_pil = transform(pil_img)
pil_time = time.time() - start
print(f"PIL 변환 시간: {pil_time:.6f}초")
# 4. 성능 비교 - 기존 텐서 vs PIL Image
start = time.time()
for _ in range(100):
img_tensor = transform(tensor) # 래핑만
tensor_time = time.time() - start
start = time.time()
for _ in range(100):
img_from_pil = transform(pil_img) # 실제 변환
pil_batch_time = time.time() - start
print(f"텐서 래핑 100회: {tensor_time:.4f}초")
print(f"PIL 변환 100회: {pil_batch_time:.4f}초")
print(f"성능 차이: {pil_batch_time/tensor_time:.1f}배")
2. ToPureTensor() - 메타데이터 제거
2-1. 역할:
- 모든 TVTensor(
Image,BoundingBoxes,Mask등)를 - 순수
PyTorchTensor(텐서)로 변환 (사실 TVTensor만 Tensor로 변환) - Meta Data가 제거됨.
ToPUreTensor는
PIL Image나 NumPy의 array를 Tensor로 변환하지 못함.
CNN이나 Custom Module의 호환성 위해 사용.
2-2. 파라미터:
ToPureTensor() # 파라미터 없음
2-3. 주요 특징:
- 메타데이터 제거 (TVTensor의 메타데이터 제거됨):
- TVTensor의 추가 정보 모두 삭제
- Image TVTensor는 특별한 메타데이터가 없음에 유의할 것.
- 순수 텐서 반환:
- 표준
torch.Tensor로 변환 - 정확히는 다음을 따름:
- TVTensor → torch.Tensor (메타데이터 제거)
- PIL Image → PIL Image (변환 안하고 그냥 통과)
- NumPy array → NumPy array (변환 안하고 그냥 통과)
- 순수 텐서 → 순수 텐서 (이미 순수하므로)
- 표준
from torchvision.transforms.v2 import ToPureTensor, ToImage
from torchvision import tv_tensors
from PIL import Image
import torch
to_pure = ToPureTensor()
# TVTensor → 순수 텐서 변환
tv_tensor = tv_tensors.Image(torch.randn(3, 224, 224))
result2 = to_pure(tv_tensor)
print(f"TVTensor → ToPureTensor: {type(result2)}")
# 출력: <class 'torch.Tensor'> (변환됨!)
# PIL Image → 그대로 통과
pil_img = Image.open(img_path)
result1 = to_pure(pil_img)
print(f"PIL → ToPureTensor: {type(result1)}")
# 출력: <class 'PIL.JpegImagePlugin.JpegImageFile'> (변환 안됨!)
# 순수 텐서 → 그대로 통과
pure_tensor = torch.randn(3, 224, 224)
result3 = to_pure(pure_tensor)
print(f"Tensor → ToPureTensor: {type(result3)}")
# 출력: <class 'torch.Tensor'> (그대로 통과)
- 호환성 위해 존재: 일반 PyTorch 연산에 필요한 경우 사용
- 과거의 CNN 이나, Custom Module의 경우,
- TVTensor가 유지되지 않기 쉽고, 예상치 못한 동작이 있을 수 있기 때문임.
2-4. 성능 이슈:
- 매우 빠름: 메타데이터만 제거, 데이터는 그대로
- 메모리 절약: 메타데이터 오버헤드 제거
- 정보 손실: 원본 형태 정보 손실 (되돌릴 수 없음)
2-5. 사용 예시:
from torchvision.transforms.v2 import ToPureTensor, ToImage
from torchvision import tv_tensors
import torch
# Image TVTensor 생성
# Image TVTensor의 경우, 특별한 메타데이터 없음.
to_image = ToImage()
to_pure = ToPureTensor()
tensor = torch.randint(0, 255, (3, 224, 224), dtype=torch.uint8)
img_tensor = to_image(tensor) # Image TVTensor
print(f"Image 원본: {type(img_tensor)}") # Image TVTensor
print(f"Image shape: {img_tensor.shape}") # torch.Size([3, 224, 224])
# Image를 순수 텐서로 변환
pure_tensor = to_pure(img_tensor)
print(f"변환후: {type(pure_tensor)}") # torch.Tensor
print("="*10)
# BoundingBoxes의 메타데이터 예시
boxes = tv_tensors.BoundingBoxes(
[[50, 50, 150, 150]],
format="XYXY",
canvas_size=(224, 224)
)
print(f"Boxes 메타데이터 - 포맷: {boxes.format}") # XYXY
print(f"Boxes 메타데이터 - 캔버스: {boxes.canvas_size}") # (224, 224)
# BoundingBoxes를 순수 텐서로 변환
pure_tensor = to_pure(img_tensor)
print(f"변환후: {type(pure_tensor)}") # torch.Tensor
print(f"Boxes 메타데이터 - 포맷: {pure_tensor.format}") # error
3. PILToTensor() - PIL to 텐서 변환
3-1. 역할:
- PIL Image를 PyTorch 텐서로 변환
- 값 범위는 그대로 유지
torchvision 에서는 PILToTensro보다는
주로 ToImage를 보다 더 많이 사용함.
3-2. 파라미터:
PILToTensor() # 파라미터 없음
3-3. 주요 특징:
- 값 보존:
- PIL의 [0, 255] 범위를 그대로 유지
- 차원 변환:
(H, W, C)to(C, H, W)자동 변환
- 타입 변환:
- PIL to
uint8텐서
- PIL to
3-4. 성능 이슈:
- 빠름:
- C++ 구현으로 최적화
- 메모리 복사:
- 새로운 텐서 생성 (메모리 사용량 증가)
- CPU 전용:
- CUDA 텐서로 직접 변환 안됨
- PIL Image는 항상 cpu에서 처리됨.
3-5. 사용 예시:
from torchvision.transforms.v2 import PILToTensor
from PIL import Image
import torch
transform = PILToTensor()
# PIL Image 로드
pil_img = Image.open(img_path) # RGB PIL Image
print(f"PIL 크기: {pil_img.size}") # (width, height)
print(f"PIL 모드: {pil_img.mode}") # RGB
print(f"PIL 범위: {pil_img.getextrema()}")
print("-"*10)
# 텐서로 변환
tensor = transform(pil_img)
print(f"텐서 크기: {tensor.shape}") # torch.Size([3, height, width])
print(f"텐서 타입: {tensor.dtype}") # torch.uint8
print(f"텐서 값 범위: {tensor.min()}-{tensor.max()}") # 0-255
print(f"{tensor.device = }") # device(type='cpu')
print("-"*10)
# 그레이스케일 이미지
gray_pil = Image.open(img_path).convert('L')
gray_tensor = transform(gray_pil)
print(f"그레이 크기: {gray_tensor.shape}") # torch.Size([1, height, width])
print(f"{tensor.device = }") # device(type='cpu')
print("-"*10)
# 성능 비교
import time
# PIL to Tensor 변환 시간 측정
start = time.time()
for _ in range(100):
tensor = transform(pil_img)
pil_time = time.time() - start
print(f"PILToTensor 100회: {pil_time:.4f}초")
4. ToPILImage([mode]) - 텐서 to PIL 변환
4-1. 역할:
- PyTorch 텐서나 NumPy 배열을
- PIL Image로 변환
4-2. 파라미터:
ToPILImage(mode=None)
- mode (str, optional): PIL 이미지 모드 ('RGB', 'L', 'P' 등)
None: 자동 추론 (기본값)'RGB': 3채널 컬러 이미지'L': 그레이스케일'P': 팔레트 모드
4-3. 주요 특징:
- Automatic Value Scaling:
- from [0,1]
float - to [0,255]
uint8 - 자동 변환
- from [0,1]
- 차원 변환:
- from
(C, H, W) - to
(H, W, C) - 자동 변환
- from
- 타입 추론:
- 텐서 shape 에 따라
- PIL Image객체의 mode 자동 결정: Batch처리가 안됨 - 주의
4-4. 성능 이슈:
- 느림: PIL 변환은 상대적으로 비용이 높음
- 메모리 복사: 새로운 PIL 객체 생성
- CPU 강제:
- GPU 텐서는 CPU로 (자동) 이동 후 변환
- 하지만 가급적 명시적 처리를 권장.
4-5. 사용 예시:
from torchvision.transforms.v2 import ToPILImage
import torch
transform = ToPILImage()
# 1. Float 텐서 (0-1 범위)
float_tensor = torch.rand(3, 224, 224) # [0, 1] 범위
pil_img = transform(float_tensor)
print(f"RGB PIL 모드: {pil_img.mode}") # RGB
# 2. Int 텐서 (0-255 범위)
int_tensor = torch.randint(0, 255, (3, 224, 224), dtype=torch.uint8)
pil_img2 = transform(int_tensor)
print(f"RGB PIL 모드: {pil_img2.mode} / {pil_img2.getextrema()=}") # RGB
# 3. 그레이스케일
gray_tensor = torch.rand(1, 224, 224)
gray_pil = transform(gray_tensor)
print(f"그레이 PIL 모드: {gray_pil.mode} / {gray_pil.getextrema()=}") # L
# 4. 명시적 모드 지정
# 명시적 RGB 변환도 채널 안 맞으면 에러.
# rgb_from_gray = ToPILImage(mode='RGB')(gray_tensor) # error!
gray_to_rgb_tensor = gray_tensor.repeat(3, 1, 1) # 1채널 → 3채널 복제
rgb_from_gray = ToPILImage(mode='RGB')(gray_to_rgb_tensor)
print(f"그레이(3ch) PIL 모드: {rgb_from_gray.mode} / {rgb_from_gray.getextrema()=}") # RGB
gray_to_rgb_tensor = gray_tensor.repeat(4, 1, 1) # 1채널 → 4채널 복제
rgb_from_gray = ToPILImage()(gray_to_rgb_tensor)
print(f"그레이(4ch) PIL 모드: {rgb_from_gray.mode} / {rgb_from_gray.getextrema()=}") # RGBA
# 5. GPU 텐서 처리
if torch.cuda.is_available():
gpu_tensor = torch.rand(3, 224, 224).cuda()
# ToPILImage는 자동으로 CPU로 이동
pil_from_gpu = transform(gpu_tensor)
print(f"from gpu PIL 모드: {pil_from_gpu.mode} / {pil_from_gpu.getextrema()=}") # RGB
# 6. batch 텐서 (0-255 범위)
int_tensor = torch.randint(0, 255, (8, 3, 224, 224), dtype=torch.uint8)
# pil_img3 = transform(int_tensor) # error!
# print(f"RGB PIL 모드: {pil_img3.mode} / {pil_img3.getextrema()=}") # RGB
# 성능 주의사항
import time
# 큰 이미지에서 성능 측정
large_tensor = torch.rand(3, 2048, 2048)
start = time.time()
for _ in range(10):
pil = transform(large_tensor)
conversion_time = time.time() - start
print(f"큰 이미지 PIL 변환 10회: {conversion_time:.4f}초")
5. ToDtype(dtype[, scale]) - 타입 변환 ***
5-1. 역할:
- 입력의 데이터 타입(dtype)을 conversion하며,
- 이미지/비디오의 경우에만, 선택적으로 value range도 조정: scale 파라메터 이용.
5-2. 파라미터:
ToDtype(dtype, scale=False)
- dtype (torch.dtype): 목표 데이터 타입
- scale (bool): 값 범위 조정 여부
True: 타입에 맞는 범위로 자동 스케일링False: 값 그대로 유지 (기본값)
5-3. 주요 특징:
- 유연한 변환:
- 모든 PyTorch dtype 지원
- Smart Value Scaling (다른 URL에서 보다 자세히 다룰 것):
- Pure Tensor 스케일링 적용:
- 단독 전달 인 경우: to_dtype(pure_tensor) → 변환 및 스케일링 적용
- 첫 번째 요소 인 경우:
- tv_tensors.Image나 tv_tensors.Video가 없으면: to_dtype([pure_tensor, labels]) → 첫 번째만 변환 및 스케일링
- 그 외의 경우 패스스루 (변환안됨)
- 나머지 요소 인 경우: 하위 호환을 위해 패스스루 (변환안됨)
- TVTensor 처리
- 단일 dtype 지정시:
- tv_tensors.Image, tv_tensors.Video 만 스케일링 처리,
- 나머지 모든 TVTensor는 패스스루
- dict로 dtype 인자 지정시
- tv_tensors.Image, tv_tensors.Video → 항상 스케일링
- tv_tensors.BoundingBoxes, tv_tensors.Mask → dict로 명시적 지정해도 조건부 처리.
- Image/Video가 없으면 역시 그냥 패스스루
- Image/Video가 있을 경우 dtype만 변환
- 단일 dtype 지정시:
- Image와 Video에 대해 선택적 scaling 적용 때문에 smart value scaling이라고 칭함.
- 단일 dtype 지정: Image/Video (또는 첫 번째 Pure Tensor)만 특별 처리, 나머지 모두 패스
- 딕셔너리 지정: Image/Video는 항상 처리, 나머지는 Image/Video 존재 여부에 따라 조건부 처리
- 일반 Tensor 보호: Image/Video가 있으면 첫 번째 포함해서 모든 일반 Tensor 패스스루
- Pure Tensor 스케일링 적용:
5-4. 성능 이슈:
- 빠름:
- PyTorch 네이티브 연산 사용
- 메모리:
- 새로운 텐서 생성
- in-place 아님
- 정밀도 손실:
- float to int 변환 시 정보 손실의 위험이 있음.
5-5. 사용 예시:
from torchvision.transforms.v2 import ToDtype
import torch
import numpy as np
print("=== 스마트 스케일링 데모 ===")
# 1. 기본 uint8 → float32 스케일링
print("1. uint8 → float32 스마트 스케일링 (기본):")
uint8_img = torch.randint(0, 255, (3, 4, 4), dtype=torch.uint8)
print(f"원본 uint8: 범위 [{uint8_img.min()}, {uint8_img.max()}]")
print(f"샘플 값 : {uint8_img[0, 0, :3]}")
to_float = ToDtype(torch.float32)
float_img = to_float(uint8_img)
print(f"변환 float32: 범위 [{float_img.min():.3f}, {float_img.max():.3f}]")
print(f"샘플 값 : {float_img[0, 0, :3]}")
print("\n기본은 scale=False 임.")
print("\n" + "="*10)
# 2. 기본 uint8 → float32 스케일링
print("2. uint8 → float32 스마트 스케일링 (scale=True):")
uint8_img = torch.randint(0, 255, (3, 4, 4), dtype=torch.uint8)
print(f"원본 uint8: 범위 [{uint8_img.min()}, {uint8_img.max()}]")
print(f"샘플 값 : {uint8_img[0, 0, :3]}")
to_float = ToDtype(torch.float32, scale=True)
float_img = to_float(uint8_img)
print(f"변환 float32: 범위 [{float_img.min():.3f}, {float_img.max():.3f}]")
print(f"샘플 값 : {float_img[0, 0, :3]}")
print("\nPure Tensor라도 단독인 경우엔 scale 가능.")
print("\n" + "="*10)
# 3. 역변환: float32 → uint8
print("3. float32 → uint8 역방향 스케일링:")
to_uint8 = ToDtype(torch.uint8, scale=True)
restored_uint8 = to_uint8(float_img)
print(f"복원 uint8: 범위 [{restored_uint8.min()}, {restored_uint8.max()}]")
print(f"샘플 값: {restored_uint8[0, 0, :3]}")
# 정확성 검증
diff = torch.abs(uint8_img.float() - restored_uint8.float())
print(f"복원 오차: 최대 {diff.max():.1f} (반올림 오차)")
print("[0,1] → [0,255] 역변환 + 반올림")
# Results
# === 스마트 스케일링 데모 ===
# 1. uint8 → float32 스마트 스케일링 (기본):
# 원본 uint8: 범위 [5, 248]
# 샘플 값 : tensor([ 62, 130, 126], dtype=torch.uint8)
# 변환 float32: 범위 [5.000, 248.000]
# 샘플 값 : tensor([ 62., 130., 126.])
#
# 기본은 scale=False 임.
#
# ==========
# 2. uint8 → float32 스마트 스케일링 (scale=True):
# 원본 uint8: 범위 [10, 248]
# 샘플 값 : tensor([108, 237, 26], dtype=torch.uint8)
# 변환 float32: 범위 [0.039, 0.973]
# 샘플 값 : tensor([0.4235, 0.9294, 0.1020])
#
# Pure Tensor라도 단독인 경우엔 scale 가능.
#
# ==========
# 3. float32 → uint8 역방향 스케일링:
# 복원 uint8: 범위 [10, 248]
# 샘플 값: tensor([108, 237, 26], dtype=torch.uint8)
# 복원 오차: 최대 0.0 (반올림 오차)
# [0,1] → [0,255] 역변환 + 반올림
6. ConvertBoundingBoxFormat(format) - 바운딩박스 포맷 변환
6-1. 역할:
- 바운딩 박스 좌표를
- 다른 포맷으로 변환
XYXY,XYWH,CXCYWH- 기타
6-2. 파라미터:
ConvertBoundingBoxFormat(format)
- format (str): 목표 바운딩박스 포맷
'XYXY':(x1, y1, x2, y2)- 좌상단, 우하단 좌표
'XYWH':(x, y, width, height)- 좌상단 + 크기
'CXCYWH':(center_x, center_y, width, height)- 중심점 + 크기
6-3. 주요 특징:
- 포맷 자동감지: 입력 포맷 자동 인식
- 정확한 변환: 수학적으로 정확한 좌표 변환
- 배치 처리: 여러 박스 동시 변환 가능
6-4. 성능 이슈:
- 매우 빠름: 단순 수학 연산만 수행
- 메모리 효율: in-place 연산 가능
- GPU 지원: CUDA 텐서에서도 동작
6-5. 사용 예시:
from torchvision.transforms.v2 import ConvertBoundingBoxFormat
# from torchvision.datapoints import BoundingBoxes # not working
from torchvision.tv_tensors import BoundingBoxes # datapoints 대신 tv_tensors 사용
import torch
# 1. 바운딩박스 생성 (XYXY 포맷)
boxes_xyxy = torch.tensor([
[10, 20, 100, 150], # x1, y1, x2, y2
[50, 30, 200, 180],
], dtype=torch.float32)
bbox_xyxy = BoundingBoxes(
boxes_xyxy,
format='XYXY',
canvas_size=(300, 400) # 이미지 크기
)
print(f"원본 XYXY: {bbox_xyxy}")
print(f"포맷: {bbox_xyxy.format}")
# 2. XYXY to XYWH 변환
to_xywh = ConvertBoundingBoxFormat('XYWH')
bbox_xywh = to_xywh(bbox_xyxy)
print(f"XYWH 변환: {bbox_xywh}")
print(f"새 포맷: {bbox_xywh.format}")
# 3. XYXY to CXCYWH 변환
to_cxcywh = ConvertBoundingBoxFormat('CXCYWH')
bbox_cxcywh = to_cxcywh(bbox_xyxy)
print(f"CXCYWH 변환: {bbox_cxcywh}")
# 4. 포맷별 의미 해석
print("\n=== 포맷별 해석 ===")
print("XYXY:", bbox_xyxy[0]) # [x1, y1, x2, y2]
print("XYWH:", bbox_xywh[0]) # [x, y, width, height]
print("CXCYWH:", bbox_cxcywh[0]) # [center_x, center_y, width, height]
# 5. 연쇄 변환
chain_transform = ConvertBoundingBoxFormat('CXCYWH')
final_boxes = chain_transform(bbox_xywh) # XYWH to CXCYWH
print(f"연쇄 변환 결과: {final_boxes}")
# 6. Detection 파이프라인에서 활용
from torchvision.transforms.v2 import Compose, RandomHorizontalFlip
detection_pipeline = Compose([
RandomHorizontalFlip(p=0.5),
ConvertBoundingBoxFormat('CXCYWH'), # YOLO 포맷으로 변환
])
# 7. 성능 테스트
import time
# 대량 박스 변환 성능
large_boxes = torch.rand(1000, 4) * 500 # 1000개 박스
large_bbox = BoundingBoxes(large_boxes, format='XYXY', canvas_size=(1000, 1000))
start = time.time()
for _ in range(100):
converted = to_cxcywh(large_bbox)
conversion_time = time.time() - start
print(f"1000개 박스 변환 100회: {conversion_time:.4f}초")
# 8. 유효성 검증
def validate_conversion(original, converted, original_format, target_format):
"""변환 정확성 검증"""
if original_format == 'XYXY' and target_format == 'XYWH':
# XYXY to XYWH 검증
x1, y1, x2, y2 = original[0]
x, y, w, h = converted[0]
assert torch.isclose(x, x1)
assert torch.isclose(y, y1)
assert torch.isclose(w, x2 - x1)
assert torch.isclose(h, y2 - y1)
print("XYXY to XYWH 변환 정확")
validate_conversion(bbox_xyxy, bbox_xywh, 'XYXY', 'XYWH')
7. 정리:
7-1. 성능 순위:
- ConvertBoundingBoxFormat - 가장 빠름 (단순 수학 연산)
- ToPureTensor - 매우 빠름 (메타데이터 제거만)
- ToImage (기존 텐서 입력) - 빠름 (TVTensor 래핑만)
- ToDtype - 빠름 (PyTorch 네이티브 연산)
- ToImage (PIL/NumPy 입력), PILToTensor - 중간 (실제 변환 발생)
- ToPILImage - 상대적으로 느림 (PIL 변환 비용)
7-2. 메모리 사용 패턴:
- ToImage:
- ToImage: 입력에 따라 다름
- 기존 텐서는 래핑만, PIL/NumPy는 새 텐서 생성
- ToPureTensor:
- 메모리 절약 (메타데이터 제거)
- 호환성 향상.
- PILToTensor/ToPILImage:
- 새로운 객체 생성
- ToDtype:
- 타입에 따라 4배까지 증가 가능:
uint8에서float32의 경우.
- 타입에 따라 4배까지 증가 가능:
728x90
'Python' 카테고리의 다른 글
| [torchvision] image로부터 torch.tensor 객체 얻기 (0) | 2025.06.17 |
|---|---|
| [torchvision] transforms.v2, transforms.v2.functional, 그리고 kernel (0) | 2025.06.17 |
| [PyTorch] torchvision.transforms.v2 - Summary (작성중) (2) | 2025.06.16 |
| [PyTorch] Composition-torchvision.transforms.v2 (0) | 2025.06.16 |
| [PyTorch] Randomly-applied-torchvision.transforms.v2 (0) | 2025.06.15 |