텐서
- 텐서 (Tensor): 넘파이 라이브러리의 ndarray 클래스와 유사한 구조로 배열(Array)이나 행렬(Matrix)과 유사한 자료 구조(자료형)
- 파이토치에서는 텐서를 사용. 모델의 입출력뿐만 아니라 모델의 매개변수를 부호화(Encode)하고 GPU를 활용해 연산을 가속화
- 넘파이와 파이토치의
- 공통점: 다양한 연산 진행 가능
- 차이점: 파이토치는 GPU 가속 (GPU Acceleration)을 적용할 수 있어서, CPU 텐서와 GPU 텐서로 나눠지고, 각각의 텐서를 상호 변환하거나 CPU 사용 여부를 설정함
- 차원 (Rank)
- 스칼라 Scalar (0차원 텐서)
- 벡터 Vector (1차원 텐서)
- 행렬 Matrix (2차원 텐서)
- 배열 Array (3차원 이상)
텐서 생성
- 생성 방법
- torch.tensor()
- 입력된 데이터를 복사해 텐서로 변환
- 데이터를 복사하기 때문에 값이 무조건 존재해야 함.
- 입력된 데이터의 형식에 가장 적합한 텐서 자료형으로 변환 → 의도하지 않은 자료형으로 변경될 수 있음. 사용 주의
- torch.Tensor()
- 텐서의 기본형
- 텐서 인스턴스를 생성하는 클래스. 값이 입력되어 있지 않은 경우 비어있는 텐서를 생성
- 명확하게 표현되는 클래스 형태의 torch.Tensor()를 사용하는 것을 권장
- torch.LongTensor(), torch.FloatTensor(): torch.Tensor 클래스를 상속받은 데이터 형식
- 이외에도 int, double, boolean 형식 등
- torch.tensor()
텐서 속성
- 형태 shape, 자료형 dtype, 장치 device
- 형태
- 텐서의 차원을 의미
- tensor.shape
- 자료형
- 텐서에 할당된 데이터 형식을 의미
- tensor.dtype
- 장치
- 텐서의 GPU 가속 여부를 의미
- tensor.device
- (예제 코드 안에서)
- torch.rand(): 0과 1사이의 무작위 숫자를 균등 분포로 생성하는 함수
- 사용 예시 torch.rand(1,2)
- 생성하려는 텐서의 형태를 의미
- torch.rand(): 0과 1사이의 무작위 숫자를 균등 분포로 생성하는 함수
차원 변환
- 가상 많이 사용되는 메서드 중 하나
- torch.reshape
자료형 설정
- 넘파이랑 차이점 존재
import torch
tensor=torch.rand((3, 3), dtype=torch.float)
- 텐서의 자료형 설정에 입력되는 인수
- torch.* 형태로 할당
- torch.float이 아니라 float로 할당해도 오류는 없지만, (자료형 관점에서) 두 데이터는 다른 자료형
- torch.float는 32비트 부동 소수점 형식
- float는 64비트 부동 소수점 형식
- float 로 할당하면 torch.float보다 더 큰 범위의 숫자를 저장함
- 더 많은 메모리 필요, 학습 과정에서 더 많은 자원 필요
- → 텐서를 선언할 때 가능한 torch.*형태로 정확한 자료형 할당
장치 설정
- 장치 설정을 정확하게 할당하지 않으면 실행 오류 (Runtime Error)가 발생 혹은 CPU 연산이 됨
- Tensor 클래스의 경우 device 매개변수가 존재하지만, CUDA 용 클래스가 별도로 존재하므로 torch.cuda.Tensor 클래스를 사용함
- 특정 데이터에서 복사해 텐서를 적용하는 경우, device 매개변수에 장치값을 할당함
import torch
device= "cuda" if torch.cuda.is_available() else "cpu"
cpu=torch.FloatTensor([1,2,3])
gpu=torch.cuda.FloatTensor([1,2,3])
tensor=torch.rand((1,1), device=device)
장치 변환
- CPU 장치를 사용하는 텐서와 GPU 장치를 사용하는 텐서는 상호 간 연산이 불가능
- CPU 장치를 사용하는 텐서와 넘파이 배열 간 연산은 가능
- GPU 장치를 사용하는 텐서와 넘파이 배열 간 연산은 불가능
- (반대로) 넘파이 배열 데이터를 학습에 활용하려면, GPU 장치로 변환 필요
import torch
cpu=torch.FloatTensor([1,2,3])
gpu=cpu.cuda()
gpu2cpu=gpu.cpu()
cpu2gpu=cpu.to("cuda")
- 장치간 상호 변환: cuda와 cpu 메서드를 통해 가능 + to 메서드
- cuda 메서드: CPU 장치로 선언되는 값을 GPU로 변환
- cpu 메서드: GPU 장치로 선언된 값을 CPU로 변환
- to 메서드: 파이토치에서 지원하는 모든 장치 간의 텐서 변환을 수행
- 파이토치 device 속성에는 cpu, cuda, mps 이외에도 mkldnn, opengl 등이 있음
넘파이 배열의 텐서 변환
- 넘파이나 다른 라이브러리의 데이터를 파이토치에 활용햐ㅏ려면 텐서 형식으로 변환이 필요함
- 변환 방법
- torch.tensor와 torch.Tensor에 넘파이 배열을 그대로 입력하는 방법
- from_numpy 메서드를 통해 변환하는 방법
- 텐서는 넘파이와 매우 친화적인 구조를 가지므로, 넘파이 데이터를 별다른 변환 없이 적용 가능
import torch
import numpy as np
ndarray=np.array([1,2,3], dtype=np.unit8)
print(torch.tensor(ndarray))
print(torch.Tensor(ndarray))
print(torch.from_numpy(ndarray))
텐서의 넘파이 배열 변환
- 추론된 결과를 후처리하거나 결과값을 활용할 때 주로 사용
- 변환 방법
- numpy 메서드를 통함
- detach 메서드 적용
- detach 메서드: 현재 연산 그래프 Graph에서 분리된 새로운 텐서를 반환
- 새로운 텐서를 생성한 다음에 넘파이 배열로 변환함
- 텐서는 기존 데이터 형식과 다르게 학습을 위한 데이터 형식으로 모든 연산을 추적해 기록함
- 이 기록을 통해 역전파 Backpropagation 등과 같은 연산이 진행돼 모델 학습이 이뤄짐
- 텐서의 데이터가 어떻게 변경되고 관리됐는지 기록됨
- GPU 장치라면 CPU 장치로 ㅂ변환한 다음에 넘파이 배열로 변환 가능
import torch
tensor=torch.cuda.FloatTensor([1,2,3])
ndarray=tensor.detach().cpu().numpy()
'Theory > Pytorch' 카테고리의 다른 글
[파이토치 트랜스포머 #6] 3장 파이토치 기초 - 5) 활성화 함수 (1) | 2024.03.17 |
---|---|
[파이토치 트랜스포머 #5] 3장 파이토치 기초 - 4) 모델/데이터세트 분리, 모델 저장 및 불러오기 (0) | 2024.03.06 |
[파이토치 트랜스포머 #4] 3장 파이토치 기초 - 3) 데이터세트와 데이터로더 (0) | 2024.03.06 |
[파이토치 트랜스포머 #3] 3장 파이토치 기초 - 2) 가설, 손실함수, 최적화 (2) | 2024.03.04 |
[파이토치 트랜스포머 #1] 1장 인공지능과 방법론 (1) | 2024.02.24 |