열심히 코딩 하숭!
2. 파이토치의 기본 기능 | 파이토치 딥러닝 프로그래밍 본문
2. 파이토치의 기본 기능
2.2 텐서
1) 텐서(Tensor)의 개념
- 파이토치에의 고유 클래스로, 데이터를 표현한다
- 파이토치의 연산 대상 데이터는 모두 Tensor라는 고유의 형식으로 되어있어야 한다
- 0계 텐서(스칼라) / 1계 텐서(벡터), 2계 텐서(행렬)
2) 다양한 계수의 텐서 만들기
- torch.tensor (값 대입)
- 뒤에 float을 붙여 강제로 float32로 변환하기 (대부분의 계산에 dtype=float32를 사용한다)
- (그렇지 않으면 float64로 설정되고 이는 nn.Linear 같은 부분에서 에러를 발생시킨다)
r0 = torch.tensor(1.0).float()
- tensor 확인
print(type(r0)) # 변수 자체의 타입 확인
print(r0.dtype) # 텐서 내의 데이터 타입 확인
print(r0.shape) # 차원 확인
print(r0.data) # 값 확인
## 결과 ##
<class 'torch.Tensor'>
torch.float32
torch.Size([])
tensor(1.)
- 1계/2계 텐서 - np.array를 활용
- 텐서와 넘파이는 서로 변환이 가능하다
## 1계 텐서 ##
r1_np = np.array([1,2,3,4,5])
r1 = torch.tensor(r1_np).float()
print(r1_np.shape)
print(r1.dtype)
print(r1.shape)
print(r1.data)
## 결과 ##
(5, )
torch.float32
torch.Size([5])
tensor([1., 2., 3., 4., 5.])
## 2계 텐서 ##
r2_np = np.array([[1,5,6],[4,3,2]])
r2 = torch.tensor(r2_np).float()
print(r2_np.shape)
print(r2.shape)
print(r2.data)
## 결과 ##
(2, 3)
torch.Size([2, 3])
tensor([1., 5., 6.],
[4., 3., 2.])
- 3계/4계 텐서- torch.randn / torch.ones를 활용
## 3계 텐서 ##
torch.manual_seed(123) # 난수 seed 초기화
r3 = torch.randn((3, 2, 2)) # shape=[3, 2, 2]인 정규분포 텐서 작성
## 4계 텐서 ##
r4 = torch.ones((2,3,2,2)) # 요소가 모두 1인 shape=[2,3,2,2] 텐서 작성
3) 정수값을 가지는 텐서 만들기
- long 함수 사용
- 다중분류에서 사용하는 손실함수 nn.CrossEntropyLoss와 nn.NLLLoss에서 사용한다고 한다…(자세히는 아직 모르겠다)
r5 = r1.long()
4) view 함수
- 넘파이의 reshape 함수와 같이, view 함수로 계수 변환이 가능하다
r3 = torch.randn((3, 2, 2))
r6 = r3.view(3, -1)
print(r6.shape)
## 결과 ##
torch.Size([3, 4])
- 1계 텐서로 변환하거나, 자동 변환을 하려면 -1로 지정하면 된다
r7 = r3.view(-1)
5) item 함수
- 0계 텐서의 경우 item 함수로 값을 꺼낼 수 있다
- 주의: 1계 이상의 텐서에 사용하면 오류가 난다
- 예외: shape이 [1]이나 [1,1]일 경우 사용 가능하다
item = r0.item()
print(type(item))
print(item)
## 결과 ##
<class 'float'>
1.0
6) max/min/mean 함수
- 최대값을 반환
print(r2.max())
print(r2.min())
print(r2.mean())
7) torch.max(r2, 1) 함수
- 기준이 되는 축을 설정하고, 축마다의 max값을 모아서 볼 수 있다
print(torch.max(r2, 1), "\\n")
print(torch.max(r2, 1) # 인덱스 가져오기
## 결과 ##
torch.return_types.max(
values=tensor([6., 4.]),
indices=tensor([2, 0]))
tensor([2, 0])
8) 텐서에서 넘파이로 변환
- .data.numpy() 사용
r2_np = r2.data.numpy()
2.3 자동 미분 기능
1) 경사 계산용 변수 정의
- 경사(미분) 계산을 해야 하는 변수는 텐서 변수로 정의한다
- 이 때, requires_grad 속성을 True로 설정해야 한다
x = torch.tensor(x_np, **requires_grid**=**True**, dtype=torch.float32)
2) 텐서 변수 간의 계산
- 다른 텐서 변수와 연산을 할 때, 계산 식을 통해 값을 계산한다
y = 2*x**2 + 2
# y도 자동적으로 텐서 변수가 된다 (**requires_grid**=**True 속성도 가질 수 있다)**
- 경사 계산 대상의 함수는 스칼라일 필요가 있으므로, y 값을 sum 함수로 모두 더한 다음 그 결과를 새로운 텐서 변수 z에 대입한다 (=> 손실함수가!!!! 스칼라 값이어야 하니까!!!)
z = y.sum()
3) 계산 그래프 시각화
- 계산 그래프는 make_dot 함수를 통해 시각화 할 수 있다
from torchviz import make_dot
g = make_dot(z, params={'x':x})
display(g)
4) 경사 계산
- 계산 결과를 저장한 텐서 변수에 backward 함수를 호출한다
- 이 때, 파이토치 내부에서 수치 미분이 작용해서 경사 계산이 이뤄진다
z.backward()
5) 경삿값 가져오기
- 수치 미분의 결과를 파이토치에서 ‘경삿값’이라고 부른다
- 경삿값은 텐서 변수의 grad 속성으로 가져올 수 있다
print(x.grad)
6) 경삿값의 초기화
- grad 속성에 저장된 경사값은, 사용이 끝나면 값을 초기화해야 한다
- x.grad는 최신 경사 계산 결과가 그대로 입력되는 것이 아니라, 지금까지의 경사 계산 결과를 합산한 값이 입력되기 때문이다
x.grad.zero_()
'프로그래밍 책 > 파이토치 딥러닝 프로그래밍' 카테고리의 다른 글
9. CNN을 활용한 이미지 인식 | 파이토치 딥러닝 프로그래밍 (1) | 2024.04.21 |
---|---|
8. MNIST를 활용한 숫자 인식 | 파이토치 딥러닝 프로그래밍 (1) | 2024.04.21 |
4. 예측 함수 정의하기 | 파이토치 딥러닝 프로그래밍 (1) | 2024.04.17 |
3. 처음 시작하는 머신러닝 | 파이토치 딥러닝 프로그래밍 (0) | 2024.04.17 |
1. 딥러닝에 꼭 필요한 파이썬의 개념 | 파이토치 딥러닝 프로그래밍 (0) | 2024.04.15 |