In [ ]:
#@title Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도 불구하고 공식 영문 문서의 내용과 일치하지 않을 수 있습니다. 이 번역에 개선할 부분이 있다면 tensorflow/docs-l10n 깃헙 저장소로 풀 리퀘스트를 보내주시기 바랍니다. 문서 번역이나 리뷰에 참여하려면 docs-ko@tensorflow.org로 메일을 보내주시기 바랍니다.
이전 튜토리얼에서는 머신러닝을 위한 기본 구성 요소인 자동 미분(automatic differentiation)을 위한 텐서플로 API를 알아보았습니다. 이번 튜토리얼에서는 이전 튜토리얼에서 소개되었던 텐서플로의 기본 요소를 사용하여 간단한 머신러닝을 수행해보겠습니다.
텐서플로는 반복되는 코드를 줄이기 위해 유용한 추상화를 제공하는 고수준 신경망(neural network) API인 tf.keras를 포함하고 있습니다. 신경망을 다룰 때 이러한 고수준의 API을 강하게 추천합니다. 이번 짧은 튜토리얼에서는 탄탄한 기초를 기르기 위해 기본적인 요소만으로 신경망 훈련시켜 보겠습니다.
In [ ]:
import tensorflow as tf
In [ ]:
# 파이썬 구문 사용
x = tf.zeros([10, 10])
x += 2 # 이것은 x = x + 2와 같으며, x의 초기값을 변경하지 않습니다.
print(x)
텐서플로는 상태를 변경할 수 있는 연산자가 내장되어 있으며, 이러한 연산자는 상태를 표현하기 위한 저수준 파이썬 표현보다 사용하기가 더 좋습니다. 예를 들어, 모델에서 가중치를 나타내기 위해서 텐서플로 변수를 사용하는 것이 편하고 효율적입니다.
텐서플로 변수는 값을 저장하는 객체로 텐서플로 연산에 사용될 때 저장된 이 값을 읽어올 것입니다. tf.assign_sub, tf.scatter_update 등은 텐서플로 변수에 저장되있는 값을 조작하는 연산자입니다.
In [ ]:
v = tf.Variable(1.0)
assert v.numpy() == 1.0
# 값을 재배열합니다.
v.assign(3.0)
assert v.numpy() == 3.0
# tf.square()와 같은 텐서플로 연산에 `v`를 사용하고 재할당합니다.
v.assign(tf.square(v))
assert v.numpy() == 9.0
변수를 사용한 연산은 그래디언트가 계산될 때 자동적으로 추적됩니다. 임베딩(embedding)을 나타내는 변수의 경우 기본적으로 희소 텐서(sparse tensor)를 사용하여 업데이트됩니다. 이는 연산과 메모리에 더욱 효율적입니다.
또한 변수를 사용하는 것은 코드를 읽는 독자에게 상태가 변경될 수 있다는 것을 알려주는 손쉬운 방법입니다.
지금까지 간단한 모델을 구축하고 학습시키기 위해 ---Tensor, GradientTape, Variable --- 와 같은 몇가지 개념을 설명했습니다. 이는 일반적으로 다음의 과정을 포함합니다.
이번 튜토리얼에서는 선형 모델의 간단한 예제를 살펴보겠습니다:
f(x) = x * W + b, 모델은 W 와 b 두 변수를 가지고 있는 선형모델이며, 잘 학습된 모델이 W = 3.0 and b = 2.0의 값을 갖도록 합성 데이터를 만들겠습니다.
In [ ]:
class Model(object):
def __init__(self):
# 변수를 (5.0, 0.0)으로 초기화 합니다.
# 실제로는 임의의 값으로 초기화 되어야합니다.
self.W = tf.Variable(5.0)
self.b = tf.Variable(0.0)
def __call__(self, x):
return self.W * x + self.b
model = Model()
assert model(3.0).numpy() == 15.0
In [ ]:
def loss(predicted_y, desired_y):
return tf.reduce_mean(tf.square(predicted_y - desired_y))
In [ ]:
TRUE_W = 3.0
TRUE_b = 2.0
NUM_EXAMPLES = 1000
inputs = tf.random.normal(shape=[NUM_EXAMPLES])
noise = tf.random.normal(shape=[NUM_EXAMPLES])
outputs = inputs * TRUE_W + TRUE_b + noise
모델을 훈련시키기 전에, 모델의 현재 상태를 시각화합시다. 모델의 예측을 빨간색으로, 훈련 데이터를 파란색으로 구성합니다.
In [ ]:
import matplotlib.pyplot as plt
plt.scatter(inputs, outputs, c='b')
plt.scatter(inputs, model(inputs), c='r')
plt.show()
print('현재 손실: '),
print(loss(model(inputs), outputs).numpy())
이제 네트워크와 훈련 데이터가 준비되었습니다. 모델의 변수(W 와 b)를 업데이트하기 위해 훈련 데이터를 사용하여 훈련시켜 보죠. 그리고 경사 하강법(gradient descent)을 사용하여 손실을 감소시킵니다. 경사 하강법에는 여러가지 방법이 있으며, tf.train.Optimizer 에 구현되어있습니다. 이러한 구현을 사용하는 것을 강력히 추천드립니다. 그러나 이번 튜토리얼에서는 기본적인 방법을 사용하겠습니다.
In [ ]:
def train(model, inputs, outputs, learning_rate):
with tf.GradientTape() as t:
current_loss = loss(model(inputs), outputs)
dW, db = t.gradient(current_loss, [model.W, model.b])
model.W.assign_sub(learning_rate * dW)
model.b.assign_sub(learning_rate * db)
마지막으로, 훈련 데이터를 반복적으로 실행하고, W 와 b의 변화 과정을 확인합니다.
In [ ]:
model = Model()
# 도식화를 위해 W값과 b값의 변화를 저장합니다.
Ws, bs = [], []
epochs = range(10)
for epoch in epochs:
Ws.append(model.W.numpy())
bs.append(model.b.numpy())
current_loss = loss(model(inputs), outputs)
train(model, inputs, outputs, learning_rate=0.1)
print('에포크 %2d: W=%1.2f b=%1.2f, 손실=%2.5f' %
(epoch, Ws[-1], bs[-1], current_loss))
# 저장된 값들을 도식화합니다.
plt.plot(epochs, Ws, 'r',
epochs, bs, 'b')
plt.plot([TRUE_W] * len(epochs), 'r--',
[TRUE_b] * len(epochs), 'b--')
plt.legend(['W', 'b', 'true W', 'true_b'])
plt.show()