day 21 TF2 API

7 minute read

TF2 API

MNIST (1) Sequential API 활용

import tensorflow as tf
from tensorflow import keras
import numpy as np
# 데이터 구성부분
mnist = keras.datasets.mnist

(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

x_train=x_train[...,np.newaxis]
x_test=x_test[...,np.newaxis]

print(len(x_train), len(x_test))
60000 10000
# Sequential Model을 구성해주세요.
"""
Spec:
1. 32개의 채널을 가지고, 커널의 크기가 3, activation function이 relu인 Conv2D 레이어
2. 64개의 채널을 가지고, 커널의 크기가 3, activation function이 relu인 Conv2D 레이어
3. Flatten 레이어
4. 128개의 아웃풋 노드를 가지고, activation function이 relu인 Fully-Connected Layer(Dense)
5. 데이터셋의 클래스 개수에 맞는 아웃풋 노드를 가지고, activation function이 softmax인 Fully-Connected Layer(Dense)
"""

# 여기에 모델을 구성해주세요

model = keras.Sequential([
    keras.layers.Conv2D(32, 3, activation='relu'),
    keras.layers.Conv2D(64, 3, activation='relu'),
    keras.layers.Flatten(),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(10, activation='softmax')
])

# 모델 학습 설정

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)

model.evaluate(x_test,  y_test, verbose=2)
Epoch 1/5
1875/1875 [==============================] - 19s 8ms/step - loss: 0.2218 - accuracy: 0.9334
Epoch 2/5
1875/1875 [==============================] - 27s 15ms/step - loss: 0.0318 - accuracy: 0.9899
Epoch 3/5
1875/1875 [==============================] - 27s 15ms/step - loss: 0.0163 - accuracy: 0.9943
Epoch 4/5
1875/1875 [==============================] - 27s 15ms/step - loss: 0.0096 - accuracy: 0.9967
Epoch 5/5
1875/1875 [==============================] - 27s 15ms/step - loss: 0.0070 - accuracy: 0.9974
313/313 - 2s - loss: 0.0564 - accuracy: 0.9861





[0.056405652314424515, 0.9861000180244446]
# keras.Model을 구성해주세요.
"""
Spec:
0. (28X28X1) 차원으로 정의된 Input
1. 32개의 채널을 가지고, 커널의 크기가 3, activation function이 relu인 Conv2D 레이어
2. 64개의 채널을 가지고, 커널의 크기가 3, activation function이 relu인 Conv2D 레이어
3. Flatten 레이어
4. 128개의 아웃풋 노드를 가지고, activation function이 relu인 Fully-Connected Layer(Dense)
5. 데이터셋의 클래스 개수에 맞는 아웃풋 노드를 가지고, activation function이 softmax인 Fully-Connected Layer(Dense)
"""

inputs = keras.Input(shape=(28, 28, 1))

x = keras.layers.Conv2D(32, 3, activation='relu')(inputs)
x = keras.layers.Conv2D(64, 3, activation='relu')(x)
x = keras.layers.Flatten()(x)
x = keras.layers.Dense(128, activation='relu')(x)
predictions = keras.layers.Dense(10, activation='softmax')(x)

model = keras.Model(inputs=inputs, outputs=predictions)
# 모델 학습 설정

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)

model.evaluate(x_test,  y_test, verbose=2)
Epoch 1/5
1875/1875 [==============================] - 14s 7ms/step - loss: 0.2116 - accuracy: 0.9319
Epoch 2/5
1875/1875 [==============================] - 14s 7ms/step - loss: 0.0352 - accuracy: 0.9889
Epoch 3/5
1875/1875 [==============================] - 14s 7ms/step - loss: 0.0188 - accuracy: 0.9936
Epoch 4/5
1875/1875 [==============================] - 23s 12ms/step - loss: 0.0105 - accuracy: 0.9966
Epoch 5/5
1875/1875 [==============================] - 27s 15ms/step - loss: 0.0084 - accuracy: 0.9973
313/313 - 1s - loss: 0.0586 - accuracy: 0.9842





[0.05857326090335846, 0.9842000007629395]

The difference is not huge

# Subclassing을 활용한 Model을 구성해주세요.
"""
Spec:
0. keras.Model 을 상속받았으며, __init__()와 call() 메소드를 가진 모델 클래스
1. 32개의 채널을 가지고, 커널의 크기가 3, activation function이 relu인 Conv2D 레이어
2. 64개의 채널을 가지고, 커널의 크기가 3, activation function이 relu인 Conv2D 레이어
3. Flatten 레이어
4. 128개의 아웃풋 노드를 가지고, activation function이 relu인 Fully-Connected Layer(Dense)
5. 데이터셋의 클래스 개수에 맞는 아웃풋 노드를 가지고, activation function이 softmax인 Fully-Connected Layer(Dense)
6. call의 입력값이 모델의 Input, call의 리턴값이 모델의 Output
"""

class CustomModel(keras.Model):
    def __init__(self):
        super().__init__()
        self.conv1 = keras.layers.Conv2D(32, 3, activation='relu')
        self.conv2 = keras.layers.Conv2D(64, 3, activation='relu')
        self.flatten = keras.layers.Flatten()
        self.fc1 = keras.layers.Dense(128, activation='relu')
        self.fc2 = keras.layers.Dense(10, activation='softmax')
        
    def call(self, x):
        x = self.conv1(x)
        x = self.conv2(x)
        x = self.flatten(x)
        x = self.fc1(x)
        x = self.fc2(x)
        
        return x
        
model = CustomModel()
# 모델 학습 설정

model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)

model.evaluate(x_test,  y_test, verbose=2)
Epoch 1/5
1875/1875 [==============================] - 28s 15ms/step - loss: 0.2137 - accuracy: 0.9346
Epoch 2/5
1875/1875 [==============================] - 27s 15ms/step - loss: 0.0318 - accuracy: 0.9904
Epoch 3/5
1875/1875 [==============================] - 16s 8ms/step - loss: 0.0177 - accuracy: 0.9943
Epoch 4/5
1875/1875 [==============================] - 14s 7ms/step - loss: 0.0120 - accuracy: 0.9963
Epoch 5/5
1875/1875 [==============================] - 14s 7ms/step - loss: 0.0075 - accuracy: 0.9975
313/313 - 1s - loss: 0.0501 - accuracy: 0.9868





[0.05010931193828583, 0.9868000149726868]

The three methods give similar enough results

CIFAR-100 (1) Sequential API 활용

# 데이터 구성부분
cifar100 = keras.datasets.cifar100

(x_train, y_train), (x_test, y_test) = cifar100.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
print(len(x_train), len(x_test))
50000 10000
# Sequential Model을 구성해주세요.
"""
Spec:
1. 16개의 채널을 가지고, 커널의 크기가 3, activation function이 relu인 Conv2D 레이어
2. pool_size가 2인 MaxPool 레이어
3. 32개의 채널을 가지고, 커널의 크기가 3, activation function이 relu인 Conv2D 레이어
4. pool_size가 2인 MaxPool 레이어
5. 256개의 아웃풋 노드를 가지고, activation function이 relu인 Fully-Connected Layer(Dense)
6. 데이터셋의 클래스 개수에 맞는 아웃풋 노드를 가지고, activation function이 softmax인 Fully-Connected Layer(Dense)
"""


model = keras.Sequential([
    keras.layers.Conv2D(16, 3, activation='relu'),
    keras.layers.MaxPool2D((2,2)),
    keras.layers.Conv2D(32, 3, activation='relu'),
    keras.layers.MaxPool2D((2,2)),
    keras.layers.Flatten(),
    keras.layers.Dense(256, activation='relu'),
    keras.layers.Dense(100, activation='softmax')
])

# 모델 학습 설정


model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)

model.evaluate(x_test,  y_test, verbose=2)
Epoch 1/5
1563/1563 [==============================] - 9s 4ms/step - loss: 3.9950 - accuracy: 0.0952
Epoch 2/5
1563/1563 [==============================] - 5s 3ms/step - loss: 2.9680 - accuracy: 0.2689
Epoch 3/5
1563/1563 [==============================] - 5s 3ms/step - loss: 2.6077 - accuracy: 0.3430
Epoch 4/5
1563/1563 [==============================] - 5s 3ms/step - loss: 2.3564 - accuracy: 0.3965
Epoch 5/5
1563/1563 [==============================] - 5s 3ms/step - loss: 2.1720 - accuracy: 0.4347
313/313 - 1s - loss: 2.6143 - accuracy: 0.3585





[2.6143131256103516, 0.35850000381469727]
# Functional API를 활용한 Model을 구성해주세요.
"""
Spec:
0. (32X32X3) 차원으로 정의된 Input
1. 16개의 채널을 가지고, 커널의 크기가 3, activation function이 relu인 Conv2D 레이어
2. pool_size가 2인 MaxPool 레이어
3. 32개의 채널을 가지고, 커널의 크기가 3, activation function이 relu인 Conv2D 레이어
4. pool_size가 2인 MaxPool 레이어
5. 256개의 아웃풋 노드를 가지고, activation function이 relu인 Fully-Connected Layer(Dense)
6. 데이터셋의 클래스 개수에 맞는 아웃풋 노드를 가지고, activation function이 softmax인 Fully-Connected Layer(Dense)
"""


inputs = keras.Input(shape=(32, 32, 3))

x = keras.layers.Conv2D(16, 3, activation='relu')(inputs)
x = keras.layers.MaxPool2D((2,2))(x)
x = keras.layers.Conv2D(32, 3, activation='relu')(x)
x = keras.layers.MaxPool2D((2,2))(x)
x = keras.layers.Flatten()(x)
x = keras.layers.Dense(256, activation='relu')(x)
predictions = keras.layers.Dense(100, activation='softmax')(x)

model = keras.Model(inputs=inputs, outputs=predictions)
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)

model.evaluate(x_test,  y_test, verbose=2)
Epoch 1/5
1563/1563 [==============================] - 7s 4ms/step - loss: 3.9875 - accuracy: 0.1027
Epoch 2/5
1563/1563 [==============================] - 4s 3ms/step - loss: 3.0038 - accuracy: 0.2650
Epoch 3/5
1563/1563 [==============================] - 4s 3ms/step - loss: 2.6571 - accuracy: 0.3330
Epoch 4/5
1563/1563 [==============================] - 5s 3ms/step - loss: 2.4541 - accuracy: 0.3760
Epoch 5/5
1563/1563 [==============================] - 5s 3ms/step - loss: 2.2993 - accuracy: 0.4051
313/313 - 1s - loss: 2.6378 - accuracy: 0.3418





[2.6378417015075684, 0.3418000042438507]
# Subclassing을 활용한 Model을 구성해주세요.
"""
Spec:
0. keras.Model 을 상속받았으며, __init__()와 call() 메소드를 가진 모델 클래스
1. 16개의 채널을 가지고, 커널의 크기가 3, activation function이 relu인 Conv2D 레이어
2. pool_size가 2인 MaxPool 레이어
3. 32개의 채널을 가지고, 커널의 크기가 3, activation function이 relu인 Conv2D 레이어
4. pool_size가 2인 MaxPool 레이어
5. 256개의 아웃풋 노드를 가지고, activation function이 relu인 Fully-Connected Layer(Dense)
6. 데이터셋의 클래스 개수에 맞는 아웃풋 노드를 가지고, activation function이 softmax인 Fully-Connected Layer(Dense)
7. call의 입력값이 모델의 Input, call의 리턴값이 모델의 Output
"""

class CustomModel(keras.Model):
    def __init__(self):
        super().__init__()
        self.conv1 = keras.layers.Conv2D(16, 3, activation='relu')
        self.maxpool1 = keras.layers.MaxPool2D((2,2))
        self.conv2 = keras.layers.Conv2D(32, 3, activation='relu')
        self.maxpool2 = keras.layers.MaxPool2D((2,2))
        self.flatten = keras.layers.Flatten()
        self.fc1 = keras.layers.Dense(256, activation='relu')
        self.fc2 = keras.layers.Dense(100, activation='softmax')
        
    def call(self, x):
        x = self.conv1(x)
        x = self.maxpool1(x)
        x = self.conv2(x)
        x = self.maxpool2(x)
        x = self.flatten(x)
        x = self.fc1(x)
        x = self.fc2(x)
        
        return x
        
model = CustomModel()
# 모델 학습 설정


model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=5)

model.evaluate(x_test,  y_test, verbose=2)
Epoch 1/5
1563/1563 [==============================] - 8s 5ms/step - loss: 4.0122 - accuracy: 0.0981
Epoch 2/5
1563/1563 [==============================] - 7s 5ms/step - loss: 2.9624 - accuracy: 0.2729
Epoch 3/5
1563/1563 [==============================] - 7s 4ms/step - loss: 2.6205 - accuracy: 0.3453
Epoch 4/5
1563/1563 [==============================] - 4s 3ms/step - loss: 2.4075 - accuracy: 0.3887
Epoch 5/5
1563/1563 [==============================] - 4s 3ms/step - loss: 2.2164 - accuracy: 0.4266
313/313 - 1s - loss: 2.6230 - accuracy: 0.3552





[2.622960090637207, 0.35519999265670776]

GradientTape의 활용

import tensorflow as tf
from tensorflow import keras

# 데이터 구성부분
cifar100 = keras.datasets.cifar100

(x_train, y_train), (x_test, y_test) = cifar100.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
print(len(x_train), len(x_test))

# 모델 구성부분
class CustomModel(keras.Model):
    def __init__(self):
        super().__init__()
        self.conv1 = keras.layers.Conv2D(16, 3, activation='relu')
        self.maxpool1 = keras.layers.MaxPool2D((2,2))
        self.conv2 = keras.layers.Conv2D(32, 3, activation='relu')
        self.maxpool2 = keras.layers.MaxPool2D((2,2))
        self.flatten = keras.layers.Flatten()
        self.fc1 = keras.layers.Dense(256, activation='relu')
        self.fc2 = keras.layers.Dense(100, activation='softmax')

    def call(self, x):
        x = self.conv1(x)
        x = self.maxpool1(x)
        x = self.conv2(x)
        x = self.maxpool2(x)
        x = self.flatten(x)
        x = self.fc1(x)
        x = self.fc2(x)

        return x

model = CustomModel()
50000 10000
loss_func = tf.keras.losses.SparseCategoricalCrossentropy()
optimizer = tf.keras.optimizers.Adam()

# tf.GradientTape()를 활용한 train_step
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
import time
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, dtype=np.float32), np.array(y_batch, dtype=np.float32))
                x_batch = []
                y_batch = []
        print('Epoch %d: last batch loss = %.4f' % (epoch, float(loss)))
    print("It took {} seconds".format(time.time() - start))

train_model()
Epoch 0: last batch loss = 4.4772
Epoch 1: last batch loss = 4.3283
Epoch 2: last batch loss = 3.2793
Epoch 3: last batch loss = 3.3624
Epoch 4: last batch loss = 2.5240
It took 93.7896785736084 seconds

이렇듯 tf.GradientTape()를 활용하면 model.compile()과 model.fit() 안에 감추어져 있던 한 스텝의 학습 단계(위 예제에서는 train_step 메소드)를 끄집어내서 자유롭게 재구성할 수 있게 됩니다.

# evaluation
prediction = model.predict(x_test, batch_size=x_test.shape[0], verbose=1)
temp = sum(np.squeeze(y_test) == np.argmax(prediction, axis=1))
temp/len(y_test)  # Accuracy
1/1 [==============================] - 3s 3s/step





0.0472

Leave a comment