코린이의 소소한 공부노트

Tensor 이해하기 본문

Deep Learning

Tensor 이해하기

무지맘 2021. 8. 8. 14:48

딥러닝에서는 고차원 데이터를 많이 사용한다. 차원이 눈에 보이는 것이 아니라 상상하기도 어렵고 데이터를 다루기는 더 어려운데, 이것을 도와줄 패키지를 먼저 소개하겠다.

import numpy as np

바로 넘파이 numpy라는 것이다. 보통 np로 많이 줄여서 쓰기도 한다.

아래 그림을 한 번 보고, numpy를 이용해서 차원의 개념인 텐서 tensor를 하나씩 이해해보도록 하자.

0차원 1차원 2차원 3차원
입체도형(cube)
스칼라 scalar 벡터 vector 매트릭스 matrix 텐서 tensor

[그림 001] 그림판 잘 못쓰는 사람이 최대한 표현해본 텐서

4차원 5차원 6차원
3차원 점으로 이루어진 선 4차원 선으로 이루어진 면 5차원 면으로 이루어진 입체도형
vector of cube matrix of cube cube of cube

참고 - 매트릭스에서 가로 한 줄을 행(row), 세로 한 줄을 열(column)이라고 한다. 그래서 가로 한 줄 벡터를 행 벡터, 세로 한 줄 벡터를 열 벡터라고 부른다. 보통 딥러닝에서의 벡터는 열 벡터를 가리킨다.


0차원 - Scalar


0차원은 1, 2와 같이 데이터 1개만 있는 차원을 말한다. 도형으로 치면 점이다.

arr0 = np.array(5)
arr0
>>
array(5)

numpy array를 이용해서 5라는 숫자를 array화(배열화)해서 arr0에 할당했다. 그 결과로 만들어진 것은 5라는 숫자가 있는 배열이다.

 

arr0.shape
>>
()

shape은 각 차원의 크기를 튜플로 나타내 준다. 0차원은 크기라고 할 게 없으므로 아무것도 표시하지 않는다.

 

arr0.ndim
>>
0

ndim은 해당 배열의 차원 수를 알려준다. 0차원이니 0을 반환한다.


1차원 - Vector


대괄호 [ ]로 1번 묶을 때마다 차원이 1개씩 더 생기게 된다. 1차원은 [ ]가 1개인 것을 말한다. 도형으로 치면 점이 모여 만들어지는 선에 해당한다.

arr1 = np.array([5])
arr1
>>
array([5])

[5]라는 배열을 만들어서 arr1에 할당했다.

 

arr1.shape
>>
(1,)

크기가 1인 벡터라는 뜻이다. 1행짜리 열 벡터라는 말과 같다. 다음 예시를 보면 더 와닿을 수 있다.

 

arr11 = np.array([1,2,3])
arr11.shape
>>
(3,)

arr11도 벡터인데 이 친구의 shape은 (3, )이 나왔다. 이것은 3행짜리 열 벡터라는 것을 알려준다. 콤마 , 뒤의 숫자가 생략된 이유는 1차원은 열 벡터이기 때문에 굳이 열을 쓸 이유가 없기 때문이다. 2차원부터는 숫자가 명시된다.

 

arr1.ndim
>>
1

arr11.ndim
>>
1

arr1과 arr11 모두 1차원인 것을 확인할 수 있다.


2차원 - Matrix


2차원은 [ ]가 2개인 것을 말한다. 도형으로 치면 선이 모여 만들어지는 면에 해당한다.

arr2 = np.array([[1,2,3]])
arr2.shape
>>
(1, 3)

arr2.size
>>
3

(1, 3)이라는 것은 1행 3열 매트릭스라는 것을 뜻한다. size가 3이라는 것은 원소의 총 개수가 1 * 3 = 3개라는 것이다.

 

arr22 = np.array([[1,2],[1,2],[1,2]])
arr22.shape
>>
(3, 2)

arr22는 3행 2열짜리 매트릭스이다. 

 

arr2.ndim
>>
2

arr22.ndim
>>
2

len(arr2.shape)
>>
2

arr2와 arr22 모두 2차원임을 확인할 수 있다. shape를 len함수에 넣어도 몇차원인지 확인이 가능하다.

 

지금까지 arr0, arr1, arr11, arr2, arr22를 보면서 shape이 왜 이렇게 나왔는지 잘 와닿지 않은 사람그게바로나을 위해 미흡한 그림판 실력으로 설명해주면 다음과 같다.

[그림 007] 0~2차원 배열 그림

덧붙이기 1 - arr0과 arr1의 차이는 대괄호밖에 없냐고 생각할 수 있다. 하지만 매우 큰 차이가 숨어있다. arr0이 종이 아무 데나 찍은 점이라면, arr1은 수직선에 찍은 점이라는 것이다. 수직선에 찍었다는 것은 위치가 생긴다는 것이고, 이는 위치벡터로 표현이 가능하다는 것에서 그냥 찍은 점과 아주 많은 차이가 나타난다. 벡터에 대해서는 기하를 배우면..

 

덧붙이기 2 - arr11과 arr2를 비교해보면, arr11은 1차원 열 벡터이고, arr2는 1차원 행 벡터 같은데 2차원으로 분류되어있다. 이는 앞에서 잠깐 언급했지만, 여기서 말하는 벡터는 열 벡터를 의미하므로 행 벡터는 2차원으로 표현될 수밖에 없기 때문이다. 꼭 행 벡터로 나타내야 할 것이 아니라면, 가급적이면 열 벡터로 표현하는 습관을 들이면 좋을 것 같다.


3차원 이상의 다차원 - Tensor


0~2차원도 텐서이지만, 보통 텐서라고 하면 3차원 이상의 다차원을 의미한다.

본문 시작 전에 위에서 그림과 표를 이용해 설명할 때, 3차원을 입체도형(보통 정육면체 cube로 생각)이라 하면 4차원은 cube로 이루어진 벡터, 5차원은 cube로 이루어진 매트릭스, 6차원은 cube로 이루어진 cube라고 설명했다. 즉 스칼라가 cube로 바뀐 것뿐, 벡터, 매트릭스라는 큰 틀은 변하지 않았다. 이렇게 생각해보면 7차원은 6차원으로 이루어진 벡터, 8차원은 6차원으로 이루어진 매트릭스라고 생각하면 될듯하다.

 

그럼 이제 다차원이 코드로 표현될 때는 어떻게 되는지 보겠다. 첫 번째로 볼 것은 3차원이다.

arr3 = np.array([[[1],[2],[3]],[[1],[2],[3]],[[1],[2],[3]]])
arr3.shape
>>
(3, 3, 1)

arr3.ndim
>>
3

첫 줄에서 대괄호가 3겹이고, ndim의 결과를 보니 3차원은 맞는 거 같은데, shape을 어떻게 읽어야 할까? 다른 3차원을 보면서 추측해보자.

arr33 = np.array([[[1,1],[2,2],[3,3]],[[1,1],[2,2],[3,3]],[[1,1],[2,2],[3,3]]])
arr33.shape
>>
(3, 3, 2)

arr33.ndim
>>
3

arr3에서 스칼라 1개씩을 더 추가해서 만든 배열이다. 위의 것과 비교해봤을 때 shape을 어떻게 받아들이면 좋을지 생각해보고 아래 그림을 확인해보자.

..

[그림 008] 나만 이해가 안되는 것 같아 그려본 3차원 배열

arr3은 3행짜리 열 벡터 구조인데, 각 원소가 3행 1열짜리 매트릭스인 것이고, arr33도 마찬가지로 3행짜리 열 벡터 구조인데 각 원소가 3행 2열짜리 매트릭스인 걸로 생각하면 다차원을 이해하는 데 도움이 될 것 같다.

 

그럼 이제 4차원을 보자.

arr4 = np.array([[[[1,2,3],[1,2,3],[1,2,3]],[[1,2,3],[1,2,3],[1,2,3]]],[[[1,2,3],[1,2,3],[1,2,3]],[[1,2,3],[1,2,3],[1,2,3]]]])
arr4.shape
>>
(2, 2, 3, 3)

arr4.ndim
>>
4

3차원까지는 어떻게든 봤는데, 4차원은 엄청 복잡하게 생겼다. 조금 더 쉽게 이해해보기 위해 또 그림을 그려보았다.

[그림 009] 이쯤되면 날 위해 그리는것 같은 4차원 배열 그림

arr4는 2행 2열 매트릭스 구조인데, 각 원소가 3행 3열 매트릭스인 4차원 배열이다.


지금까지 텐서에 대해서 심하다(?)싶을 정도로 자세하게 살펴보았다. 앞으로 딥러닝을 공부하면서 많은 도움이 됐으면 하는 바람이다. 헷갈리는 것이 있다면 차원을 하나씩 만들어보고 내용을 바꿔가면서 익숙해질 때까지 들여다보는 것을 추천한다. 왜냐면 앞으로는 shape확인을 계속하면서 코딩을 하게 되기 때문이다. 저도 아직도 한 번씩 헷갈려요