TensorFlow.org에서 보기 | Google Colab에서 실행 | GitHub에서 소스 보기 | 노트북 다운로드 |
설정
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
2022-12-14 22:19:05.490410: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory 2022-12-14 22:19:05.490499: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory 2022-12-14 22:19:05.490509: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.
Sequential 모델을 사용하는 경우
Sequential
모델은 각 레이어에 정확히 하나의 입력 텐서와 하나의 출력 텐서가 있는 일반 레이어 스택에 적합합니다.
개략적으로 다음과 같은 Sequential
모델은
# Define Sequential model with 3 layers
model = keras.Sequential(
[
layers.Dense(2, activation="relu", name="layer1"),
layers.Dense(3, activation="relu", name="layer2"),
layers.Dense(4, name="layer3"),
]
)
# Call model on a test input
x = tf.ones((3, 3))
y = model(x)
다음 함수와 동일합니다.
# Create 3 layers
layer1 = layers.Dense(2, activation="relu", name="layer1")
layer2 = layers.Dense(3, activation="relu", name="layer2")
layer3 = layers.Dense(4, name="layer3")
# Call layers on a test input
x = tf.ones((3, 3))
y = layer3(layer2(layer1(x)))
Sequential 모델은 다음의 경우에 적합하지 않습니다.
- 모델에 다중 입력 또는 다중 출력이 있습니다
- 레이어에 다중 입력 또는 다중 출력이 있습니다
- 레이어 공유를 해야 합니다
- 비선형 토폴로지를 원합니다(예: 잔류 연결, 다중 분기 모델)
Sequential 모델 생성하기
레이어의 목록을 Sequential 생성자에 전달하여 Sequential 모델을 만들 수 있습니다.
model = keras.Sequential(
[
layers.Dense(2, activation="relu"),
layers.Dense(3, activation="relu"),
layers.Dense(4),
]
)
속한 레이어는 layers
속성을 통해 접근할 수 있습니다.
model.layers
[<keras.layers.core.dense.Dense at 0x7f2f1dc468e0>, <keras.layers.core.dense.Dense at 0x7f2f1c09f9a0>, <keras.layers.core.dense.Dense at 0x7f2f1c0ab910>]
add()
메서드를 통해 Sequential 모델을 점진적으로 작성할 수도 있습니다.
model = keras.Sequential()
model.add(layers.Dense(2, activation="relu"))
model.add(layers.Dense(3, activation="relu"))
model.add(layers.Dense(4))
레이어를 제거하는 pop()
메서드도 있습니다. Sequential 모델은 레이어의 리스트와 매우 유사하게 동작합니다.
model.pop()
print(len(model.layers)) # 2
2
또한 Sequential 생성자는 Keras의 모든 레이어 또는 모델과 마찬가지로 name
인수를 허용합니다. 이것은 의미론적으로 유의미한 이름으로 TensorBoard 그래프에 주석을 달 때 유용합니다.
model = keras.Sequential(name="my_sequential")
model.add(layers.Dense(2, activation="relu", name="layer1"))
model.add(layers.Dense(3, activation="relu", name="layer2"))
model.add(layers.Dense(4, name="layer3"))
미리 입력 형상 지정하기
일반적으로 Keras의 모든 레이어는 가중치를 만들려면 입력의 형상을 알아야 합니다. 따라서 다음과 같은 레이어를 만들면 처음에는 가중치가 없습니다.
layer = layers.Dense(3)
layer.weights # Empty
[]
가중치는 모양이 입력의 형상에 따라 달라지기 때문에 입력에서 처음 호출될 때 가중치를 만듭니다.
# Call layer on a test input
x = tf.ones((1, 4))
y = layer(x)
layer.weights # Now it has weights, of shape (4, 3) and (3,)
[<tf.Variable 'dense_6/kernel:0' shape=(4, 3) dtype=float32, numpy= array([[ 0.48057687, 0.15762746, 0.64167905], [-0.65657234, 0.75073576, -0.5933933 ], [ 0.14622176, -0.07526302, -0.32710624], [-0.6101604 , -0.19589275, -0.6752404 ]], dtype=float32)>, <tf.Variable 'dense_6/bias:0' shape=(3,) dtype=float32, numpy=array([0., 0., 0.], dtype=float32)>]
당연히 이것은 Sequential 모델에도 적용됩니다. 입력 형상이 없는 Sequential 모델을 인스턴스화할 때는 "빌드"되지 않습니다. 가중치가 없습니다(그리고 model.weights
를 호출하면 오류가 발생함). 모델에 처음 입력 데이터가 표시되면 가중치가 생성됩니다.
model = keras.Sequential(
[
layers.Dense(2, activation="relu"),
layers.Dense(3, activation="relu"),
layers.Dense(4),
]
) # No weights at this stage!
# At this point, you can't do this:
# model.weights
# You also can't do this:
# model.summary()
# Call the model on a test input
x = tf.ones((1, 4))
y = model(x)
print("Number of weights after calling the model:", len(model.weights)) # 6
Number of weights after calling the model: 6
모델이 "빌드"되면, 그 내용을 표시하기 위해 summary()
메서드를 호출할 수 있습니다.
model.summary()
Model: "sequential_3" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense_7 (Dense) (1, 2) 10 dense_8 (Dense) (1, 3) 9 dense_9 (Dense) (1, 4) 16 ================================================================= Total params: 35 Trainable params: 35 Non-trainable params: 0 _________________________________________________________________
그러나 현재 출력 형상을 포함하여 지금까지 모델의 요약을 표시할 수 있도록 Sequential 모델을 점진적으로 빌드할 때 매우 유용할 수 있습니다. 이 경우 Input
객체를 모델에 전달하여 모델의 시작 형상을 알 수 있도록 모델을 시작해야 합니다.
model = keras.Sequential()
model.add(keras.Input(shape=(4,)))
model.add(layers.Dense(2, activation="relu"))
model.summary()
Model: "sequential_4" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense_10 (Dense) (None, 2) 10 ================================================================= Total params: 10 Trainable params: 10 Non-trainable params: 0 _________________________________________________________________
Input
객체는 레이어가 아니므로 model.layers
의 일부로 표시되지 않습니다.
model.layers
[<keras.layers.core.dense.Dense at 0x7f2f1c0abe20>]
간단한 대안은 첫 번째 레이어에 input_shape
인수를 전달하는 것입니다.
model = keras.Sequential()
model.add(layers.Dense(2, activation="relu", input_shape=(4,)))
model.summary()
Model: "sequential_5" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense_11 (Dense) (None, 2) 10 ================================================================= Total params: 10 Trainable params: 10 Non-trainable params: 0 _________________________________________________________________
이처럼 사전 정의된 입력 모양으로 빌드된 모델은 항상 가중치를 가지며(데이터를 보기 전에도) 항상 정의된 출력 형상을 갖습니다.
일반적으로 Sequential 모델의 입력 형상을 알고 있는 경우 항상 Sequential 모델의 입력 형상을 지정하는 것이 좋습니다.
일반적인 디버깅 워크플로우: add()
+ summary()
새로운 Sequential 아키텍처를 구축할 때는 add()
하여 레이어를 점진적으로 쌓고 모델 요약을 자주 인쇄하는 것이 유용합니다. 예를 들어 Conv2D
및 MaxPooling2D
레이어의 스택이 이미지 특성 맵을 다운 샘플링 하는 방법을 모니터링할 수 있습니다.
model = keras.Sequential()
model.add(keras.Input(shape=(250, 250, 3))) # 250x250 RGB images
model.add(layers.Conv2D(32, 5, strides=2, activation="relu"))
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.MaxPooling2D(3))
# Can you guess what the current output shape is at this point? Probably not.
# Let's just print it:
model.summary()
# The answer was: (40, 40, 32), so we can keep downsampling...
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.MaxPooling2D(3))
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.MaxPooling2D(2))
# And now?
model.summary()
# Now that we have 4x4 feature maps, time to apply global max pooling.
model.add(layers.GlobalMaxPooling2D())
# Finally, we add a classification layer.
model.add(layers.Dense(10))
Model: "sequential_6" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 123, 123, 32) 2432 conv2d_1 (Conv2D) (None, 121, 121, 32) 9248 max_pooling2d (MaxPooling2D (None, 40, 40, 32) 0 ) ================================================================= Total params: 11,680 Trainable params: 11,680 Non-trainable params: 0 _________________________________________________________________ Model: "sequential_6" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 123, 123, 32) 2432 conv2d_1 (Conv2D) (None, 121, 121, 32) 9248 max_pooling2d (MaxPooling2D (None, 40, 40, 32) 0 ) conv2d_2 (Conv2D) (None, 38, 38, 32) 9248 conv2d_3 (Conv2D) (None, 36, 36, 32) 9248 max_pooling2d_1 (MaxPooling (None, 12, 12, 32) 0 2D) conv2d_4 (Conv2D) (None, 10, 10, 32) 9248 conv2d_5 (Conv2D) (None, 8, 8, 32) 9248 max_pooling2d_2 (MaxPooling (None, 4, 4, 32) 0 2D) ================================================================= Total params: 48,672 Trainable params: 48,672 Non-trainable params: 0 _________________________________________________________________
매우 실용적이죠?
모델이 완성되면 해야 할 일
모델 아키텍처가 준비되면 다음을 수행할 수 있습니다.
- 모델을 훈련시키고 평가하며 추론을 실행합니다. 내장 루프를 사용한 훈련 및 평가 가이드를 참조하세요.
- 모델을 디스크에 저장하고 복구합니다. 직렬화 및 저장 가이드를 참조하세요.
- 다중 GPU를 활용하여 모델 훈련 속도를 향상 시킵니다. 다중 GPU 및 분산 훈련 가이드를 참조하세요.
Sequential 모델을 사용한 특성 추출
Sequential 모델이 빌드되면 Functional API 모델처럼 동작합니다. 이는 모든 레이어가 input
및 output
속성을 갖는다는 것을 의미합니다. 이러한 속성을 사용하면 Sequential 모델 내의 모든 중간 레이어들의 출력을 추출하는 모델을 빠르게 생성하는 등 깔끔한 작업을 수행할 수 있습니다.
initial_model = keras.Sequential(
[
keras.Input(shape=(250, 250, 3)),
layers.Conv2D(32, 5, strides=2, activation="relu"),
layers.Conv2D(32, 3, activation="relu"),
layers.Conv2D(32, 3, activation="relu"),
]
)
feature_extractor = keras.Model(
inputs=initial_model.inputs,
outputs=[layer.output for layer in initial_model.layers],
)
# Call feature extractor on test input.
x = tf.ones((1, 250, 250, 3))
features = feature_extractor(x)
다음은 한 레이어에서 특성만 추출하는 것과 유사한 예입니다.
initial_model = keras.Sequential(
[
keras.Input(shape=(250, 250, 3)),
layers.Conv2D(32, 5, strides=2, activation="relu"),
layers.Conv2D(32, 3, activation="relu", name="my_intermediate_layer"),
layers.Conv2D(32, 3, activation="relu"),
]
)
feature_extractor = keras.Model(
inputs=initial_model.inputs,
outputs=initial_model.get_layer(name="my_intermediate_layer").output,
)
# Call feature extractor on test input.
x = tf.ones((1, 250, 250, 3))
features = feature_extractor(x)
Sequential 모델에서 전이 학습 이용
전이 학습은 모델의 하단 레이어는 고정하고 상단 레이어만 학습하도록 구성되어 있습니다. 이에 익숙하지 않다면 전이 학습 가이드를 읽어보세요.
Sequential 모델과 관련된 두 가지 일반적인 전이 학습 청사진은 다음과 같습니다.
먼저 Sequential 모델이 있고 마지막 레이어를 제외한 모든 레이어를 고정하고 싶다고 가정해 보겠습니다. 이 경우 다음과 같이 model.layers
를 반복하고 마지막 레이어를 제외한 각 레이어에서 layer.trainable = False
를 설정하면 됩니다.
model = keras.Sequential([
keras.Input(shape=(784)),
layers.Dense(32, activation='relu'),
layers.Dense(32, activation='relu'),
layers.Dense(32, activation='relu'),
layers.Dense(10),
])
# Presumably you would want to first load pre-trained weights.
model.load_weights(...)
# Freeze all layers except the last one.
for layer in model.layers[:-1]:
layer.trainable = False
# Recompile and train (this will only update the weights of the last layer).
model.compile(...)
model.fit(...)
또 다른 일반적인 청사진은 Sequential 모델을 사용하여 사전에 훈련된 모델과 새롭게 초기화된 분류 레이어를 다음과 같이 쌓는 것입니다.
# Load a convolutional base with pre-trained weights
base_model = keras.applications.Xception(
weights='imagenet',
include_top=False,
pooling='avg')
# Freeze the base model
base_model.trainable = False
# Use a Sequential model to add a trainable classifier on top
model = keras.Sequential([
base_model,
layers.Dense(1000),
])
# Compile & train
model.compile(...)
model.fit(...)
전이 학습을 수행하게 되면 이 두 가지 패턴을 자주 사용하게 될 것입니다.
이것이 Sequential 모델에 대해 알아야 할 전부입니다!
Keras에서 모델을 빌드하는 방법에 대한 자세한 내용은 다음을 참조하세요.