AIFFEL에서 우지철님의 자료를 공부한 내용입니다.
Tensorflow V2의 이전버전 대비 차별화된 장점
TensorFlow2 API
TensorFlow2에서 딥러닝 모델을 작성하는 방법에는 Sequential, Functional, 그리고 Model Subclassing 3가지가 존재합니다.
Sequential Model
import tensorflow as tf
from tensorflow import keras
model = keras.Sequential()
model.add(__넣고싶은 레이어__)
model.add(__넣고싶은 레이어__)
model.add(__넣고싶은 레이어__)
model.fit(x, y, epochs=10, batch_size=32)
입력부터 출력까지 레이어를 그야말로 sequential하게 차곡차곡 add해서 쌓아나가기만 하면 됩니다.
모델의 입력과 출력이 여러 개인 경우에는 적합하지 않은 모델링 방식입니다. Sequential 모델은 반드시 입력 1가지, 출력 1가지를 전제로 합니다.
Functional API
import tensorflow as tf
from tensorflow import keras
inputs = keras.Input(shape=(__원하는 입력값 모양__))
x = keras.layers.__넣고싶은 레이어__(관련 파라미터)(input)
x = keras.layers.__넣고싶은 레이어__(관련 파라미터)(x)
outputs = keras.layers.__넣고싶은 레이어__(관련 파라미터)(x)
model = keras.Model(inputs=inputs, outputs=outputs)
model.fit(x,y, epochs=10, batch_size=32)
함수형으로 모델을 구성한다는 것은 입력과 출력을 규정함으로써 모델 전체를 규정한다는 것입니다. 그래서 이번에는 Input이라는 것을 규정합니다. Input이 될 수 있는 텐서가 여러개가 될 수 도 있습니다.
Functional API를 통해 다중입력/출력을 가지는 모델을 구성할 수 있습니다.
Subclassing
import tensorflow as tf
from tensorflow import keras
class CustomModel(keras.Model):
def __init__(self):
super(CustomModel, self).__init__()
self.__정의하고자 하는 레이어__()
self.__정의하고자 하는 레이어__()
self.__정의하고자 하는 레이어__()
def call(self, x):
x = self.__정의하고자 하는 레이어__(x)
x = self.__정의하고자 하는 레이어__(x)
x = self.__정의하고자 하는 레이어__(x)
return x
model = CustomModel()
model.fit(x,y, epochs=10, batch_size=32)tf.GradientTape는 위와 같이 순전파(forward pass) 로 진행된 모든 연산의 중간 레이어값을 tape에 기록하고, 이를 이용해 gradient를 계산한 후 tape를 폐기하는 기능을 수행합니다.
keras.Model은 위와 같이 init()이라는 메소드 안에서 레이어 구성을 정의합니다. 그리고 call()이라는 메소드 안에서 레이어간 forward propagation을 구현합니다.
tf.GradientTape()
tf.GradientTape는 forward pass로 진행된 모든 연산의 중간 레이어값을 tape에 기록하고, 이를 이용해 gradient를 계산한 후 tape를 폐기하는 기능을 수행합니다.
loss_func = tf.keras.losses.SparseCategoricalCrossentropy()
optimizer = tf.keras.optimizers.Adam()
def train_step(features, labels):
with tf.GradientTape() as tape:
predictions = model(features)
loss = loss_func(labels, predictions)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
return loss
def train_model(batch_size=32):
start = time.time()
for epoch in range(5):
x_batch = []
y_batch = []
for step, (x, y) in enumerate(zip(x_train, y_train)):
if step % batch_size == batch_size-1:
x_batch.append(x)
y_batch.append(y)
loss = train_step(np.array(x_batch), np.array(y_batch))
x_batch = []
y_batch = []
print('Epoch %d: last batch loss = %.4f' % (epoch, float(loss)))
print("It took {} seconds".format(time.time() - start))
train_model()