euphoriaO-O

[PyTorch] 3. Tensor 본문

Machine Learning/Pytorch

[PyTorch] 3. Tensor

euphoria0-0 2020. 7. 16. 00:00
This article is based on the book "Deep Learing with PyTorch".
https://pytorch.org/deep-learning-with-pytorch

3. It starts with a tensor

  1. The world as floating-point numbers
  2. Tensors: Multidimensional arrays
  3. Indexing tensors
  4. Named tensors
  5. Tensor element types
  6. The tensor API
  7. Tensors: Scenic views of storage
  8. Tensor metadata: Size, offset, and stride
  9. Moving tensors to the GPU
  10. NumPy interoperability
  11. Generalized tensors are tensors, too
  12. Serializing tensors

이 단원에서는 PyTorch의 데이터 구조인 tensor에 대해 배운다.

모델은 데이터의 표현을 변환하는 매핑 함수이다!

예를 들어, 이미지 관련 모델은 이미지 픽셀 숫자를 변환 및 처리하는 함수라 할 수 있다.

1. The world as floating-point numbers

부동소수점 숫자(floating-point numbers)는 네트워크가 정보를 처리하는 방식이므로 처리하고자 하는 종류의 실제 데이터를 네트워크에 의해 이해가능한 방법으로 인코딩하고, 우리의 목적을 위해 사용할 수 있는 형태로 다시 디코딩하는 방법이 필요하다.

심층 신경망(DNN)은 일반적으로 한 형태의 데이터에서 다른 형태로 단계적으로 변환하는 것을 학습한다.

초기 표현에서는 edge detection이나 texture 등이 될 수 있으며

더 깊은 표현에서는 귀, 코 등의 복잡한 구조를 포착할 수 있다.

중간 표현은 입력을 특성화하고 인풋을 신경망의 아웃풋에 매핑되는 법을 설명가능한 데이터의 구조를 포착하는 부동소수점의 컬렉션이라 할 수 있다. 이는 이전 뉴런 레이어의 가중치와 결합한 결과이며 각 중간 표현은 발생하는 인풋에 유일하다.

PyTorch가 데이터를 어떻게 다루고 저장하는가 -> 텐서 도입

텐서(tensor)는 벡터, 행렬을 임의의 수의 차원으로 일반화한 것이며 다차원 배열을 의미한다.

numpy 등도 있지만 PyTorch 텐서는 GPU에서 빠른 작업 속도를 보여 분산 처리, 계산 그래프 추적? 등을 할 수 있다.

이제 PyTorch에서 메모리가 저장되는 방법, 일정한 시간에 임의의 대형 텐서에서 특정 작업을 수행하는 방법, numpy와의 상호 운용성, GPU 가속 등을 배울 것이다.

 

2. Tensors: 다차원 배열

텐서는 배열이다. 즉, 숫자들의 컬렉션을 저장하는 데이터 구조이다. 텐서는 인덱스를 사용하여 개별적으로 혹은 여러개로 가능하다.

 

Python list에서는 zero-base의 인덱스에 대응하는 숫자로 접근할 수 있다.

PyTorch에서는 다음과 같이 텐서를 만들 수 있다.

import torch
a = torch.ones(3)
a
tensor([1., 1., 1.])

PyTorch tensor 인덱싱 (zero-baed의 인덱스)

a[1]
tensor(1.)

PyTorch tensor 원소의 개별 데이터 타입 변경

float(a[1])
1.0

PyTorch tensor 원소 변경 (새로운 값 할당)

a[2] = 2.0
a
tensor([1., 1., 2.])

 

 

파이썬 리스트나 튜플은 메모리에 개별적으로 할당된다.

그러나 PyTorch의 텐서나 NumPy의 어레이는 unboxed C numeric types를 포함하는 연속적인 메모리 블락에 대한 뷰이다.

이 경우 각 원소는 32-bit이다. 즉, 1백만 부동 소수점 수의 1D 텐서를 저장하려면 4백만 개의 연속 바이트와 메타 데이터(차원,숫자유형)에 대한 작은 오버 헤드가 필요하다.예로, X 좌표를 짝수 인덱스(0,2,4)에, Y 좌표를 홀수 인덱스(1,3,5)에 저장한다고 하자.

points = torch.zeros(6)
points[0] = 4.0
points[1] = 1.0
points[2] = 5.0
points[3] = 3.0
points[4] = 2.0
points[5] = 1.0

혹은 파이썬 리스트를 파이토치 텐서로 변경해도 같다.

points = torch.tensor([4.0, 1.0, 5.0, 3.0, 2.0, 1.0])

첫 번째 (X, Y) 좌표를 얻으려면 다음과 같이 한다.

float(points[0]), float(points[1])

하지만 이 경우에선 2D tensor로 표현하는 것이 더 좋을 것이다.

points = torch.tensor([[4.0, 1.0], [5.0, 3.0], [2.0, 1.0]])
points
tensor([[4., 1.],
	[5., 3.],
	[2., 1.]])

tensor의 shape(크기, 차원)는 다음과 같이 구한다.

points.shape
torch.Size([3, 2])

tensor 초기화 시 zero나 one을 이용해 사이즈를 지정하여 만들 수도 있다.

points = torch.zeros(3, 2)
points
tensor([[0., 0.],
	[0., 0.],
	[0., 0.]])

2D tensor는 두 인덱스로 개별 원소에 접근할 수 있다.

points = torch.tensor([[4.0, 1.0], [5.0, 3.0], [2.0, 1.0]])
points
tensor([[4., 1.],
	[5., 3.],
	[2., 1.]])
points[0, 1] # 1번째 점의 Y좌표
tensor(1.)
points[0] # 첫번째 점의 X,Y좌표
tensor([4., 1.])

아웃풋은 같은 데이터의 다른 뷰로 보여지는 또다른 텐서이다. 새로운 텐서는 포인트 텐서 내의 첫번째 행의 값을 참조하는 크기 2의 1D 텐서이다.

새 메모리 chunk가 할당되고 값이 복사되고 새로운 메모리가 새로운 텐서 객체에 wrapping되어 반환된 것은 아니다. 텐서의 뷰는 이장의 이후에 다시 나온다.

3. Indexing tensors

range indexing notation 사용

some_list = list(range(6))
some_list[:]   # 모든 원소
some_list[1:4] # 1부터 3까지
some_list[1:]  # 1부터 끝까지
some_list[:4]  # 처음부터 3까지
some_list[:-1] # 처음부터 마지막 전 원소(2)까지
some_list[1:4:2] # 1부터 3까지 2 step으로

2차원 이상일 때

points[1:]    # 1이후 행, 모든 열
points[1:, :] # 1이후 행, 모든 열
points[1:, 0] # 1이후 행, 1천째 열
points[None]  # 크기 1의 차원을 더해 unsqueeze와 같음

4. Named tensors

텐서의 차원(또는 축)은 일반적으로 픽셀의 위치 또는 색상 채널 등을 인덱싱한다. 즉, 텐서로 인덱싱하려면 차원의 순서를 기억하고 그에 따라 인덱싱을 작성해야 한다. 데이터가 여러 텐서를 통해 변환될 때 어떤 차원에 오류가 발생하기 쉬운 데이터가 포함되어 있는지 추적한다.

2.1.4의 img_t와 같은 3D 텐서를 grayscale로 변환한다길 원할 때 단일 밝기 값을 얻기 위해 색상에 대한 전형적인 가중치를 찾았다.

img_t = torch.randn(3, 5, 5) # shape [channels, rows, columns]
weights = torch.tensor([0.2126, 0.7152, 0.0722])

또한, 코드가 일반화되길 원한다. 예를 들어, 높이와 너비 차원을 가진 2D 텐서로 표현된 그레이 스케일 이미지에서 세 번째 채널 차원을 추가하는 이미지로, 혹은 단일 이미지를 이미지 배치로. 2.1.4에서 우리는 추가 배치 차원을 소개했다.

batch_t = torch.randn(2, 3, 5, 5) # shape [batch, channels, rows, columns]

따라서 때로는 RGB 채널이 0 차원에 있고 1 차원에도 있다. 그러나 우리는 끝까지 세어 일반화할 수 있다. 항상 -3, 3 차원에 있다. lazy하고 가중치가 없는 평균은 다음과 같이 된다. ??????????????

img_gray_naive = img_t.mean(-3)
batch_gray_naive = batch_t.mean(-3)
img_gray_naive.shape, batch_gray_naive.shape

 

'Machine Learning > Pytorch' 카테고리의 다른 글

[PyTorch] 2-4. Torch Hub  (0) 2020.07.14
[PyTorch] 2-3. Image Captioning  (0) 2020.07.14
[PyTorch] 2-2. GAN, CycleGAN  (0) 2020.07.12
[PyTorch] 2-1. Object Recognition with ResNet  (0) 2020.07.11
Comments