Machine Learning/TensorFlow

[Machine Learning] TensorFlow Basic

데이터 세상 2021. 2. 26. 20:15
728x90
반응형

TensorFlow

  • 데이터 흐름 그래프(Data Flow Graph)를 사용하여 수치 연산을 하는 오픈소스 라이브러리
  • 그래프의 node는 수치 연산을 나타내고 edge는 노드 사이를 이동하는 다차원 데이터 배열(tensor)를 나타낸다
  • 머신러닝과 딥 뉴럴 네트워크 연구를 목적으로 구글의 인공지능 연구 조직인 구글 브레인 팀에서 개발

Tensor

  • 딥러닝에서 데이터를 표현하려는 방식을 Tensor(텐서)라고 함
  • 텐서는 행렬로 표현할 수 있는 2차원 형태의 배열을 높은 차원으로 확장한 다차원 배열을 말함
  • Tensor = Multidimensional Arrays = Data

과학과 공학 등 다양한 분야에서 이전부터 쓰이던 개념

수학에서는 임의의 기하 구조를 좌표 독립적으로 표현하기 위한 표기법으로 알려져 있음

 

Dataflow Graph

  • 수학 계산과 데이터의 흐름을 node와  edge를 사용한 방향 그래프로 표현
  • 각 node들을 독립변수로 지정하여 학습
  • Tensor 형태의 데이터들이 딥러닝 모델을 구성하는 연산들의 그래프(Data flow graph)을 따라 연산이 일어나도록 하는 것
  • Node
    • 수학적 계산, 데이터 입/출력, 데이터의 읽기/저장 등의 작업을 수행
  • Edge
    • node들 간 데이터의 입/출력 관계를 나타냄
    • 동적 사이즈의 다차원 데이터 배열(Tensor)를 실어 나르는데, 여기에서 TensorFlow 이름이 지어짐

 

TensorFlow 2.x 

  • 사용의 편의성
    • 기존 1.x에서는 tf.contrib, tf.keras, tf.layer 등 많은 estimator를 사용하여 모델을 만들었으나 이는 사용자의 혼란 가중
    • 동일한 기능의 다양한 API를 하나로 통합하고, 잘 사용하지 않는 다양한 API 제거
  • Eager Execution
    • 기존 1.x에서는 그래프 작성 / 동작을 위한 세션 작성으로 나누어 구성
    • 기존 실행 방식은 텐서플로 API를 이용해 그래프를 만든 후 별도로 세션을 통해 해당 그래프를 실행하는 방식
    • 2.0부터는 파이썬과 동일한 Eager mode로 실행되기 때문에 연산을 구성하면서 바로 값 확인 가능
  • 쉬운 모델 구축 및 개발
    • TensorFlow 2.x에서는 TensorFlow Keras API를 통해 모델을 쉽고 유연하게 만들 수 있으며 tf.function을 사용하여 오토그래프 기능을 사용할 수 있음

TensorFlow 구성요소

Variables

  • 변경이 가능한 매개 변수
  • y = W * x + b 라는 y 노드를 구성했을 때 x가 입력 데이터라면 W와 b는 학습을 통해서 구해야 하는 값
  • 이를 변수라고 하며 변수형은 Variable 형의 객체로 생성된다.
  • tf.Variable(
        initial_value
    =None, trainable=None, validate_shape=True, caching_device=None,
        name
    =None, variable_def=None, dtype=None, import_scope=None, constraint=None,
        synchronization
    =tf.VariableSynchronization.AUTO,
        aggregation
    =tf.compat.v1.VariableAggregation.NONE, shape=None
    )
  • Variable()에 전달할 초기값을 상수나 램던으로 초기화
    • tf.zeros(shape, dtype=tf.float32, name=None)
    • tf.zeros_like(tensor, dtype=None, name=None)
    • tf.ones(shape, dtype=tf.float32, name=None)
    • tf.ones_like(tensor, dtype=None, name=None)
    • tf.fill(dims, value, name=None)
    • tf.constant(value, dtype=None, shape=None, name='Const')
    • tf.linspace(start, stop, num, name=None)
    • tf.range(start, limit=None, delta=1, name='range')
    • tf.random_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)
    • tf.truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)
    • tf.random_uniform(shape, minval=0, maxval=None, dtype=tf.float32, seed=None, name=None)
    • tf.random_shuffle(value, seed=None, name=None)
    • tf.set_random_seed(seed)
import tensorflow as tf

vdata1 = tf.Variable(1.0)
print(vdata1)

vdata2 = tf.Variable(tf.ones((2,)))
print(vdata2)
print(vdata2.numpy())

vdata2 = tf.Variable(tf.ones([2,1]))
print(vdata2)
print(vdata2.numpy())
vdata2.assign(tf.zeros((2,1)))
print(vdata2.numpy())
vdata2.assign_add(tf.ones((2,1)))
print(vdata2.numpy())

>>
<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=1.0>
<tf.Variable 'Variable:0' shape=(2,) dtype=float32, numpy=array([1., 1.], dtype=float32)>
[1. 1.]
<tf.Variable 'Variable:0' shape=(2, 1) dtype=float32, numpy=
array([[1.],
       [1.]], dtype=float32)>
[[1.]
 [1.]]
[[0.]
 [0.]]
[[1.]
 [1.]]

Placeholders

  • 외부 그래프로 데이터를 공급받는 빈 node라고 생각할 수 있음
  • TensorFlow 2에서는 placeholder와 계산 그래프를 명시적으로 사용하지 않고 선언적으로 계산 과정을 구현

Constants

  • 변하지 않는 매개 변수
  • tf.constant(value, dtype=None, shape=None, name='Const', verify_shape=False)
    • value: 상수 값
    • dtype: 상수의 데이터형
    • shape: 행렬의 차원, shape=[3, 3]은 3x3 행렬
    • name: 상수의 이름
    • verify_shape: tensor shape를 바꿀 수 있게 해주는 bool 값
# constant의 실제 값을 확인하기 위해서는 numpy() 이용
import tensorflow as tf

a = tf.constant([1,2,3], dtype=tf.float32)
print('a:', a.numpy())
>>
a: [1. 2. 3.]

b = tf.constant([[1,2,3],[4,5,6]], dtype=tf.float32)
print('b:', b.numpy())
>>
b: [[1. 2. 3.]
 [4. 5. 6.]]

Operations

  • Tensors에서 계산을 수행하는 그래프의 node

Graph Session

  • TensorFlow의 Operations를 실행

TensorFlow Data Type

Tensor data type 설명
tf.float32 32비트 부동소수점
tf.float64 64비트 부동소수점
tf.int8 8비트 정수
tf.int16 16비트 정수
tf.int32 32비트 정수
tf.int64 64비트 정수
tf.uint8 8비트 부호 없는 정수
tf.uint16 16비트 부호 없는 정수
tf.string 가변 길이 바이트 배열
tf.bool 참 거짓 값
tf.complex64 2개의 32비트 부동소수점 숫자로 구성된 복소수
tf.complex128 2개의 64비트 부동소수점 숫자로 구성된 복소수

TensorFlow 연산자

  • 텐서플로우에서 텐서 객체끼리의 연산은 기본 연산자를 이용하여 사용
  • 텐서플로우에서는 기본 연산을 위한 연산자 함수들이 기술되어 있음
operator Tensor operator description
x + y tf.add() x와 y의 요소간 덧셈
x - y tf.subtract() x와 y의 요소간 뺄셈
x * y tf.multiply() x와 y의 요소간 곱셈
x / y tf.div() x와 y의 요소간 나눗셈
x // y tf.floordiv() x와 y의 요소간 나눈셈 몫
x % y tf.mod() x와 y의 요소간 나눗셈 나머지
x ** y tf.pow() x와 y의 요소간 지수승
x < y tf.less() x < y
x <= y tf.less_equal() x <= y
x > y tf.greater() x > y
x >= y tf.greater_equal() x >= y
x & y tf.logical_and() x & y
x | y tf.logical_or() x | y
x ^ y tf.logical_xor() x ^ y
import tensorflow as tf

a = tf.range(6, dtype=tf.int32)
b = tf.ones(6, dtype=tf.int32) * 2
print(tf.add(a,b).numpy())
print((a+b).numpy())
print((-b).numpy())

>>
[2 3 4 5 6 7]
[2 3 4 5 6 7]
[-2 -2 -2 -2 -2 -2]
"""
사칙 연산 프로그램
((5 * 3) - (3 + 2))
"""

import tensorflow as tf

# 상수 선언
x1 = tf.constant(5)
x2 = tf.constant(3)
x3 = tf.constant(2)

# 연산
result = tf.subtract(tf.multiply(x1, x2), tf.add(x2, x3))
print("result={}".format(result))

>> 
result=10

 

vs TensorFlow 1.x 연산

  • Node의 연산 인스턴스가 생성
  • 생성된 연산 인스턴스들은 그래프가 실행이 안되면 연산 값을 반환하지 않음
  • TensorFlow는 모든 구성요소가 담긴 그래프의 골격을 먼저 만들도록 설계
  • 세션이 실행되면 그래프에 Tensor가 입력되고 연산 수행

==> TensorFlow1.x: 그래프 기반 vs TensorFlow2.x:즉시 모드

import tensorflow as tf

x_data = np.random.randn(5, 10)

x = tf.placeholder(tf.float32, shape=(5, 10))
w = tf.Variable(np.random.randn(10,1), dtype=tf.float32)
b = tf.fill((5, 1), -1.)

xw = tf.matmul(x, w)
xwb = xw + b
s = tf.reduce_max(xwb)
with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())
  outs = sess.run(s, feed_dict={x: x_data})
print("outs = {}".format(outs))

 

다차원 데이터

텐서플로는 Numpy의 다차원 배열과 유사한 텐서 프레임워크를 제공

  • Numpy의 다차원 배열과 텐서플로의 텐서와의 차이
  • 텐서플로는 GPU와 TPU 같은 하드웨어 가속기를 사용할 수 있음
  • 텐서플로는 임의의 미분 가능 텐서 표현의 gradient를 자동으로 계산
  • 텐서플로 계산은 단일 머신에 있는 여러 개의 장치나 머신에 분산할 수 있음
명칭 설명
Scalar 하나의 숫자만을 저장하고 있는 텐서
Vector 숫자를 가진 1차원 배열
다차원 배열과 마찬가지로 하나의 축(열)을 가짐
Matrix 1차원 텐서를 원소로 하는 텐서로 벡터의 배열 또는 행렬이라고도 함
다차원 배열과 마찬가지로 2개의 축(행과 열)을 가짐
Tensor n차원 텐서
n차원 이상의 텐서는 이를 지칭할 용어가 없어 그냥 n차원 텐서라고 함
ex) 3차원 텐서
2차원 텐서를 원소로 하는 텐서

import tensorflow as tf

### scalar
scalar_A = tf.constant(1)
scalar_B = tf.constant(1)
add_scalar_AB = scalar_A + scalar_B

## 1-dim
vector_A = tf.constant([1, 2, 3])
vector_B = tf.constant([3, 5, 7])
add_vector_AB = vector_A + vector_B

## 2-dim
matrix_A = tf.constant([[1, 2],[3, 4]])
matrix_B = tf.constant([[4, 3],[2, 1]])
matrix_AB = tf.matmul(matrix_A, matrix_B)

>>
shape of scala_A : ()
shape of scala_B : ()
shape of add_scalar_AB : ()
shape of vector_A : (3,)
shape of vector_B : (3,)
shape of add_vector_AB : (3,)
shape of matrix_A : (2, 2)
shape of matrix_B : (2, 2)
shape of matrix_AB : (2, 2)

 

"""
Tensorflow 다차원 데이터 연산
 |2 2 4|   |4 3 3|   |16 16 50|
 |1 1 6| * |2 1 6| = |12 16 57|
 |1 3 7|   |1 2 8|   |18 22 85|
"""

import tensorflow as tf

## 매트릭스 연산 작성하기.
A = tf.constant([ [2, 2, 4],
                  [1, 1, 6],
                  [1, 3, 8] ])
B = tf.constant([ [4, 3, 3],
                  [2, 1, 6],
                  [1, 2, 8] ])
AB = tf.matmul(A, B)

print("result = {}".format(AB))

>> 
result = [[16 16 50]
 [12 16 57]
 [18 22 85]]

텐서 생성 시, 파이썬이 제공하는 다양한 타입을 저장할 수 있음

텐서는 범용 컨테이너가 아닌 수치 연산 전용 컨테이너이므로 서로 다른 타입이 전달될 경우

데이터의 손실이 없는 연산 가능한 공통의 타입으로 암시적 변환이 이루어짐

import tensorflow as tf

x = tf.constrant([10, 3.14, True])
print(x)
>> tf.Tensor([10. 3.14 1. ], shape=(3,), dtype=float32)

수치 데이터로 변환할 수 없는 데이터가 포함될 경우 오류가 발생

import tensorflow as tf

x = tf.constrant([10, 3.14, True, "hello"])
print(x)
>> ValueError

텐서 생성시, 원소의 타입을 명시적으로 지정 가능

import tensorflow as tf

x = tf.constrant([1,2,3,4], dtype=tf.float32)
print(x)
>> tf.Tensor([1,2,3,4], shape=(4,), dtype=float32)

Reference

728x90
반응형