Tensorflow란?
이제 설치는 끝났고 tensorflow에 대해서 조금 알아보자
tensorflow는 일단 기본적으로 오픈소스 라이브러리이다. 머신러닝과 딥러닝에 대한 함수들이 내장되있다고 보면된다.
머신러닝? 딥러닝 무슨 차이?
사실 구글에 검색을 해봤는데도 여러가지 입장과 측면이 있는 것 같다.
내가 보기에는 머신러닝은 말그대로 기계가 학습을하도록 하는 알고리즘을 짜는 것이다. 그 목적은 입력데이터의 특정부분을 추출 해서 그 부분을 학습하고 원하는 출력데이터를 얻는데 있다.
딥러닝은 위에서 얘기한 추출 마저 스스로하게 만드는 것이다. 그래서 딥러닝을 end to end machine learning이라고 부르기도 한다.
결국 가장 큰 차이점은 추출하는 알고리즘의 유무 정도라고 해야될까...?
잘 몰라서 머신러닝을 공부하는 형한테 물어봤는데 머신러닝의 한 갈래중 뉴럴넷에서 히든레이어가 많아진게 딥러닝이라고 한다. 히든레이어는 학습을 담당하는 부분이다. 단순히 특징을 추출한 input feature가 많다고해서 딥러닝은 아니라고 한다. 대충 여러가지 학습이 가능한 것이 딥러닝인 것 같기도 하다.
기본용어
- Tensor : 모든 데이터를 텐서라고 부른다. 일종의 다차원 배열
- Node : 수학적 계산, 데이터 입/출력, 그리고 데이터의 읽기/저장 등의 작업을 수행하는 녀석이다.
- Edge : 엣지는 노드들 간 데이터의 입출력 관계를 의미한다.
- Operation : 하나이상의 텐서를 입력받고 계산(연산)을 수행하고 결과를 하나 이상으로 텐서로 반환하는 것
- Session : Operation의 실행환경을 캡슐화한 것
- Variable : 그래프의 실행시, 파라미터를 저장하고 갱신해주는 역할
Tesorflow 기본 예제
import tensorflow as tf
import numpy as np
# 데이터를 랜덤하게 세팅하는 주는 부분
x_data = np.float32(np.random.rand(2, 200))
# 목표값 설정하는 단계
y_data = np.dot([0.100000, 0.500000], x_data) + 0.300
# 실제 학습되어서 목표값에 찾아가는 변수
b = tf.Variable(tf.zeros([1]))
# W는 1x2 형태의 웨이트 변수 (균등 랜덤값으로 초기화) 첫번째 초기값 세팅임
W = tf.Variable(tf.random_uniform([1, 2], -100.0, 100.0))
# 학습시킬 데이터 모델
y = tf.matmul(W, x_data) + b
# 손실에 대한 학습 함수 정의
loss = tf.reduce_mean(tf.square(y - y_data))
# 경사하강법으로 학습하면서 발생하는 변화량 최소화 (0.5는 학습 비율)
# 값이 1에 가까이 갈수록 1회 학습당 값의 변동폭 커짐
# 값이 0에 가까이 갈수록 1회 학습당 값의 변동폭 작아짐
optimizer = tf.train.GradientDescentOptimizer(0.5)
# 학습 오퍼레이션 정의
train = optimizer.minimize(loss)
# 모든 변수를 초기화.
init = tf.initialize_all_variables()
# 세션 시작
sess = tf.Session()
sess.run(init)
# 200번 학습.
for step in range(0, 200):
sess.run(train)
if step % 10 == 0:
print( step, sess.run(W), sess.run(b) )
일단 코드는 이렇다. 왜 이런지에 대해서 조금씩 알아보자.
초보자관점의 코드 분석ㅋ
np.dot()
Numpy라는 라이브러리인데 과학적 계산을 위해 필요한 핵심 라이브러리라고한다. dot(v:np.array ,w:np.array)은 매트릭스 곱셈 연산이다. 우리가 알고잇는 행렬곱샘 연산을 잘 만들어놓은 것으로 추정된다.
np.float32()
return값이 float32 부호 비트, 8 비트 지수, 23 비트 가수 일종의 형변환정도로 생각된다.
np.random.rand(a,b)
리턴값이 ab값중 랜덤하게 나오게 하는 것 같다.200사이에서 랜덤하게 추출해서 x_data에 대입하겠다는 걸 의미한다.x_data = np.float32(np.random.rand(2, 200))
이 코드는 float32타입의 변수를 2y_data = np.dot([0.100000, 0.500000], x_data) + 0.300
이 코드는 [0.100000, 0.500000]이라는 np.array타입을 x_data와 행렬곱셈을 시킨후 + 0.3을 하고 그값을 y_data에 대입하겠다 는 걸 의미한다
//TODO : 역시 여기서 0.300이 왜 결과값의 꼴에 영향을 주는지 이해가 안간다.
tf.Variable()
이 함수를 통해서 리턴되는 값은 run()호출을 통해 그래프에 있는 상태를 유지하는 것으로 본다. 즉 학습을 통해 변해가는 변수라고 볼 수 있는 것 같다.
tf.zeros([1])
tf.zeros([3, 4], tf.int32) ==> [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
이렇게 보는 것이 제일 이해가 쉬울 것 같다.
b = tf.Variable(tf.zeros([1]))
는 1*1 타입의 데이터에 0을 집어넣고 그래프에 올리는 용도로 쓰는 변수로 세팅하겠다.
tf.random_uniform([a,b],minimum,maximum)
대충봐도 슬슬 딱 감이온다. a*b행렬에 minimum ~ maximum 사이의 값 중 랜덤으로 값을 세팅하는 것 같다.
W = tf.Variable(tf.random_uniform([1, 2], -100.0, 100.0))
W라는 변수는 1*2행렬이며 -100~100사이의 값이 세팅되고 그래프에 올리는 용도로 사용되는 것 같다.
tf.matmul(W, x_data)
# 2-D tensor `a`
a = tf.constant([1, 2, 3, 4, 5, 6], shape=[2, 3]) => [[1. 2. 3.]
[4. 5. 6.]]
# 2-D tensor `b`
b = tf.constant([7, 8, 9, 10, 11, 12], shape=[3, 2]) => [[7. 8.]
[9. 10.]
[11. 12.]]
c = tf.matmul(a, b) => [[58 64]
[139 154]]
위 코드를 보는 것이 가장 이해가 빠를 것 같다. tensorflow 라이브러리에서 행렬 곱을 하는 함수.
loss = tf.reduce_mean(tf.square(y - y_data)) //TODO: 좀 더 알아볼 필요가있다.
reduce_mean(
input_tensor,
axis=None,
keep_dims=False,
name=None,
reduction_indices=None
)
api에 있는 reduce_mean()의 기본 모델이다. 일단 파라미터가 input_tensor이고 나머지 파라미터는 다 default값인 것 같다.
공식 api에 있는 함수설명 :
Computes the mean of elements across dimensions of a tensor.
Reduces input_tensor along the dimensions given in axis. Unless keep_dims is true, the rank of the tensor is reduced by 1 for each entry in axis. If keep_dims is true, the reduced dimensions are retained with length 1.
If axis has no entries, all dimensions are reduced, and a tensor with a single element is returned.
뭐라는지 잘 모르겠지만 텐서의 평균을 반환하는 녀석이다. 단 keep_dims의 값이 true이면 차원이 1로 감소하는 것이고 false이면 차원이 각 엔트리마다 1씩 감소한다는데... 아직 무슨 뜻인지 파악이 잘 안된다.
# 'x' is [[1., 1.]
# [2., 2.]]
tf.reduce_mean(x) ==> 1.5
tf.reduce_mean(x, 0) ==> [1.5, 1.5]
tf.reduce_mean(x, 1) ==> [1., 2.]
단 위 예제를 봤을 때 어느정도 유추해볼 수 있는 사실은 default일 경우 각 배열의 평균값을 단일로 반환
0이면 같은 각 배열의 원소들의 평균을 배열로 반환 1인경우는 짐작이 안간다...
tf.square(x)
return x^2
종합해보면 초기 설정한 값 y_data 에 텐서인 y를 뺀 차이의 제곱을 loss라는 변수에 저장한다가 되겠다.
optimizer = tf.train.GradientDescentOptimizer(0.5)
일단 api에 검색했을 때는 GradientDescentOptimizer 이 녀석은 클래스이다. 지금 불러온 이 메소드는 일종의 생성자라고 봐도 무방하다.
__init__(
learning_rate,
use_locking=False,
name='GradientDescent'
)
해당 클래스의 생성자인데 첫번째 파라미터는 학습율을 의미한다.
학습율에 관해서 다른 데이터를 몇번 넣어봤는데
- 값이 1에 가까이 갈수록 1회 학습당(반복마다) 값의 변동폭 커짐
- 값이 0에 가까이 갈수록 1회 학습당(반복마다) 값의 변동폭 작아짐
왜 0.5가 최적의 값인지, 과연 최적인지, 반복횟수와 연관성에 관한 것은 도저히 나로서는 알 수 가 없다.는게 내 결론...
train = optimizer.minimize(loss)
api : Add operations to minimize loss by updating var_list.
var_list를 업데이트하여 손실을 최소화하는 작업을 추가한다. 어떻게 코드가 짜여져있는지는 모르겠지만 손실을 최소화시키는 녀석인듯 하다.
init = tf.initialize_all_variables()
# 세션 시작
sess = tf.Session()
sess.run(init)
그 이후로는 tensoflow로 동작하는 녀석들을 초기화 시키고 세션을 통해서 진행하는 걸로 추측할 수 있다.
막상 코드를 보니까 단순하게 생각하면 목표값과 입력값의 차이의 제곱을 계속 최소화시키게 반복하면서 목표값에 근접해 가는 것이 기본 예제의 핵심인 것을 알 수 있다.
'Tensorflow' 카테고리의 다른 글
00. MacOS에 Tensorflow 설치하기 (0) | 2017.10.01 |
---|