Tensor 생성 및 변환
Tensor 초기화
torch.zeros(n) | 길이가 n인 0으로 초기화된 1-D Tensor를 생성 |
---|---|
torch.zeros([n,m]) | 크기가 n * m인 0으로 초기화된 2-D Tensor를 생성 |
torch.ones(n) | 길이가 n인 1으로 초기화된 1-D Tensor를 생성 |
torch.zeros_like(e) | e와 크기와 자료형이 같은 0으로 초기화된 Tensor로 변환 |
torch.ones_like(b) | b와 크기와 자료형이 같은 1로 초기화된 Tensor로 변환 |
torch.rand(n) | 크기가 n인, 0~1 사이의 연속균등분포에서 추출한 난수로 채워진 Tensor를 생성 |
torch.randn(n) | 크기가 n인, 표준정규분포에서 추출한 난수로 채워진 Tensor를 생성 |
torch.rand_like(n) | n과 크기와 자료형이 같은 [0, 1] 구간의 연속균등분포 난수로 채워진 Tensor로 변환 |
torch.arange(start, end, step) | start에서 end(포함하지 않음)까지 step만큼 증가하는 1-D Tensor |
초기화 하지 않은 Tensor
- 성능 향상: Tensor를 생성하고 곧바로 다른 값들로 덮어쓸 예정인 경우라면, 초기 값을 설정하는 단계는 불필요한 자원을 소모하는 것임
- 메모리 사용 최적화: 큰 Tensor를 다룰 때, 불필요한 초기화는 메모리 사용량을 증가시킴. 초기화되지 않은 Tensor를 사용함으로써 메모리 할당 후 즉시 필요한 계산에 사용하여 메모리 효율성을 높일 수 있음
torch.empty(n) | 크기가 n인 초기화 되지 않은 Tensor를 생성 |
---|---|
t.fill_(k) | 초기화 되지 않은 Tensor t의 데이터를 k로 수정해 채움. 이때, 메모리 주소는 변경되지 않음! |
다양한 Tensor 생성
torch.tensor(리스트) | 리스트를 Tensor로 생성할 수 있음 |
---|---|
torch.from_Numpy(u) | |
넘파이 매트릭스 u를 Tensor로 생성 | |
torch.IntTensor(n) | n을 데이터로 갖는 정수형 CPU Tensor 생성 |
torch.FloatTensor(n) | n을 데이터로 갖는 실수형 CPU Tensor 생성 |
torch.ByteTensor | 8비트 부호 없는 정수형 CPU Tensor 생성 |
torch.CharTensor | 8비트 부호 있는 정수형 CPU Tensor 생성 |
torch.ShortTensor | 16비트 부호 있는 정수형 CPU Tensor 생성 |
torch.LongTensor | 64비트 부호 있는 정수형 CPU Tensor 생성 |
torch.DoubleTensor | 64비트 부호 있는 실수형 CPU Tensor 생성 |
y = x.clone() | Tensor x와 같은 Tensor y를 생성 |
z = x.detach() | Tensor x와 같은 Tensor z를 생성, clone() 메서드와 다른 점은 x를 계산 그래프에서 분리하여 새로운 Tensor z에 저장한다는 것 |
CUDA Tensor
CUDA
- Compute Unified Device Architecture, NVIDIA가 만든 GPGPU 플랫폼 및 API 모델
- GPU 가상 명령어 집합을 쓸 수 있게 해주는 소프트웨어
- GPU는 병렬 데이터 처리 능력이 뛰어나기 때문에 AI 분야에서는 GPU를 주로 사용함
- CUDA 메서드를 설명하는 PyTorch 공식 문서
- GPU와 AI의 관련성
# Tensor t가 어떤 디바이스(CPU, CUDA...)에 있는지 확인
t.device
#CUDA를 사용할 수 있는 환경인지 확인
torch.cuda.is_available()
#CUDA device 이름을 확인
torch.cuda.get_device_name(device=0)
#Tensor를 GPU에 할당
g = torch.tensor([1, 2, 3, 4, 5]).to(‘cuda’)
g = torch.tensor([1, 2, 3, 4, 5]).cuda()
#GPU에 할당된 Tensor를 CPU Tensor로 변환하는 코드 표현
c = b.to(device = ‘cpu’)
c = b.cpu()
Tensor 인덱싱 / 슬라이싱
- Indexing(인덱싱)이란 Tensor의 특정 위치의 요소에 접근하는 것
- Slicing(슬라이싱)이란 Tensor의 부분집합을 선택하여 새로운 Sub Tensor를 생성하는 과정
Tensor의 인덱싱과 슬라이싱은 대부분 numpy와 같은 방식으로 이루어진다!
Tensor 모양 변경: view()
vs reshape()
view()
t.view(m, n)
#텐서 t로부터 m*n 크기의 서브 텐서를 생성하는 메서드
view()
메서드는 Tensor의 메모리가 연속적으로 할당된 경우에 사용 가능- 슬라이싱 등으로 Tensor를 조작했을 때 서브 Tensor가 생성되는 과정에서 메모리가 비연속적으로 변하기도 하기 때문에 확인이 필요함
- view() 메소드는 연속적인 상황에서 원본과 동일한 데이터를 가리키면서 모양과 같은 메타 정보만 바뀌기 때문에 빠르다
view()
메서드 사용 가능 여부는 stride에 영향을 받는다? stride가 규칙성을 가지면 연속적이라 판단하기도 하는 모양.
reshape()
t.reshape(m, n)
#텐서 t로부터 m*n 크기의 서브 텐서를 생성하는 메서드
reshape()
메서드는view()
메서드와 달리 Tensor의 메모리가 연속적으로 할당되지 않아도 사용이 가능- 안전하고 유연성이 좋다는 장점이 있으나 성능 저하의 단점이 있음
view()
vs reshape()
- 메모리의 연속성이 확실하고 성능이 중요한 경우
view()
메서드를 사용하는 것이 좋음 - PyTorch에서
view()
를 사용할 수 있는지 확실하지 않은 경우 대부분reshape()
를 사용할 것을 권장하고 있음
메모리 정렬이 이루어지지 않은 데이터는 데이터 참조시 불필요하게 전체 메모리에서 값을 찾아야 할 수 있음.
반대로 메모리 정렬이 잘 되어 있다면 데이터 참조 시에 주소 순서에 따라 빠르게 데이터를 가져올 수 있음. 이 경우 데이터가 커지면 커질 수록 정렬된 데이터가 연산에도 유리!
또한 Contigous()한 상태로 가져오지 않고 처리할 경우, 나중에 데이터 처리를 위한 정렬을 다시 해야 하므로 비용이 이중으로 발생!
Tensor 모양 변경
flatten()
- Tensor를 평탄화 하는 모양 변경 방법
- flatten() 함수는 다차원 데이터를 처리할 때 유용하며, 데이터를 신경망 모델에 적합한 형태로 전처리하기 위해 많이 활용함
# 3차원 텐서 k
l = torch.flatten(k, 0)
# k의 0번째 차원부터 마지막 차원까지 평탄화
m = torch.flaten(k, 1, 2)
# k의 1번째 차원부터 2번째 차원까지 평탄화
transpose()
- transpose는 Tensor의 특정한 두 차원의 축을 서로 바꿈
q.transpose(0, 1)
# q 텐서의 0차원과 1차원의 축을 바꿈
squeeze()
- Tensor에서 dim이 1인 특정 차원을 축소
# Tensor w에서 dim이 1인 특정 차원을 축소하는 코드 표현
x = torch.squeeze(w, dim = 0)
# 또는
x = torch.squeeze(w, dim = 1)
unsqueeze()
- Tensor에서 dim이 1인 특정 차원을 확장
#Tensor y에서 2차원으로 dim이 1인 특정 차원을 확장하는 코드 표현
z = torch.unsqueeze(y, dim = 2)
stack()
- dim-n인 축을 기준으로 새로운 차원을 생성하여 Tensor들을 결합
# dim-0인 축을 생성하여 3개의 2D Tensor를 결합
# argument 안 주면 default가 dim=0
a = torch.stack((red_channel, green_channel, blue_channel))
# dim-1인 축을 생성하여 3개의 2D Tensor를 결합
a = torch.stack((red_channel, green_channel, blue_channel), dim = 1)
cat()
- 새로운 차원을 추가하는 것이 아닌 기존의 차원을 유지하면서 Tensor들을 연결
- 기존을 차원을 유지하기 때문에 크기가 맞아야만 연결할 수 있음
# dim = 0을 기준으로 Tensor b와 c를 연결
d = torch.cat((b,c))
# dim = 1을 기준으로 Tensor b와 c를 연결
d = torch.cat((b,c), 1)
expand()
- 주어진 Tensor의 차원의 크기가 1일 때, 해당 차원의 크기를 확장함
- 크기가 1인 차원이 있으면 메모리를 할당하지 않고 expand가 일어나고, 그렇지 않으면 할당하면서 expand가 일어난다?
f = torch.tensor([[1, 2, 3]]) # 크기가 (1,3)인 2차원 텐서
g = f.expand(4, 3)
# (1, 3) 크기인 f를 (4,3)로 확장
repeat()
repeat()
메서드는 Tensor의 요소들을 반복해서 크기를 확장하는데 사용하며,expand()
메서드와는 다르게 Tensor의 차원 중 일부의 크기가 1이어야 하는 제약이 없음repeat()
메서드는 추가 메모리를 할당하기 때문에 메모리를 할당하지 않는expand()
메서드보다 메모리 효율성이 떨어짐repeat()
메서드와expand()
메서드의 차이점 파악할 것
# Tensor h를 dim = 0 축으로 2번 반복하고, dim = 1 축으로 3번 반복하여 크기 확장
i = h.repeat(2, 3)
'Study - AI > Torch & Tensor' 카테고리의 다른 글
이진 분류 알고리즘 & 배치(Batch) (0) | 2025.01.03 |
---|---|
Tensor 연산 방식 (0) | 2025.01.03 |
PyTorch & Tensor (0) | 2025.01.02 |