딥러닝 프로세스는 입력을 부동소수점수로 변환하는 것부터 시작한다
데이터처리와 저장을 위해 파이토치에서는 텐서라는기본 ㅈ료구조를 제공한다. 다차원 배열이라고도 부른다. 파이토치가 다차원 배열을 다루는 유일한 라이브러리는 아니며 넘파이가 현재까지는 제일 유명한 다차원 배열 라이브러리다. 파이토치는 넘파이와 깔끔하게 호환되도록 만들어졌다.
텐서는 차원이나 축이있고 각 차원은 픽셀위치나 컬러채널에 해당한다.
import torch
a = torch.ones(3)
파이썬에서 숫자는 객체라 소량연산은 상관없지만 수백만개가넘어가면 상당히 비효율적이다. 마찬가지로 C 같은 저수준 컴파일과 다르게 연산이느리게된다.
리스트에들어있는 데이터를 최적화해배치하는기능이없고 단일차원이다.물론 리스트에리스트를 만드는 방법이있지만 매우 비효율적이다.
위의 이유로 넘파이에 의존하거나 파이토치 텐서같은 전용 저수준의 데이터구조를 만든후 효율을 높여 고차원 API로 래핑해 편리성을 더한다.
dtype인자는 아래와같다.
torch.float32, torch.float
torch.float64, torch.double
torch.float16, torch.half
torch.int8 부호있는 8비트 정수
torch.unit8 부호없는 8비트 정수
torch.int16, torch.short
torch.int32, torch.int
torch.int64, torch.long
torch.bool
dtype인자전달, 속성읽기, 타입변환
torch.ones(10, 2, dtype=torch.double)
var1.dtype
var2 = torch.zeros(10, 2).to(torch.double)
_ 밑줄로 끝나면 새텐서가 넘어오지않고 기존 텐서의 내용이 바뀐다.
a = torch.ones(3, 2)
a.zero_()
a
tensor([
[0., 0.],
[0., 0.],
[0., 0.]
]
)
size는 하나의 요소를 가지는 객체이고 값으로는 차원의 크기가들어있다.이는 shape와 동일하다
var.size()
var.shape()
stride()는각 차원에서 인덱스를 하나증가했을때 저장공간상 몇개요소를 건너뛰어야하는지를 값으로가진다.
points = torch.tensor(
[
[4.0, 1.0],
[4.0, 1.0],
[4.0, 1.0],
]
)
point.stride()
(2, 1)
Tensor를 생성하면 실제 메모리에서는 이렬로 저장되며 reshape도 메모리를 재할당하지않는다.
import torch
x = torch.arange(12)
print(x)
tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
Storage
0 1 2 3 4 5 6 7 8 9 10 1
x = torch.arange(12)
y = x.view(3, 4)
print(y)
tensor([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
Storage
0 1 2 3 4 5 6 7 8 9 10 11
Tensor 정보
size=(3,4)
stride=(4,1)
전치 transpose 새로운 메모리를 할당하지 않고 원래 것과 다른 스트라이드 순서를 가진 새로운 tensor 인스턴스 만든다.
행렬 뿐 아니라 다차원배열에서도 두 차원을 지정해주면 전치된다.
PyTorch의 transpose / permute가 “데이터를 복사하지 않고 view(view tensor)”를 만든다는 핵심입니다. 즉, stride만 바꿔서 논리적 배치만 바꾸는 방식
transpose (2D)
import torch
x = torch.tensor([
[1, 2, 3],
[4, 5, 6]
])
print("원본 x")
print(x)
print("stride:", x.stride())
# transpose (0,1)
y = x.transpose(0, 1)
print("\ntranspose 결과 y")
print(y)
print("stride:", y.stride())
transpose ( 3D)
x = torch.arange(2 * 3 * 4).reshape(2, 3, 4)
print("원본 shape:", x.shape)
print("stride:", x.stride())
# 0번과 2번 차원 swap
y = x.transpose(0, 2)
print("\n변경 후 shape:", y.shape)
print("stride:", y.stride())
permute (다차원 재배열)
tanspose는 2차원까지가 가능하다.
x = torch.randn(2, 3, 4)
y = x.permute(2, 0, 1)
print("원본:", x.shape)
print("변환:", y.shape)
contiguous()
메모리 상에서 실제로 인접한 텐서로 만들어주는 메서드
베연속 텐서를 물리적으로 연속된 메모리 배치로 복사해서 재구성한다.
`transpose`, `permute` 같은 연산을 하면 데이터 자체가 이동하지않아 stride만 바뀐 view 텐서가 만들어진다. 즉 메모리가 논리적으로는 맞지만 물리적으로는 건너뛰면서 배치된것. 즉 이것을 non-contiguous tensor라 한다.
contiguous()는 새로운 메모리 블록을 할당해 텐서값을 보이는 순서대로 복사해 재구성한다 독립적으로 수정도 가능하다.
z = y.contiguous()
print(z.is_contiguous())
딥러닝에서 메모리상에서 실제로 인접한 텐서로 만들어주는 메서드 contiguous 는 매우 중요하다.
일부 연산은 contiguous만 허용한다. 예를 들어 특정 loss / conv 최적화 연산시 -1 에러가 날수있기때문이다.
y.view(-1) # 에러 날 수 있음 (non-contiguous면)
y = y.contiguous().view(-1)
* transpose → stride만 바꿈 (논리 구조 변경)
* contiguous → stride를 다시 “정상 순서”로 재구성 + 데이터 복사
Tensor를 gpu로 옮기기
파이토치는 cpu외 gpu 메모리에도 저장할 수 있는데 대량 병렬 처리 연산으로 빠르게 학습할 수 있다.
device 라는 인자로 텐서 데이터가 실제 컴퓨터 어디에 위치할지 저장할 수 있다.
import torch
# CPU에 생성
x_cpu = torch.tensor([1, 2, 3], device='cpu')
print(x_cpu)
print(x_cpu.device)
import torch
# GPU 사용 가능할 때
x_gpu = torch.tensor([1, 2, 3], device='cuda')
print(x_gpu)
print(x_gpu.device)
x = torch.tensor([1, 2, 3])
# GPU로 이동
x_gpu = x.to('cuda')
# 다시 CPU로 이동
x_cpu = x_gpu.to('cpu')
x = torch.tensor([1, 2, 3], device='cpu')
y = torch.tensor([1, 2, 3], device='cuda')
x + y # 에러 발생
Numpy는 파이썬 데이터과학 생태계에서 매우 독보적이다.
파이토치에 텐서와 넘파이 배열의변환응ㄴ 매우 효율적으로 이루어지고 넘파이 배열과의 제로카피 수준의 상호변환은 파이썬 버퍼 프로토콜이라는 저장 시스템 덕분이다.
import torch
x = torch.tensor([1, 2, 3])
y = x.numpy() # NumPy view 생성 (copy 아님)
print(y)
print(type(y))
x = torch.tensor([1, 2, 3])
y = x.numpy()
y[0] = 999
print("torch tensor:", x)
print("numpy array:", y)
Numpy 값을 바꾸면 Tensor도 같이 바뀐다. 동일한 underlying memory를 공유하는것! 반대역시 마찬가지
import numpy as np
import torch
a = np.array([1, 2, 3])
t = torch.from_numpy(a)
print(t)
a = np.array([1, 2, 3])
t = torch.from_numpy(a)
t[0] = 777
print("numpy array:", a)
print("torch tensor:", t)
!!
텐서란 하나의 고정된 자료구조이다.
텐서는 하나의 인터페이스 즉 규약일 뿐 구현을 여러가지일 수 있다는 점이 중요한 개념.
일반화된 텐서라는 말은 우리가 보통 아는 텐서 pytorch tensor, umpy tensor 처럼 하나의 배열처럼 보이지만 개념적으로는 n차원 데이터를 표현하고 특정 연산 api를 만족하는 개체일 뿐이다 즉 내부 구현이 아니라 연산규칙일 뿐이란말.
api안에는 shape, dtype, indexing, boardcasting 등의 조건이 있는데 이것들을 만족하면 내부 구현이 달라고 텐서처럼 쓸수있다는것!
예전에는 텐서는 그저 dese array하나엿다면 현재는 sparse tensor, graph tensor, laze tensor등 겉으로 모두 tensor api를 따르며 존재할 수 있다는 것이다. 즉 텐서는 데이터 구조가 아니라 연산 인터페이스.
HDF5
Hierarchical Data Format 5
다른 라이브러리에 의존하는 시스템이 있는 상태에서 파이토치를 도입하는 경우라면 텐서를 호환가능한 상태로 저장해야할 가능성이 높다. 이럴때는 먼저 HDF5 포맷을 위한 라이브러리가 필요한데 이는 이식성이 높고 광범위하게 지원되는 딕셔너리에서 다차원 배열을 표현하는 포맷이다.
pytorch tensor는 gpu 메모리 기반 python runtime에 의존했다면 다른 시스템과 직접 호환이 어렵다. 반면 hdf5는 모든 시스템이 읽을 수 있는 중립 저장 포맷이다
import torch
import h5py
import numpy as np
# tensor 생성
x = torch.randn(3, 4)
# HDF5 저장
with h5py.File("data.h5", "w") as f:
f.create_dataset("my_tensor", data=x.numpy())
import h5py
import torch
with h5py.File("data.h5", "r") as f:
arr = f["my_tensor"][:] # numpy array로 로딩
x = torch.tensor(arr)
print(x)
import torch
import h5py
x = torch.randn(2, 2)
y = torch.randn(3, 3)
with h5py.File("multi.h5", "w") as f:
f.create_dataset("x", data=x.numpy())
f.create_dataset("y", data=y.numpy())
'Personal > Book' 카테고리의 다른 글
| 파이토치 딥러닝 마스터 - 1부 - 4장 실제 데이터를 텐서로 표현해보기 (0) | 2026.06.28 |
|---|---|
| 파이썬으로 따라해보는 딥러닝 AI프로젝트 실사례 (0) | 2026.06.26 |
| Do it! 자바 완전 정복 (0) | 2026.06.19 |
| 팀 개발을 위한 Git GitHub시작하기 (0) | 2026.06.15 |
| 이것이 MySQL이다 - part04_MySQL 응용 프로그램 및 공간 데이터 (0) | 2026.06.11 |