목차
학습 목표
- 파이토치의 기본 연산 단위인 Tensor를 생성하고 연산하는 방법을 안다.
- 파이토치의 AutoGrad(자동 미분) 작동원리에 대해서 안다.
실습 자료 추가(To Do)
Remind
- Pytorch = numpy + AutoGrad
Tensor란?
Pytorch에서 다차원 array를 표현하는 클래스 cf) TF는 ndarry
- 대부분 numpy arr와 비슷
Tensor 생성하기
1) 직접 data 삽입
# 1. 직접 생성
x = torch.tensor([1, 2, 3]) # 1D 텐서 생성
2) numpy arr 기반으로 생성
data = [[1, 2, 3]]
np_array = np.array(data)
y = torch.tensor(np_array)
3) 차원 사이즈를 주고 텐서 생성
- torch.ones(N,M,...) # 주어진 사이즈를 가진, 1로 채워진 tensor로 생성
- torch.zeros(N,M,...) # 주어진 사이즈를 가진, 0로 채워진 tensor로 생성
- torch.rand(N,M,...) # 주어진 사이즈를 가진, 랜덤 tensor로 생성
x = torch.rand(3, 3) # 크기가 3x3인 랜덤 텐서 생성
z = torch.ones(2, 3) # 모든 값이 1인 2x3 텐서 생성
y = torch.zeros(4, 5) # 모든 값이 0인 4x5 텐서 생성
4) 특정 텐서와 같은 shape의 텐서 생성
- torch.ones_like(tensor) # 주어진 텐서와 같은 형태이고, 1로 채워진 tensor로 생성
- torch.zeros_like(tensor) # 주어진 텐서와 같은 형태이고, 0로 채워진 tensor로 생성
- random_like(tensor) # 주어진 텐서와 같은 형태인 랜덤 텐서 생성
x = torch.rand(3, 3) # 크기가 3x3인 랜덤 텐서 생성
y_ones = torch.ones_like(x) # 모든 값이 1인 3x3 텐서 생성
y_zeros = torch.zeros_like(x) # 모든 값이 0인 3x3 텐서 생성
y_random = torch.rand_like(x) # 크기가 3x3인 랜덤 텐서 생성
Tensor와 numpy arr 간 변환
- tensor > np array: numpy()
- np array> tensor : from_numpy()
* 주의점! CPU 상 tensor와 numpy 배열을 메모리 공간을 공유하기 때문에, 하나를 변경하면 다른 하나도 변경된다.
# tensor를 array로 변환하기, tensor를 변환하면 arr 도 같이 변형된다.
t = torch.tensor([1,2,3])
arr = t.numpy()
print(f'tensor:{t}\n numpy arr:{arr}\n') # [1,2,3], [1,2,3]
t.add_(1)
print(f'tensor에 1을 더한 이후 결과 -\n tensor:{t}\n numpy arr:{arr}\n') #[2 3 4], [2 3 4]
Tensor Attributes
shape # 텐서 형태
size() # 텐서 형태
dim # 차원
dtype # 데이터 타입
device # 어떤 장치에 저장되는지 (cpu, gpu면 'cuda')
# 텐서의 속성
print(x.shape) # 텐서의 형태
print(x.size()) # 텐서의 크기
print(x.dtype) # 텐서의 데이터 타입
print(x.device) # 텐서가 어느 장치에 저장되는지
Tensor 슬라이싱
: numpy arr 의 슬라이싱과 매우 유사하다
- tensor[row,col] 의 형태
- row, col 인덱스 지정 : tensor[N, M] 사용
- 범위를 지정하고 싶으면 tensor[N:M, N:M]을 사용
- - e.g. 처음 2개의 row를 찾고 싶음 tensor[:2, :]
Tensor Method
산술 연산
더하기 빼기 가능
# 수학 기본연산
a = torch.tensor([1, 2, 3])
b = torch.tensor([4, 5, 6])
c = a + b # 텐서 덧셈
d = a * b # 텐서 곱셈
print("덧셈 결과:", c)
print("곱셈 결과:", d)
행렬곱 연산
여러 개가 있는데, mm()을 사용하는 것을 추천
A.dot(B)
A.mm(B)
A.matmul(B)
A @ B
*dot vs mm
- dot()은 1차원 tensor 끼리만 가능
- mm()은 N차원 tensor 끼리만 연산 가능(1차원 tensor는 안된다.)
예를 들어, dot은 [1,2,3]과 [4,5,6] 과 같이 1차원 tensor 끼리의 내적만 가능
즉, [[1,2],[3,4]] 와 [[5,6],[7,8]] 의 내적은 dot으로 불가
반면, mm()은 [[1,2],[3,4]] 와 [[5,6],[7,8]] 는 내적 가능하지만 1차원 텐서끼리 내적은 불가!
*dot, mm vs matmul
- matmul는 dot & mm 와 달리, 차원이 다른 tensor 끼리 연산 가능함 (자동으로 broadcasting).
- 예상하지 못한 결과값을 나타낼 수 있기 때문에 사용에 유의 해야함.
연산 가능 차원 | Auto Broadcasting(다른 차원끼리 계산 가능한가?) | |
dot() | 1차원 텐서 끼리만 연산 가능 | X |
mm() | 다차원 텐서 끼리만 연산 가능 | X |
matmul() | 1~N | O |
tensor handling
view() # reshape와 결과는 똑같음
reshape()
squeeze(dim) : 차원 삭제 (dim이 None이면 차원의 개수가 1인 차원을 삭제)
unsqueeze(dim) : 차원 추가(dim이 None이면 차원의 개수가 1인 차원을 추가)
flatten() # 1차원으로 변환
* view, reshape 과의 차이
- 실행 결과는 같음 BUT view를 쓰는 것을 추천
- tensor 형태가 달라지는 경우 값을 보장해주는지 안보장해주는지 차이
- view: 형태가 달라지는 경우에도 같은 메모리를 공유 -> 값의 변화가 반영된다
- reshape: 형태가 달라지면, 원래 값을 copy해서 다른 메모리에 저장 -> 값의 변화가 반영 X
# view()
a1 = torch.zeros(3,2)
b1 = a1.view(2,3) # 텐서 형태를 바꿔줌
a1.fill_(1)
# 결과: b가 바뀌면, a의 값도 바뀜
print("a", a1) # a [[1., 1.],[1., 1.], [1., 1.]]
print("b", b1) # b [[1., 1., 1.], [1., 1., 1.]]
# reshape
a1 = torch.zeros(3,2)
b1 = a1.t().reshape(6) # 텐서 형태를 변형
a1.fill_(1)
# 결과 b가 바뀌어도 a는 바뀌지 않음.
print("a", a1) # a [[1., 1.],[1., 1.], [1., 1.]]
print("b", b1) # b [0., 0., 0., 0., 0., 0.]
*squeeze와 unsqueeze 원리
- squeeze(dim) : 차원 삭제 (dim이 None이면 차원의 개수가 1인 차원을 삭제)
- unsqueeze(dim) : 차원 추가(dim이 None이면 차원의 개수가 1인 차원을 추가)
- 일단 눈으로 한 번 풀어봐라!
- 코드 예상 결과를 상상해보세요.
tensor_ex = torch.zeros((2,2))
print(tensor_ex) # [[0,0],[0,0]]
#unsqueeze- dim0
print(f'unsqueeze- dim0 result:\n', tensor_ex.unsqueeze(0), '\n') # [[[0,0],[0,0]]]
print('-shape:',tensor_ex.unsqueeze(0).shape, '\n') # (1,2,2)
#unsqueeze- dim1
print(f'unsqueeze- dim1 result:\n', tensor_ex.unsqueeze(1), '\n') # [[[0,0]],[[0,0]]]
print('-shape:',tensor_ex.unsqueeze(1).shape, '\n') # (1,2,2)
#unsqueeze- dim2
print(f'unsqueeze- dim2 result:\n', tensor_ex.unsqueeze(2), '\n') # [[[[0],[0]],[[0],[0]]]]
print('-shape:, ',tensor_ex.unsqueeze(2).shape, '\n')
Tensor GPU에 올리기!
# GPU가 존재하면 텐서를 이동합니다
if torch.cuda.is_available():
print("available")
tensor = tensor.to("cuda")
Tensor Operations for ML/DL formula
torch.nn.functional
- softmax(), argmax(), one_hot() 등 다양한 인공지능 함수들을 사용할 수 있음.
AutoGrad(자동 미분)
pytorch의 핵심은 자동 미분 지원이다 -> backward() 함수 사용
- 미분 주체 : tensor에 requires_grad= True 설정
- backward() 함수를 통해 실제 미분 수행
Reference
인공지능 기초 다지기
부스트코스 무료 강의
www.boostcourse.org
(2강-실습) Pytorch basics for DL newbies.ipynb
Colaboratory notebook
colab.research.google.com
텐서(Tensor)
파이토치(PyTorch) 기본 익히기|| 빠른 시작|| 텐서(Tensor)|| Dataset과 Dataloader|| 변형(Transform)|| 신경망 모델 구성하기|| Autograd|| 최적화(Optimization)|| 모델 저장하고 불러오기 텐서(tensor)는 배열(array)이
tutorials.pytorch.kr
'AI > Pytorch' 카테고리의 다른 글
[Pytorch] 2. 나만의 커스텀 데이터셋과 데이터 로더 만들기 (3) | 2024.11.07 |
---|---|
[Pytorch] 프로젝트 구조 이해 (0) | 2024.07.29 |
딥러닝 프레임 워크 비교 - Keras, Tensorflow, Pytorch (0) | 2024.07.26 |