일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- regression
- 회귀
- gpt
- 분류
- 딥러닝
- 오블완
- PCA
- GPT-4
- OpenAI
- ChatGPT
- supervised learning
- 해커톤
- LG Aimers
- LG Aimers 4th
- Machine Learning
- 티스토리챌린지
- Classification
- AI
- 지도학습
- deep learning
- LLM
- 머신러닝
- LG
- Today
- Total
SYDev
Chapter 02-2: 신경망을 위한 데이터 표현 본문
Chapter 02-2: 신경망을 위한 데이터 표현
시데브 2023. 7. 23. 14:47- 텐서(tensor): 데이터를 위한 컨테이너(container)
- 텐서는 임의의 차원 개수를 가지는 행렬의 일반화된 모습
- 랭크(rank): 텐서의 축 개수
스칼라(0D 텐서)
- 스칼라(scalar): 하나의 숫자만 담고 있는 텐서
- 스칼라 텐서, 0차원 텐서, 0D텐서
- Numpy에서 스칼라 텐서 -> float32나 float64 타입 숫자
>>> import numpy as np
>>> x = np.array(12)
>>> x
array(12) #숫자 요소가 하나 -> 0dim
>>> x.ndim
0
벡터(1D 텐서)
- 벡터(vector): 숫자의 배열
- 1D 텐서
>>> x = np.array([12, 3, 6, 14, 7])
>>> x
array([12, 3, 6, 14, 7]) #5개의 원소를 가지므로 5차원 벡터
>>> x.ndim
1
+ 5D 벡터 vs 5D 텐서 -> 5D 벡터는 한 축을 따라 원소가 5개, 5D 텐서는 5개의 축을 가짐
+ 이런 상황에서는 5D 텐서를 랭크 5인 텐서(rank는 텐서의 축)라고 말하는 것이 기술적으로 정확
행렬(2D 텐서)
- 행렬(matrix): 벡터의 배열
- 2D 텐서
>>> x = np.array([[5, 78, 2, 34, 0],
[6, 79, 3, 35, 1],
[7, 80, 4, 36, 2]])
>>> x.ndim
2
- 1행: [5, 78, 2, 34, 0], 1열: [5, 6, 7]
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.ndim
3
- 3D 텐서들을 하나의 배열로 합치면 4D 텐서
- 딥러닝에서는 보통 0D~4D 텐서 다룸
- 동영상 데이터 다룰 경우 -> 5D 텐서까지
핵심 속성
텐서의 핵심 속성 3가지
- 축의 개수(랭크)
- 크기(shape): 텐서의 각 축을 따라 얼마나 많은 차원이 있는지를 나타낸 파이썬의 튜플(tuple, 셀 수 있는 수량의 순서 있는 열거)
위 예시 중에서 벡터의 크기 (5,), 행렬의 크기 (3, 5), 3D 텐서의 크기 (3, 3, 5) + 배열 스칼라는 크기 X
- 데이터 타입: 텐서에 포함된 데이터의 타입(ex. float32, uint8, float64 등등... char 타입도 드물게 사용하지만 텐서는 사전에 할당되어 연속된 메모리에 저장되어야 하므로 넘파이 배열은 가변 길이의 문자열 지원 x)
MNIST 예제에서 사용한 데이터의 속성을 알아보자.
>>> from keras.datasets import mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
>>> print(train_images.ndim)
3 #축의 개수
>>> print(train_images.shape)
(60000, 28, 28) #배열의 크기
>>> print(train_images.dtype)
uint8 #데이터 타입
이로써 훈련 이미지 배열은 8비트 정수형 3D 텐서(28X28 크기의 정수 행렬 6만 개의 배열)임을 알 수 있다.
해당 3D 텐서의 5번째 이미지 출력
digit = train_images[4]
import matplotlib.pyplot as plt
plt.imshow(digit, cmap=plt.cm.binary)
plt.show()
넘파이로 텐서 조작하기
- 슬라이싱(slicing): 배열에 있는 특정 원소들을 선택하는 것
train_images의 11번째에서 100번째까지 숫자를 선택하여 (90, 28, 28) 크기의 배열을 만드는 예시
>>> my_slice = train_images[10:100]
>>> print(my_slice.shape)
(90, 28, 28)
:은 전체 인덱스를 선택
>>> my_slice = train_images[10:100, :, :]
>>> my_slice = train_images[10:100, 28:28, 28:28]
둘 다결과는 위와 동일하다.
이미지 오른쪽 아래 14X14 픽셀
>>> my_slice = train_images[:, 14:, 14:]
정중앙에 위치한 14X14 픽셀을 잘라낸 이미지
>>> my_slice = train_images[:, 7:-7, 7:-7]
+ 음수 인덱스는 축의 끝에서부터 순서를 나타낸다. 고로 해당 이미지는 1~7, 21~27 범위의 이미지 데이터이다.
배치 데이터
- 딥러닝 모델은 한 번에 전체 데이터셋을 처리하지 않으며, 데이터를 작은 배치(batch)로 나눈다.
MNIST 숫자 데이터에서 크기가 128인 배치 하나는 다음과 같으며, 그 다음 배치로 넘어가면서 다음 형태를 보인다.
batch = train_images[:128] #첫 배치
batch = train_images[128:256] #그 다음 배치
batch = train_images[128 * n:128 *(n + 1)] #n번째 배치
- 배치 축(batch axis) 또는 배치 차원(batch dimension): 첫 번째 축(0번 축)
텐서의 실제 사례
모든 데이터 텐서의 첫 번째 축은 샘플 축(sample axis)
- 벡터 데이터: (samples, features) 크기의 2D 텐서
- 시계열 데이터 or 시퀀스(sequence) 데이터: (samples, timesteps, features) 크기의 3D 텐서
- 이미지: (samples, height, width, channels) or (samples, channels, height, width) 크기의 4D 텐서
- 동영상: (samples, frames, height, width, channels) or (samples, frames, channels, height, width) 크기의 5D 텐서
벡터 데이터
- 대부분의 경우에 해당됨
- 첫 번째 축은 샘플 축, 두 번째 축은 특성 축(feature axis)
- 사람의 나이, 우편 번호, 소득으로 구성된 인구 통계 데이터. 각 사람은 3개의 값을 가진 벡터로 구성되고 10만 명이 포함된 전체 데이터셋은 (100000, 3)크기의 텐서로 저장 -> 100000명의 사람들은 각각 3개의 벡터를 가짐
- 500개의 각 문서에 20000개의 원소를 포함하고있는 전체 데이터셋은 (500, 20000) 크기의 텐서로 저장 -> 500개의 각 문서는 20000개의 벡터를 가짐
시계열 데이터 또는 시퀀스 데이터
- 데이터에서 시간 (혹은 연속된 순서가) 필요할 때, 시간 축을 포함한 3D 텐서 저장
- 관례적으로 시간 축은 항상 두 번째 축(index 1)
- 주식 가격 데이터셋: 1분마다 현재 주식 가격, 지난 1분 동안의 최고 가격과 최소 가격을 저장. 1분마다 데이터는 3D 벡터로 인코딩되고 하루 동안의 거래는 (390, 3) 크기의 2D 텐서로 인코딩(하루의 거래 시간 390분). 250일치의 데이터는 (250, 390, 3) 크기의 3D 텐서로 저장됨.
- 트윈 데이터셋: 각 트윗은 128개의 알파벳으로 구성된 280개의 문자 시퀀스. 여기서 각 문자가 128개의 크기인 이진 벡터로 인코딩될 수 있음(해당 문자의 인덱스만 1이고 나머지는 모두 0인 벡터, 원-핫 벡터). 각 트윗은 (280, 128) 크기의 2D 텐서로 인코딩될 수 있음. 100만 개의 트윗으로 구성된 데이터셋은 (1000000, 280, 128) 크기의 텐서에 저장
이미지 데이터
- 이미지는 전형적으로 높이, 너비, 컬러 채널의 3차원으로 이뤄짐
- 흑백 이미지(컬러 채널의 차원 크기 1)는 하나의 컬러 채널만 가지고 있어 2D 텐서로도 저장될 수 있지만 관례상 이미지 데이터는 항상 3D 텐서로 저장
- 256X256 크기의 흑백 이미지에 대한 128개의 배치는 (128, 256, 256, 1) 크기의 텐서에 저장, 컬러 이미지의 경우 (128, 256, 256, 3)
- 채널 마지막(channel-last) 방식: (samples, height, width, color_depth) -> 구글의 텐서플로 머신 러닝 프레임 워크
- 채널 우선(channel-first) 방식: (samples, color_depth, height, width) -> 씨아노
- 케라스 프레임 워크는 두 형식 모두 지원
비디오 데이터
- 하나의 비디오는 프레임의 연속, 각 프레임은 하나의 컬러 이미지
- 프레임이 (height, width, color_depth)의 3D 텐서로 저장 가능
- 프레임의 연속은 (frames, height, width, color_depth)의 4D 텐서로 저장 가능
- 여러 비디오의 배치는 (samples, frames, height, width, color_depth)의 5D 텐서로 저장 가능
- 60초짜리 144X256 유튜브 비디오 클립을 초당 4프레임으로 샘플링하면 240 프레임, 이런 비디오 클립을 4개 가진 배치는 (4, 240, 144, 256, 3) 크기의 텐서에 저장됨
- 해당 데이터는 106,168,320개의 값이 존재. 이 텐서의 dtype이 float32일 시에는 각 값이 32비트로 저장되어 텐서의 저장 크기는 405MB로 매우 큼.
- 실생활에서 접하는 비디오는 float32 크기로 저장되지 않기 때문에 용량이 훨씬 적고, 일반저긍로 높은 압축률로 압축됨(MPEG 포맷 같은 방식)
참고자료
- 프랑소와 숄레, <케라스 창시자에게 배우는 딥러닝>, (주)도서출판 길벗, 2018.10.22
'Machine Learning, Deep Learning > 케라스 창시자에게 배우는 딥러닝' 카테고리의 다른 글
Chapter 02-1 : 신경망과의 첫 만남 (0) | 2023.07.22 |
---|---|
MLDL Chapter 01-1 : 딥러닝의 기초 (0) | 2023.07.19 |