케라스 창시자에게 배우는 딥러닝 2-2장

2020. 3. 14. 21:19Python/모두를 위한 딥러닝

신경망을 위한 데이터 표현

 

이전 예제에서는 tensor라 부르는 다차원 넘파이(numpy) 배열에 데이터를 저장하는 것 부터 시작했습니다.

최근의 모든 머신 러닝 시스템은 일반적으로 텐서를 기본 데이터 구조로 사용합니다.

구글의 텐서플로우(TensorFlow)의 이름도 여기서 따왔습니다.

 

 

tensor

데이터를 위한 컨데이너(container)입니다. 거의 항상 수치형 데이터를 다루므로 숫자를 위한 컨테이너입니다.

행렬은 2D 텐서입니다.

텐서는 임의의 차원 개수를 가지는 행렬의 일반화된 모습입니다.(텐서에서는 종종 '차원 == 축' 이라고 부릅니다.)

 


 

[2.2.1 스칼라 0D 텐서]

하나의 숫자만을 담고 있는 텐서를 스칼라(scalar)(또는 스칼라 텐서, 0차원 텐서, 0D 텐서)라고 부릅니다.

Numpy에서의 스칼라 텐서(배열 스칼라): float32, float64

 

ndim 속성을 사용하면 넘파이 배열의 축(차원) 개수를 확인할 수 있습니다.

스칼라 텐서의 축 개수는 0입니다.(ndim == 0)

텐서의 축 개수를 랭크(rank)라고도 부릅니다.

 

스칼라 텐서

import numpy as np

>>> x = np.array(12)	#numpy형 array 정의
>>> x
array(12)

>>> x.ndim	#numpy형 array 차원을 표현
0	#정수형 숫자 1개 == 0차원

- 스칼라 텐서는 하나의 숫자만을 가진 0차원 텐서이다.

 

 


 

[2.2.2 벡터(1D 텐서]

숫자의 배열을 벡터(vector) 또는 1D 텐서라고 부릅니다.

1D 텐서는 단 하나의 축(차원)을 가집니다.

 

벡터 텐서

>>> x = np.array([12, 3, 6, 14, 7])	#numpy형 array 생성(5D vector)
>>> x
array([12,  3,  6, 14,  7])

>>> x.ndim
1	#1차원

 

이 Vector는 5개의 원소를 가지고 있으므로 5D Vector라고 부릅니다. (5D Vector와 5D Tensor를 혼동하면 안됩니다.)

  • 5D Vector: 하나의 축을 따라 5개의 차원을 가진 것
  • 5D Tensor: 5개의 축을 가진 것

- 텐서의 각 축을 따라 여러개의 차원을 가진 벡터가 놓일 수 있습니다.

 

차원수(dimensionality)는 특정 축을 따라 놓인 원소의 개수(5D 벡터와 같은 경우)이거나 텐서의 축 개수(5D 텐서와 같은 경우)를 의미하므로 혼동하기 쉽습니다.

 

- 벡터 텐서는 1D 텐서 축에 여러개의 차원을 가진 벡터가 존재하는 1차원 텐서이다.

 

 


 

 

[2.2.3 행렬 (2D 텐서)]

벡터의 배열이 행렬(matrix) 또는 2D 텐서입니다.

행렬에는 축이 2개 있습니다.(row: 행, column: 열)

 

행렬 텐서

>>> x = np.array([[5, 78, 2, 34, 0],
                 [6, 79, 3, 35, 1],
                 [7, 80, 4, 36, 2]])	#벡터의 배열인 행렬(2D 텐서) 정의
>>> x
array([[ 5, 78,  2, 34,  0],
       [ 6, 79,  3, 35,  1],
       [ 7, 80,  4, 36,  2]])
       
>>> x.ndim
2	#벡터의 행렬은 2차원

 

- 행렬 텐서는 2D 텐서로 벡터의 배열이라고도 할 수 있는 2차원 텐서이다.

 

 


 

 

[2.2.4 3D 텐서와 고차원 텐서]

2.2.3에서와 같은 행렬들을 하나의 새로운 배열로 합치면 숫자가 채워진 직육면체 형태로 해석할 수 있는 3D 텐서가 만들어집니다.

 

3D 텐서

>>> x = np.array([[[5, 78, 2, 34, 0],
               [6, 79, 3, 35, 1],
               [7, 80, 4, 36, 2]],
              [[5, 78, 2, 34, 0],
               [6, 79, 3, 35, 1],
               [7, 80, 4, 36, 2]],
              [[5, 78, 2, 34, 0],
               [6, 79, 3, 35, 1],
               [7, 80, 4, 36, 2]]])
>>> x
array([[[ 5, 78,  2, 34,  0],
        [ 6, 79,  3, 35,  1],
        [ 7, 80,  4, 36,  2]],

       [[ 5, 78,  2, 34,  0],
        [ 6, 79,  3, 35,  1],
        [ 7, 80,  4, 36,  2]],

       [[ 5, 78,  2, 34,  0],
        [ 6, 79,  3, 35,  1],
        [ 7, 80,  4, 36,  2]]])
        
>>> x.ndim
3

 

위과 같은 3D 텐서들을 배열로 합치면 4D 텐서를 만드느 식으로 이어집니다.

딥러닝에서는 일반적으로 0D에서 4D까지의 텐서를 다룹니다.44ㄷㄷㄷㄷㄷㄷㄷㄷㄷㄷㄷ444444444444444444444444444444444ㄷ4

동영상 데이터를 다루는 경우에는 5D 텐서까지 가기도 합니다.

 

 


 

 

[2.2.5 핵심 속성]

  • 텐서의 핵심 속성 3가지
    1. 축의 개수(랭크)
      - 3D 텐서에는 3개의 축이 있고, 행렬에는 2개의 축이 있습니다.
      - numpy의 ndim 속성
    2. 크기(shape)
      - 텐서의 각 축을 따라 얼마나 많은 차원이 있는지를 나타내는 파이썬의 튜플(tuple)입니다.
      - 3D 텐서의 크기는 (3, 3, 5), 행렬의 크기는 (3, 5), 벡터의 크기는 (5, )와 같이 1개의 원소로 이루어진 튜플입니다.
      - 배열 스칼라는 ()처럼 크기가 없습니다.
    3. 데이터 타입(numpy: dtype)
      - 텐서에 포함된 데이터의 타입입니다.
      - 텐서의 타입은 float32, uint8, float64 등이 될 수 있으며 드물게 char 타입을 사용합니다.
      - 텐서는 사전에 할당되어 연속된 메모리에 저장되어야 합니다. 따라서 넘파이 배열은 가버길이의 문자열을 지원하지 않습니다.

 

텐서의 속성을 확인하기 위한 MNIST 예제

>>> from keras.datasets import mnist
>>> (train_images, train_labels), (test_images, test_labels) = mnist.load_data()

>>> print(train_images.ndim)	#ndim: 축의 개수 확인
3

>>> print(train_images.shape)	#shape: 배열의 크기
(60000, 28, 28)

>>> print(train_images.dtype)	#dtype: 데이터 타입 확인
uint8

이 배열은 8비트 정수형 3D 텐서로 좀 더 정확하게는 28x28 크기의 정수 행렬 6만개가 있는 배열로

각 행렬은 하나의 흑백 이미지이고, 행렬의 각 원소는 0~225사이의 값을 가집니다.

 

 

다섯 번째 샘플을 Matplotlib 라이브러리를 사용하여 이미지 출력

digit = train_images[4]


import matplotlib.pyplot as plt

plt.imshow(digit, cmap=plt.cm.binary)	#imshow: image 출력 함수
plt.show()	#실제 그림을 출력하는 함수

 

 


 

 

[2.2.6 Numpy로 텐서 조작하기]

 

 

슬라이싱(slicing) : 배열에 있는 특정 원소들을 선택하는 것

 

슬라이싱 연산