딥러닝 소개 - 텐서플로 기본
Page content
강의 홍보
- 취준생을 위한 강의를 제작하였습니다.
- 본 블로그를 통해서 강의를 수강하신 분은 게시글 제목과 링크를 수강하여 인프런 메시지를 통해 보내주시기를 바랍니다.
스타벅스 아이스 아메리카노를 선물
로 보내드리겠습니다.
- [비전공자 대환영] 제로베이스도 쉽게 입문하는 파이썬 데이터 분석 - 캐글입문기
공지
-
본 Tutorial은 교재
핸즈온 머신러닝 2판
를 활용하여 본 강사로부터 국비교육 강의를 듣는 사람들에게 자료 제공을 목적으로 제작하였습니다. -
강사의 주관적인 판단으로 압축해서 자료를 정리하였기 때문에, 자세하게 공부를 하고 싶은 분은 반드시 교재를 구매하실 것을 권해드립니다.
책 정말 좋습니다! 꼭 구매하세요!
개요
- 인경 신경망은(
Artificial Neural Network
)을 촉발시킨 근원임- 뇌에 있는 생물학적 뉴런의 네트워크에서 영감을 받은 머신러닝 모델
- 활용예제
- 수백만개의 이미지 분류
- 수백만개의 비디어 추천
- 매우 복잡한 문제를 풀 때 유용한 머신러닝 모델
- Keras API
- 케라스는 신경망 구축, 훈련, 평가, 실행을 목적으로 설계된 API이자, 프레임워크
(1) 주요 환경 설정
- 주요 환경 설정은 아래와 같이 정의합니다.
# 파이썬 ≥3.5 필수
import sys
assert sys.version_info >= (3, 5)
# 사이킷런 ≥0.20 필수
import sklearn
assert sklearn.__version__ >= "0.20"
# 텐서플로 ≥2.0 필수
import tensorflow as tf
assert tf.__version__ >= "2.0"
from tensorflow import keras
# 공통 모듈 임포트
import numpy as np
import pandas as pd
import os
# 노트북 실행 결과를 동일하게 유지하기 위해
np.random.seed(42)
# 깔끔한 그래프 출력을 위해
%matplotlib inline
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rc('axes', labelsize=14)
mpl.rc('xtick', labelsize=12)
mpl.rc('ytick', labelsize=12)
# 그림을 저장할 위치
PROJECT_ROOT_DIR = "."
CHAPTER_ID = "ann"
IMAGES_PATH = os.path.join(PROJECT_ROOT_DIR, "images", CHAPTER_ID)
os.makedirs(IMAGES_PATH, exist_ok=True)
def save_fig(fig_id, tight_layout=True, fig_extension="png", resolution=300):
path = os.path.join(IMAGES_PATH, fig_id + "." + fig_extension)
print("그림 저장:", fig_id)
if tight_layout:
plt.tight_layout()
plt.savefig(path, format=fig_extension, dpi=resolution)
# 불필요한 경고를 무시합니다 (사이파이 이슈 #5998 참조)
import warnings
warnings.filterwarnings(action="ignore", message="^internal gelsd")
I. 텐서플로의 전체적인 개요
- 지금까지는 케라스를 활용한 인공신경망의 개요에 대해 확인하였다.
- 딥러닝 작업의
95%
는tf.keras
외에 다른 것은 필요하지 않다. - 그러나, 텐서플로를 조금 더 자세히 들여다 본다.
II. 텐서플로의 역사 및 기능 개요
- 텐서플로는 2015년 11월 오픈 소스로 공개
- 그 전에 구글 포토, 구글 검색, 구글 클라우드 스피치에서 이미 사용됨
- 텐서플로를 활용하여 이미지 분류, 자연어 처리, 추천 시스템, 시계열 예측 등과 같은 머신러닝 작업을 수행
- 그 외 딥러닝 프레임워크에 관한 비교글은 다음 글 참조
(1) 텐서플로의 주요 기능
- NumPy와 비슷하지만,
GPU
지원- 병렬처리 가능 및 연산속도 향상
- 분산 컴퓨팅 지원
- JIT 컴파일러 포함, 메모리 사용량을 줄이기 위해 계산 최적화
- 텐서플로 API의 주요 기능은 다음 그림 참조
- 가장 저수준의 텐서플로 연산은 매우 효율적인
C++
코드로 구현되어 있음
(2) 텐서플로의 그 외 기능
- 윈도우, 리눅스, 맥OS, iOS, 안드로이드에서 사용 가능
- C++, 자바, Go, 스위프트 API에서도 사용 가능
- 텐서보드 (시각화), 텐서플로 제품화를 위한 TFX
III. 텐서플로 사용
- 텐서플로의 기초적인 사용법에 대해 다시 확인한다.
- 텐서는 한 연산에서 다른 연상르ㅗ 흐름
- 텐서는 넘파이의
ndarray
와 비슷 - 다차원 배열
(1) 텐서와 연산
- 두 개의 행과 세계의 열을 가진 실수 행렬을 만든다.
tf.constant([[1., 2., 3.], [4., 5., 6.]]) # 행렬
<tf.Tensor: shape=(2, 3), dtype=float32, numpy=
array([[1., 2., 3.],
[4., 5., 6.]], dtype=float32)>
tf.constant(42) # 단순값 스칼라도 확인 가능
<tf.Tensor: shape=(), dtype=int32, numpy=42>
ndarray
와 마찬가지로tf.Tensor
는 크기와 데이터 타입(dtype)을 가진다.
t = tf.constant([[1., 2., 3.], [4., 5., 6.]])
print(t.shape)
print(t.dtype)
(2, 3)
<dtype: 'float32'>
- 인덱스 참조도 넘파이와 매우 비슷하게 작동함
t[:, 1:]
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[2., 3.],
[5., 6.]], dtype=float32)>
t[..., 1, tf.newaxis]
<tf.Tensor: shape=(2, 1), dtype=float32, numpy=
array([[2.],
[5.]], dtype=float32)>
- 모든 종류의 텐서 연산이 가능하다.
t+10
<tf.Tensor: shape=(2, 3), dtype=float32, numpy=
array([[11., 12., 13.],
[14., 15., 16.]], dtype=float32)>
tf.square(t)
<tf.Tensor: shape=(2, 3), dtype=float32, numpy=
array([[ 1., 4., 9.],
[16., 25., 36.]], dtype=float32)>
tf.transpose(t)
<tf.Tensor: shape=(3, 2), dtype=float32, numpy=
array([[1., 4.],
[2., 5.],
[3., 6.]], dtype=float32)>
t @ tf.transpose(t)
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[14., 32.],
[32., 77.]], dtype=float32)>
@
연산은 행렬 곱셈을 위해 파이썬3.5
에 추가된 것.- 위 행렬곱셈은 (2 x 3) x (3 x 2) = (2 x 2) 방식을 따른 것이다.
(2) 텐서와 넘파이
- 텐서는 넘파이와 함께 사용이 가능함
- 텐서와 넘파이는 서로 쉽게 변환이 가능함
a = np.array([2., 4., 5.])
tf.constant(a)
<tf.Tensor: shape=(3,), dtype=float64, numpy=array([2., 4., 5.])>
t.numpy()
array([[1., 2., 3.],
[4., 5., 6.]], dtype=float32)
tf.square(a)
<tf.Tensor: shape=(3,), dtype=float64, numpy=array([ 4., 16., 25.])>
np.square(t)
array([[ 1., 4., 9.],
[16., 25., 36.]], dtype=float32)
- 단 한가지 주의점이 있다.
- NumPy는 기본으로
64
비트 정밀도를 사용하지만, 텐서플로는32
비트 정밀도를 사용함. 따라서, 넘파이 배열로 텐서를 만들 때dtype=tf.float32
로 지정한다.
- NumPy는 기본으로
(3) 타입 변환
- 호환되지 않는 타입의 예를 확인한다.
- 먼저 정수텐서와 실수 텐서는 더할 수 없다.
tf.constant(2.) + tf.constant(40)
---------------------------------------------------------------------------
InvalidArgumentError Traceback (most recent call last)
<ipython-input-16-1026a7e18cf4> in <module>()
----> 1 tf.constant(2.) + tf.constant(40)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/math_ops.py in binary_op_wrapper(x, y)
982 with ops.name_scope(None, op_name, [x, y]) as name:
983 if isinstance(x, ops.Tensor) and isinstance(y, ops.Tensor):
--> 984 return func(x, y, name=name)
985 elif not isinstance(y, sparse_tensor.SparseTensor):
986 try:
/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/math_ops.py in _add_dispatch(x, y, name)
1274 return gen_math_ops.add(x, y, name=name)
1275 else:
-> 1276 return gen_math_ops.add_v2(x, y, name=name)
1277
1278
/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/gen_math_ops.py in add_v2(x, y, name)
478 pass # Add nodes to the TensorFlow graph.
479 except _core._NotOkStatusException as e:
--> 480 _ops.raise_from_not_ok_status(e, name)
481 # Add nodes to the TensorFlow graph.
482 _, _, _op, _outputs = _op_def_library._apply_op_helper(
/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/ops.py in raise_from_not_ok_status(e, name)
6651 message = e.message + (" name: " + name if name is not None else "")
6652 # pylint: disable=protected-access
-> 6653 six.raise_from(core._status_to_exception(e.code, message), None)
6654 # pylint: enable=protected-access
6655
/usr/local/lib/python3.6/dist-packages/six.py in raise_from(value, from_value)
InvalidArgumentError: cannot compute AddV2 as input #1(zero-based) was expected to be a float tensor but is a int32 tensor [Op:AddV2]
- 32비트 실수와 64비트 실수도 더할 수 없다.
tf.constant(2.) + tf.constant(40., dtype=tf.float64)
---------------------------------------------------------------------------
InvalidArgumentError Traceback (most recent call last)
<ipython-input-22-11603e4e2c5e> in <module>()
----> 1 tf.constant(2.) + tf.constant(40., dtype=tf.float64)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/math_ops.py in binary_op_wrapper(x, y)
982 with ops.name_scope(None, op_name, [x, y]) as name:
983 if isinstance(x, ops.Tensor) and isinstance(y, ops.Tensor):
--> 984 return func(x, y, name=name)
985 elif not isinstance(y, sparse_tensor.SparseTensor):
986 try:
/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/math_ops.py in _add_dispatch(x, y, name)
1274 return gen_math_ops.add(x, y, name=name)
1275 else:
-> 1276 return gen_math_ops.add_v2(x, y, name=name)
1277
1278
/usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/gen_math_ops.py in add_v2(x, y, name)
478 pass # Add nodes to the TensorFlow graph.
479 except _core._NotOkStatusException as e:
--> 480 _ops.raise_from_not_ok_status(e, name)
481 # Add nodes to the TensorFlow graph.
482 _, _, _op, _outputs = _op_def_library._apply_op_helper(
/usr/local/lib/python3.6/dist-packages/tensorflow/python/framework/ops.py in raise_from_not_ok_status(e, name)
6651 message = e.message + (" name: " + name if name is not None else "")
6652 # pylint: disable=protected-access
-> 6653 six.raise_from(core._status_to_exception(e.code, message), None)
6654 # pylint: enable=protected-access
6655
/usr/local/lib/python3.6/dist-packages/six.py in raise_from(value, from_value)
InvalidArgumentError: cannot compute AddV2 as input #1(zero-based) was expected to be a float tensor but is a double tensor [Op:AddV2]
- 만약 타입 변환이 필요할 경우에는
tf.cast()
함수를 사용한다.
t2 = tf.constant(40., dtype=tf.float64)
tf.constant(2.0) + tf.cast(t2, tf.float32)
<tf.Tensor: shape=(), dtype=float32, numpy=42.0>
(4) 변수
- 기본적으로
tf.tensor
는 변경 불가능함 - 즉, 텐서의 내용을 바꿀 수 없음.
- 이는, 역전파로 변경되어야 하는 신경망의 가중치를 구현할 수 없음
- 그래서, 필요한 것이
tf.Variable
임
tf_v = tf.Variable([[1., 2., 3.], [4., 5., 6.]])
tf_v
<tf.Variable 'Variable:0' shape=(2, 3) dtype=float32, numpy=
array([[1., 2., 3.],
[4., 5., 6.]], dtype=float32)>
- 이제 특정 또는 전체의 값을 변경한다.
tf_v[0, 1].assign(42)
<tf.Variable 'UnreadVariable' shape=(2, 3) dtype=float32, numpy=
array([[ 1., 42., 3.],
[ 4., 5., 6.]], dtype=float32)>
tf_v[0, 0:2].assign([3., 2.])
<tf.Variable 'UnreadVariable' shape=(2, 3) dtype=float32, numpy=
array([[3., 2., 3.],
[4., 5., 6.]], dtype=float32)>
- 변수를 직접 만드는 일은 매우 드물다.
(5) 그 외 다른 데이터 구조
- 그 외헤,
희소 텐서
,텐서 배열
,래그트 텐서
,문자열 텐서
,집합
,큐
등이 있는데, 교재 470 페이지를 참고한다.
IV. What’s Next
- 다음 시간에는 사용자 정의 모델과 훈련 알고리즘에 대해 실습을 진행하도록 한다.