A.I
TensorFlow v2 다뤄보기 본문
1. TensorFlow 종류¶
1. TensorFlow2 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 모델은 입출력이 1개씩이다.
2. TensorFlow2 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)
- Functional API를 통해 다중입력/출력을 가지는 모델을 구성
- input과 output을 규정함으로써 모델 전체를 규정
3. TensorFlow2 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)
- init()이라는 메소드 안에서 레이어 구성을 정의
- call()이라는 메소드 안에서 레이어간 forward propagation을 구현
2. Tensorflow2 API로 모델 작성 - MNIST¶
Sequential API 활용¶
In [1]:
import tensorflow as tf
from tensorflow import keras
import numpy as np
In [2]:
# 데이터 구성부분
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
In [3]:
"""
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')
])
In [5]:
# 모델 학습 설정
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 [==============================] - 55s 29ms/step - loss: 0.1098 - accuracy: 0.9667 Epoch 2/5 1875/1875 [==============================] - 56s 30ms/step - loss: 0.0366 - accuracy: 0.9880 Epoch 3/5 1875/1875 [==============================] - 56s 30ms/step - loss: 0.0208 - accuracy: 0.9933 Epoch 4/5 1875/1875 [==============================] - 55s 29ms/step - loss: 0.0127 - accuracy: 0.9958 Epoch 5/5 1875/1875 [==============================] - 56s 30ms/step - loss: 0.0099 - accuracy: 0.9964 313/313 - 2s - loss: 0.0376 - accuracy: 0.9899
Out[5]:
[0.037583090364933014, 0.9898999929428101]
Functional API 활용¶
In [6]:
import tensorflow as tf
from tensorflow import keras
import numpy as np
In [7]:
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
In [8]:
"""
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)
In [9]:
# 모델 학습 설정
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 [==============================] - 57s 30ms/step - loss: 0.1057 - accuracy: 0.9671 Epoch 2/5 1875/1875 [==============================] - 56s 30ms/step - loss: 0.0335 - accuracy: 0.9897 Epoch 3/5 1875/1875 [==============================] - 58s 31ms/step - loss: 0.0195 - accuracy: 0.9936 Epoch 4/5 1875/1875 [==============================] - 56s 30ms/step - loss: 0.0127 - accuracy: 0.9958 Epoch 5/5 1875/1875 [==============================] - 57s 30ms/step - loss: 0.0090 - accuracy: 0.9970 313/313 - 2s - loss: 0.0435 - accuracy: 0.9893
Out[9]:
[0.04349708557128906, 0.989300012588501]
Subclassing 활용¶
- init() 메소드 안에서 레이어를 선언, call() 메소드 안에서 forward propagation을 구현하는 방식
- Functional 방식과 비교하면, call()의 입력이 Input이고, call()의 리턴값이 Output이 되는 것
In [10]:
import tensorflow as tf
from tensorflow import keras
import numpy as np
In [11]:
# 데이터 구성부분
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
In [12]:
"""
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()
In [13]:
# 모델 학습 설정
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 [==============================] - 56s 30ms/step - loss: 0.1040 - accuracy: 0.9693 Epoch 2/5 1875/1875 [==============================] - 58s 31ms/step - loss: 0.0346 - accuracy: 0.9890 Epoch 3/5 1875/1875 [==============================] - 59s 32ms/step - loss: 0.0197 - accuracy: 0.9936 Epoch 4/5 1875/1875 [==============================] - 61s 33ms/step - loss: 0.0133 - accuracy: 0.9953 Epoch 5/5 1875/1875 [==============================] - 58s 31ms/step - loss: 0.0094 - accuracy: 0.9968 313/313 - 2s - loss: 0.0463 - accuracy: 0.9876
Out[13]:
[0.04627349227666855, 0.9876000285148621]
3. TensorFlow2 API로 모델 작성 - CIFAR-100¶
Sequential API 활용¶
In [14]:
import tensorflow as tf
from tensorflow import keras
In [15]:
# 데이터 구성부분
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
In [16]:
"""
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')
])
In [17]:
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 5ms/step - loss: 3.6859 - accuracy: 0.1426 Epoch 2/5 1563/1563 [==============================] - 8s 5ms/step - loss: 3.0430 - accuracy: 0.2559 Epoch 3/5 1563/1563 [==============================] - 8s 5ms/step - loss: 2.7404 - accuracy: 0.3144 Epoch 4/5 1563/1563 [==============================] - 8s 5ms/step - loss: 2.5169 - accuracy: 0.3596 Epoch 5/5 1563/1563 [==============================] - 8s 5ms/step - loss: 2.3409 - accuracy: 0.3991 313/313 - 1s - loss: 2.5819 - accuracy: 0.3578
Out[17]:
[2.581890821456909, 0.3578000068664551]
Functional API 활용¶
In [18]:
import tensorflow as tf
from tensorflow import keras
In [19]:
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
In [20]:
"""
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)
In [21]:
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 6ms/step - loss: 3.6216 - accuracy: 0.1536 Epoch 2/5 1563/1563 [==============================] - 9s 6ms/step - loss: 2.8967 - accuracy: 0.2866 Epoch 3/5 1563/1563 [==============================] - 9s 5ms/step - loss: 2.6016 - accuracy: 0.3482 Epoch 4/5 1563/1563 [==============================] - 9s 6ms/step - loss: 2.4055 - accuracy: 0.3848 Epoch 5/5 1563/1563 [==============================] - 9s 6ms/step - loss: 2.2527 - accuracy: 0.4184 313/313 - 1s - loss: 2.5930 - accuracy: 0.3566
Out[21]:
[2.593045234680176, 0.35659998655319214]
Subclassing 활용¶
In [22]:
import tensorflow as tf
from tensorflow import keras
In [23]:
# 데이터 구성부분
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
In [24]:
"""
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()
In [25]:
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 6ms/step - loss: 3.5736 - accuracy: 0.1647 Epoch 2/5 1563/1563 [==============================] - 9s 6ms/step - loss: 2.8426 - accuracy: 0.2972 Epoch 3/5 1563/1563 [==============================] - 9s 6ms/step - loss: 2.5296 - accuracy: 0.3588 Epoch 4/5 1563/1563 [==============================] - 9s 6ms/step - loss: 2.3124 - accuracy: 0.4041 Epoch 5/5 1563/1563 [==============================] - 8s 5ms/step - loss: 2.1299 - accuracy: 0.4454 313/313 - 1s - loss: 2.5328 - accuracy: 0.3648
Out[25]:
[2.532813787460327, 0.36480000615119934]
GradientTape의 활용¶
Numpy를 이용한 딥러닝 과정에서는
- Forward Propagation 수행 및 중간 레이어값 저장
- Loss 값 계산
- 중간 레이어값 및 Loss를 활용한 체인룰(chain rule) 방식의 역전파(Backward Propagation) 수행
- 학습 파라미터 업데이트 4단계로 이루어진 train_step 을 여러번 반복해야했다.
TenSorFlow2 API에는 model.fit()이라는 메소드 안에 모두 추상화되어 함축되어있다.
강화학습이나 GAN을 위해 model.compile()과 model.fit()을 분리하여 train_step의 메소드를 재구성할수 있게 된 것.
In [26]:
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
In [27]:
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
tape.gradient()를 통해 매 스텝 학습이 진행될 때마다 발생하는 그래디언트를 추출한 후 optimizer.apply_gradients()를 통해 발생한 그래디언트가 업데이트해야 할 파라미터 model.trainable_variables를 지정해 주는 과정을 기술한 것
In [28]:
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.5469 Epoch 1: last batch loss = 4.4348 Epoch 2: last batch loss = 4.1166 Epoch 3: last batch loss = 3.4593 Epoch 4: last batch loss = 2.7548 It took 61.11846089363098 seconds
model.fit()과정을 train_step()가 호출되는 과정으로 바꾸어 구현
In [29]:
# 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 [==============================] - 0s 3ms/step
Out[29]:
0.0594
'파이썬 & AI 학습' 카테고리의 다른 글
Linear, Convolution layer (0) | 2021.03.06 |
---|---|
MapReduce 원리 (0) | 2021.03.04 |
파이썬으로 DB 다루기 (0) | 2021.02.24 |
딥러닝에 대한 개념 학습 (0) | 2021.02.21 |
이상치 탐색 (0) | 2021.02.19 |