계산그래프 Computation Graph
Python으로 효율적인 수치 연산을 하기 위해, 보통 행렬곱 등의 비싼 연산을 Python 외부에서 처리하는 NumPy등의 라이브러리들을 사용하는데, NumPy등은 다른 언어로 구현된 매우 효율적 인 코드를 이용합니다. 불행히도, 모든 op에서 Python으로 도로 스위칭하는 과정에서 아주 큰 오버헤드가 여전히 발생됩니다. 이러한 오버헤드는 GPU를 이용하거나 분산 처리할 경우에 매우 커서 데이터전송에 비용이 많이 소요될 수 있습니다.
To do efficient numerical computing in Python, we typically use
libraries like NumPy that do expensive operations such as matrix multiplication
outside Python, using highly efficient code implemented in another language.
Unfortunately, there can still be a lot of overhead from switching back to
Python every operation. This overhead is especially bad if you want to run
computations on GPUs or in a distributed manner, where there can be a high cost
to transferring data.
TensorFlow는 또한 Python 외부에서 무거운 작업들을 실행하지만, 이러한 오버헤드를 피하기 위해 한 단계 더 일을 합니다. 대형 단일 op를 Python과 독립적으로 실행하는 대신, TensorFlow 는 완전히 Python 밖에서 실행되는 상호작용하는 ops의 그래프를 기술하게 합니다. 이 방법은 Theano나 Torch에서 사용되는 것과 유사합니다.
TensorFlow also does its heavy lifting outside Python, but it
takes things a step further to avoid this overhead. Instead of running a single
expensive operation independently from Python, TensorFlow lets us describe a
graph of interacting operations that run entirely outside Python. This approach
is similar to that used in Theano or Torch.
따라서 Python코드의 역할은 이러한
외부 계산그래프를 만들고, 계산그래프의 어떤
부분이 실행 되어야
하는지 명령하는 것입니다. 보다 상세한 내용은 기본 사용(Basic Usage)의 계산그래프에서 확인하세요.
The role of the Python code is therefore to build this external computation
graph, and to dictate which parts of the computation graph should be run. See
the Computation Graph section of Basic Usage for more detail.
소프트맥스 회귀 모델 만들기 Build a Softmax Regression Model
이 장에서는 1개의 선형 층(single linear layer)으로 된 소프트맥스 회귀 모델을 만듭니다. 다음 장에서, 이 모델을 다층 합성곱 네트워크(multilayer convolutional
network)로 된 소프트맥스 회귀로 확장합니다.
In this section we will build a softmax regression model with a
single linear layer. In the next section, we will extend this to the case of
softmax regression with a multilayer convolutional network.
Placeholders
입력 이미지와 목표 출력 클래스용 노드를 만드는 것으로 계산그래프 작성을 시작 합니다.
We start building the computation graph by creating nodes for the
input images and target output classes.
x =
tf.placeholder(tf.float32, shape=[None, 784])
y_ = tf.placeholder(tf.float32, shape=[None, 10])
x 와 y_는 특별히 정해진 값이 아닙니다. x 와 y_는 TensorFlow에게 계산 실행을 요구할 때 입력할 값들인, 각각의 placeholder 입니다.
Here x
and y_
aren't specific values. Rather,
they are each a placeholder
-- a value that we'll input when we ask TensorFlow to run a
computation.
입력 이미지 x는 부동소수(floating point numbers)인 2d 텐서로 구성됩니다. x의 형상 은 [None, 784]인데, None은 첫째 차원(dimension)이 뱃치 크기에 따라 어떤 크기도 될 수 있음을 가리키며, 784는 평탄화된 단일 MNIST이미지의 차원수(dimensionality) 입니다. 목표 출력(target output) 클래스 y_도 2d 텐서로 구성되는데, 여기서 각 행은 상응하는 MNIST이미지가 어떤 숫자 클래스에 속하는지를 나타내는 one-hot 10차원의 벡터입니다.
The input images x
will consist of a 2d tensor of floating point numbers. Here we
assign it a shape
of [None, 784]
, where 784
is the dimensionality of a
single flattened MNIST image, and None
indicates that the first dimension, corresponding to the batch
size, can be of any size. The target output classes y_
will also consist of a 2d
tensor, where each row is a one-hot 10-dimensional vector indicating which
digit class the corresponding MNIST image belongs to.
Placeholder의 형상 아규먼트는 선택사항이지만, TensorFlow는 이 아규먼트로 일관성 없는 텐서 형상에서 생기는 버그를 자동으로 잡을 수 있습니다.
The shape
argument to placeholder
is optional, but it allows TensorFlow to automatically catch bugs
stemming from inconsistent tensor shapes.
Variables
이제 모델의 가중치W와 편향값b를 정의합니다. 이들 가중치와 편향값을 추가 입력 (additional inputs) 처럼 처리할 수도 있지만, 이 보다 나은 처리방식은 TensorFlow에 있는 변수입니다. 변수는 TensorFlow의 계산그래프 안에 있는 값 입니다. 계산할 때 변수를 사용 또는 수정할 수 있습니다. ML애플리케이션에서, 모델 매개변수는 일반적 으로 변수입니다.
We now define the weights W
and biases b
for our model. We could imagine
treating these like additional inputs, but TensorFlow has an even better way to
handle them: Variable
. A Variable
is a value that lives in
TensorFlow's computation graph. It can be used and even modified by the
computation. In machine learning applications, one generally has the model
parameters be Variable
s.
W =
tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
tf.Variable 호출에서 각 매개변수에 초기 값(initial value)을 전달합니다. 이 경우, W와 b를 0으로 채워진 tensor들로 초기화 합니다. W는 784x10행렬이며(784개의 입력 특성(이미지의 픽셀수)과
10개의 출력을 갖고 있으므로), b는 10-차원의 벡터 입니다(10개의 클래스를 갖고 있으므로).
We pass the initial value for each parameter in the call to tf.Variable
. In this case, we initialize both W
and b
as tensors full of zeros. W
is a 784x10 matrix (because we
have 784 input features and 10 outputs) and b
is a 10-dimensional vector (because we have 10 classes).
세션 안에서 변수를 사용하기 전에, 해당 세션을 사용하여 변수를 반드시 초기화해야 합니다. 이 단계에서는 이미 지정된 초기값(이 경우 0으로 채워진 텐서)을 사용하는데, 각 변수에 초기 값을 할당 합니다. 이 과정은 모든 변수에 대하여 한 번 수행될 수 있습니다.
Before Variable
s can be used within a session, they must be initialized using
that session. This step takes the initial values (in this case tensors full of
zeros) that have already been specified, and assigns them to each Variable
. This can be done for all Variables
at once.
sess.run(tf.initialize_all_variables())
예측 클래스 및 비용함수 Predicted Class and Cost Function
이제 회귀모델을 만들 수 있습니다. 딱 1줄이면 됩니다! 벡터화된 입력 이미지 x와 가중치 행렬 W을 곱하고, 편향값 b를 더한 다음, 각 클래스에 할당되는 소프트맥스 확률을 계산합니다.
We can now implement our regression model. It only takes one line!
We multiply the vectorized input images x
by the weight matrix W
, add the bias b
, and compute the softmax probabilities that are assigned to each
class.
y = tf.nn.softmax(tf.matmul(x,W) + b)
훈련을 통해 최소화시킬 비용함수는 쉽게 정할 수 있습니다. 비용함수는 목표와 모델 예측 간의 교차-엔트로피(cross-entropy) 입니다.
The cost function to be minimized during training can be specified
just as easily. Our cost function will be the cross-entropy between the target
and the model's prediction.
cross_entropy = -tf.reduce_sum(y_*tf.log(y))
tf.reduce_sum는 모든 클래스는 물론 미니뱃치의 모든 이미지들에 걸쳐 더합니다. 전체 미니뱃치의 교차 엔트로피를 계산하는 것입니다.
Note that tf.reduce_sum
sums across all images in the minibatch, as well as all classes.
We are computing the cross entropy for the entire minibatch.
모델 훈련시키기 Train the Model
이제
모델과 훈련용 비용함수를
정의했고,
TensorFlow를 사용한 훈련은
간단합니다.
TensorFlow가 전체 계산그래프를 알고
있으므로, 자동미분을 사용하여
각 변수별 비용의
기울기를 찾습니다. TensorFlow에는 다양한 내장 최적화 알고리즘들이
있습니다. 이 예제
는 교차 엔트로피를 줄이기
위해 가파른내리막기울기(steepest
gradient descent)를 0.01 의 보폭(step
length)으로 사용합니다.
Now that we have defined our model and training cost function, it is
straightforward to train using TensorFlow. Because TensorFlow knows the entire
computation graph, it can use automatic differentiation to find the gradients
of the cost with respect to each of the variables. TensorFlow has a variety of builtin optimization
algorithms. For this example, we will use steepest
gradient descent, with a step length of 0.01, to descend the cross entropy.
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)
이 줄에서 TensorFlow가 실제 한 일은 계산그래프에 새로운 op를 추가한 것 뿐입니다. 이들 op 는 기울기 계산, 매개변수의 갱신보폭 계산, 갱신된 보폭의 매개변수에 대한 반영입니다.
What TensorFlow actually did in that single
line was to add new operations to the computation graph. These operations
included ones to compute gradients, compute parameter update steps, and apply
update steps to the parameters.
가동되면 리턴된 op인 train_step이 매개변수에 내리막기울기 업데이트를 반영합니다. 이렇게 train_step을 반복 실행하여 모델을 훈련시킵니다.
The returned operation train_step, when run,
will apply the gradient descent updates to the parameters. Training the model
can therefore be accomplished by repeatedly running train_step.
for i in range(1000):
batch = mnist.train.next_batch(50)
train_step.run(feed_dict={x: batch[0],
y_: batch[1]})
반복되는 각 훈련 마다 훈련예제 50개를 불러옵니다. 그런 다음 feed_dict를 사용하여 placeholder 텐서 x 와 y_를 훈련예제로 바꾸는 train_step op를 실행합니다. feed_dict를 사용하여 placeholder 뿐만 아니라, 계산그래프 내의 어떠한 텐서도 대체할 수 있습니다.
Each training iteration we load 50 training
examples. We then run the train_step operation, using feed_dict to replace the
placeholder tensors x and y_ with the training examples. Note that you can
replace any tensor in your computation graph using feed_dict -- it's not
restricted to just placeholders.
'TensorFlow' 카테고리의 다른 글
윈도우에 TensorFlow 설치하고 MNIST 다운로드 하기 (0) | 2016.04.28 |
---|---|
Deep MNIST (3) (0) | 2016.04.27 |
전문가용 Deep MNIST(1) (0) | 2016.04.27 |
Feeds (13) (0) | 2016.03.31 |
Fetch (12) (0) | 2016.03.31 |
댓글