TensorFlow.org에서보기 | Google Colab에서 실행하기 | GitHub에서 소스 보기 | 노트북 다운로드하기 |
개요
이 가이드는 TensorFlow 2(TF2)를 사용하여 코드를 작성하기 위한 모범 사례 목록을 제공하며 최근에 TensorFlow 1(TF1)에서 전환한 사용자를 위해 작성되었습니다. TF1 코드를 TF2로 마이그레이션하는 방법에 대한 자세한 내용은 가이드의 마이그레이션 섹션을 참고하세요.
설치하기
이 가이드의 예제에서 사용하는 TensorFlow 및 기타 종속 항목을 가져옵니다.
import tensorflow as tf
import tensorflow_datasets as tfds
2022-12-14 21:55:10.524042: 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 21:55:10.524133: 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 21:55:10.524142: 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.
관용적 텐서플로우 2.0 권장 사항
코드를 더 작은 모듈로 리팩토링
필요에 따라 호출되는 더 작은 함수로 코드를 리팩토링하는 것이 좋습니다. 최고의 성능을 위해서는 tf.function
에서 가능한 가장 큰 계산 블록을 장식해야 합니다(tf.function
로 호출하여 중첩한 Python 함수는 tf.function
에 다른 jit_compile
설정을 사용하려는 경우가 아니면 별도의 장식이 필요하지 않음). 사용 사례에 따라 여러 훈련 단계 또는 전체 훈련 루프가 될 수도 있습니다. 추론 사용 사례는 단일 모델 전달 경로일 수 있습니다.
일부 tf.keras.optimizer
의 기본 훈련률 조정하기
일부 Keras 옵티마이저는 TF2에서 다른 훈련률을 갖습니다. 모델의 수렴 동작이 변경되면 기본 훈련률을 확인해야 합니다.
optimizers.SGD
, optimizers.Adam
또는 optimizers.RMSprop
에는 변경사항이 없습니다.
다음 기본 훈련률이 변경되었습니다.
0.01
에서0.001
까지optimizers.Adagrad
1.0
에서0.001
까지optimizers.Adadelta
0.002
에서0.001
까지optimizers.Adamax
0.002
에서0.001
까지optimizers.Nadam
tf.Module
및 Keras 레이어를 사용하여 변수 관리
tf.Module
및 tf.keras.layers.Layer
는 편리한 variables
및 trainable_variables
속성을 제공하고, 이는 모든 종속 변수를 재귀적으로 수집합니다. 이렇게 하면 변수가 사용되는 위치에서 로컬로 변수를 쉽게 관리할 수 있습니다.
Keras 레이어와 모델은 tf.train.Checkpointable로부터 상속하고 @tf.function과 통합되어 Keras 객체에서 저장 모델을 직접 검사하거나 내보낼 수 있도록 합니다. 이러한 통합을 활용하기 위해 반드시 Keras의 Model.fit API를 사용해야 하는 것은 아닙니다.
Keras를 사용하여 관련 변수의 하위 집합을 수집하는 방법을 알아보려면 Keras 가이드의 전이 학습 및 미세 조정 섹션을 읽어보세요.
tf.data.Dataset
와 tf.function
결합하기
TensorFlow 데이터세트 패키지(tfds
)에는 사전 정의된 데이터세트를 tf.data.Dataset
객체로 로드하는 유틸리티가 포함되어 있습니다. 이 예제에서는 tfds
를 사용하여 MNIST 데이터세트를 로드할 수 있습니다.
datasets, info = tfds.load(name='mnist', with_info=True, as_supervised=True)
mnist_train, mnist_test = datasets['train'], datasets['test']
그런 다음 훈련에 사용할 데이터를 준비합니다.
- 각 이미지의 크기를 다시 조정합니다.
- 예제의 순서를 셔플링합니다.
- 이미지 및 레이블 배치를 수집합니다.
BUFFER_SIZE = 10 # Use a much larger value for real code
BATCH_SIZE = 64
NUM_EPOCHS = 5
def scale(image, label):
image = tf.cast(image, tf.float32)
image /= 255
return image, label
이 예제를 짧게 유지하려면 5개의 배치만 반환하도록 데이터세트를 자릅니다.
train_data = mnist_train.map(scale).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)
test_data = mnist_test.map(scale).batch(BATCH_SIZE)
STEPS_PER_EPOCH = 5
train_data = train_data.take(STEPS_PER_EPOCH)
test_data = test_data.take(STEPS_PER_EPOCH)
image_batch, label_batch = next(iter(train_data))
2022-12-14 21:55:16.307777: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
메모리에 맞는 훈련 데이터를 반복하려면 일반 Python 반복을 사용해야 합니다. 그렇지 않을때 이 디스크에서 훈련 데이터를 스트리밍하는 가장 좋은 방법은 tf.data.Dataset
입니다. 데이터세트는 반복할 수 있으며(반복기는 아님) 즉시 실행에서 다른 Python 반복기처럼 동작합니다. 코드를 tf.function
로 래핑하여 데이터세트 비동기 프리페치/스트리밍 기능을 온전히 활용할 수 있습니다. 이는 AutoGraph를 사용하여 Python 반복기를 동등한 그래프 연산으로 교체합니다.
@tf.function
def train(model, dataset, optimizer):
for x, y in dataset:
with tf.GradientTape() as tape:
# training=True is only needed if there are layers with different
# behavior during training versus inference (e.g. Dropout).
prediction = model(x, training=True)
loss = loss_fn(prediction, y)
gradients = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
Keras Model.fit API를 사용하면 데이터세트 반복에 대해 신경 쓸 필요가 없습니다.
model.compile(optimizer=optimizer, loss=loss_fn)
model.fit(dataset)
Keras 훈련 루프 사용하기
훈련 과정을 세부적으로 제어할 필요가 없다면 케라스의 내장 메서드인 fit, evaluate, predict를 사용하는 것이 좋습니다. 이 메서드들은 모델 구현(Sequential, 함수형 API, 클래스 상속)에 상관없이 일관된 훈련 인터페이스를 제공합니다.
이 메소드의 장점은 다음과 같습니다.
- Numpy 배열, Python 제너레이터,
tf.data.Datasets
를 사용할 수 있습니다. - 정규화 및 활성화 손실을 자동으로 적용합니다.
- 하드웨어 구성에 관계 없이 훈련 코드가 동일하게 유지되는
tf.distribute
를 지원합니다. - 손실 및 메트릭으로 임의의 호출 가능 항목을 지원합니다.
tf.keras.callbacks.TensorBoard
와 같은 콜백과 사용자 정의 콜백을 지원합니다.- TensorFlow 그래프를 사용하여 자동으로 성능 기준을 맞춥니다.
다음은 Dataset
를 사용하여 모델을 훈련하는 예제입니다. 작동 방식에 대한 자세한 내용은 튜토리얼을 확인합니다.
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(32, 3, activation='relu',
kernel_regularizer=tf.keras.regularizers.l2(0.02),
input_shape=(28, 28, 1)),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Flatten(),
tf.keras.layers.Dropout(0.1),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Dense(10)
])
# Model is the full model w/o custom layers
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
model.fit(train_data, epochs=NUM_EPOCHS)
loss, acc = model.evaluate(test_data)
print("Loss {}, Accuracy {}".format(loss, acc))
Epoch 1/5 5/5 [==============================] - 3s 6ms/step - loss: 1.5373 - accuracy: 0.5000 Epoch 2/5 2022-12-14 21:55:19.700111: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead. 5/5 [==============================] - 0s 5ms/step - loss: 0.4361 - accuracy: 0.9312 Epoch 3/5 2022-12-14 21:55:19.979427: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead. 5/5 [==============================] - 0s 5ms/step - loss: 0.2826 - accuracy: 0.9656 Epoch 4/5 2022-12-14 21:55:20.289201: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead. 5/5 [==============================] - 0s 5ms/step - loss: 0.1974 - accuracy: 0.9875 Epoch 5/5 2022-12-14 21:55:20.576118: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead. 5/5 [==============================] - 0s 5ms/step - loss: 0.1499 - accuracy: 1.0000 2022-12-14 21:55:20.848689: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead. 5/5 [==============================] - 0s 3ms/step - loss: 1.6309 - accuracy: 0.7531 Loss 1.6308777332305908, Accuracy 0.753125011920929 2022-12-14 21:55:21.212331: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
훈련 루프 사용자 정의하기 및 자체 루프 작성하기
Keras 모델이 적합하지만 훈련 단계 또는 외부 훈련 루프에 더 많은 유연성과 제어가 필요한 경우 자체 훈련 단계 또는 전체 훈련 루프를 구현할 수 있습니다. 자세한 내용은 fit
사용자 정의하기의 Keras 가이드를 참조해 주세요.
tf.keras.callbacks.Callback
으로 많은 것을 구현할 수도 있습니다.
이 메서드에는 이전에 언급한 많은 장점 외에도 훈련 단계와 외부 루프까지 제어할 수 있다는 장점도 있습니다.
표준 훈련 루프에는 세 단계가 있습니다.
- Python 생성기 또는
tf.data.Dataset
를 반복하여 예제 배치를 가져옵니다. tf.GradientTape
를 사용하여 그래디언트를 수집합니다.tf.keras.optimizers
중 하나를 사용하여 모델 변수에 가중치 업데이트를 적용합니다.
기억해야 하는 사항:
- 서브 클래화된 레이어 및 모델의
call
메서드에 항상training
인수를 포함합니다. training
인수가 올바르게 설정된 모델을 호출하는지 확인합니다.- 사용법에 따라 데이터 배치에서 모델을 실행할 때까지 모델 변수가 존재하지 않을 수 있습니다.
- 모델의 정규화 손실 등은 수동으로 처리해야 합니다.
변수 이니셜라이저를 실행하거나 수동 제어 종속성을 추가할 필요가 없습니다. tf.function
은 생성 시 자동 제어 종속성과 변수 초기화를 처리합니다.
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(32, 3, activation='relu',
kernel_regularizer=tf.keras.regularizers.l2(0.02),
input_shape=(28, 28, 1)),
tf.keras.layers.MaxPooling2D(),
tf.keras.layers.Flatten(),
tf.keras.layers.Dropout(0.1),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Dense(10)
])
optimizer = tf.keras.optimizers.Adam(0.001)
loss_fn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
@tf.function
def train_step(inputs, labels):
with tf.GradientTape() as tape:
predictions = model(inputs, training=True)
regularization_loss=tf.math.add_n(model.losses)
pred_loss=loss_fn(labels, predictions)
total_loss=pred_loss + regularization_loss
gradients = tape.gradient(total_loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
for epoch in range(NUM_EPOCHS):
for inputs, labels in train_data:
train_step(inputs, labels)
print("Finished epoch", epoch)
2022-12-14 21:55:22.897407: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead. Finished epoch 0 2022-12-14 21:55:23.185574: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead. Finished epoch 1 2022-12-14 21:55:23.467763: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead. Finished epoch 2 2022-12-14 21:55:23.738925: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead. Finished epoch 3 Finished epoch 4 2022-12-14 21:55:24.029871: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
Python 제어 흐름으로 tf.function
활용하기
tf.function
은 데이터에 따라 결정되는 제어 흐름을 tf.cond
와 tf.while_loop
와 같은 그래프 모드로 변환하는 방법을 제공합니다.
데이터에 의존하는 제어 흐름이 나타나는 대표적인 곳은 시퀀스 모델입니다. tf.keras.layers.RNN
은 RNN 셀을 래핑하여 반복을 정적으로 또는 동적으로 전개할 수 있도록 합니다. 예를 들어 다음과 같은 동적 언롤을 다시 구현할 수 있습니다.
class DynamicRNN(tf.keras.Model):
def __init__(self, rnn_cell):
super(DynamicRNN, self).__init__(self)
self.cell = rnn_cell
@tf.function(input_signature=[tf.TensorSpec(dtype=tf.float32, shape=[None, None, 3])])
def call(self, input_data):
# [batch, time, features] -> [time, batch, features]
input_data = tf.transpose(input_data, [1, 0, 2])
timesteps = tf.shape(input_data)[0]
batch_size = tf.shape(input_data)[1]
outputs = tf.TensorArray(tf.float32, timesteps)
state = self.cell.get_initial_state(batch_size = batch_size, dtype=tf.float32)
for i in tf.range(timesteps):
output, state = self.cell(input_data[i], state)
outputs = outputs.write(i, output)
return tf.transpose(outputs.stack(), [1, 0, 2]), state
lstm_cell = tf.keras.layers.LSTMCell(units = 13)
my_rnn = DynamicRNN(lstm_cell)
outputs, state = my_rnn(tf.random.normal(shape=[10,20,3]))
print(outputs.shape)
(10, 20, 13)
자세한 정보는 tf.function
가이드를 참고합니다.
새로운 스타일의 메트릭 및 손실
메트릭과 손실은 모두 tf.function
에서 즉시 작동하는 객체입니다.
손실 객체는 호출할 수 있으며 (y_true
, y_pred
)를 인수로 예상합니다.
cce = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
cce([[1, 0]], [[-1.0,3.0]]).numpy()
4.01815
메트릭을 사용하여 데이터를 수집하고 표시하기
tf.metrics
를 사용하여 데이터를 집계하고 tf.summary
를 사용하여 요약문을 기록하고 컨텍스트 관리자를 사용하여 작성자에게 리디렉션할 수 있습니다. 요약문은 작성자에게 직접 내보내지므로 호출 사이트에서 step
값을 제공해야 합니다.
summary_writer = tf.summary.create_file_writer('/tmp/summaries')
with summary_writer.as_default():
tf.summary.scalar('loss', 0.1, step=42)
요약문으로 기록하기 전에 tf.metrics
를 사용하여 데이터를 집계합니다. 메트릭은 정적(Stateful)이기에 result
메서드(예: Mean.result
)를 호출하면 값이 누적되고 누적 결과가 반환됩니다. Model.reset_states
로 누적된 값을 삭제합니다.
def train(model, optimizer, dataset, log_freq=10):
avg_loss = tf.keras.metrics.Mean(name='loss', dtype=tf.float32)
for images, labels in dataset:
loss = train_step(model, optimizer, images, labels)
avg_loss.update_state(loss)
if tf.equal(optimizer.iterations % log_freq, 0):
tf.summary.scalar('loss', avg_loss.result(), step=optimizer.iterations)
avg_loss.reset_states()
def test(model, test_x, test_y, step_num):
# training=False is only needed if there are layers with different
# behavior during training versus inference (e.g. Dropout).
loss = loss_fn(model(test_x, training=False), test_y)
tf.summary.scalar('loss', loss, step=step_num)
train_summary_writer = tf.summary.create_file_writer('/tmp/summaries/train')
test_summary_writer = tf.summary.create_file_writer('/tmp/summaries/test')
with train_summary_writer.as_default():
train(model, optimizer, dataset)
with test_summary_writer.as_default():
test(model, test_x, test_y, optimizer.iterations)
텐서보드(TensorBoard)에서 요약문 로그 디렉터리를 지정하여 생성된 요약문을 시각화합니다.
tensorboard --logdir /tmp/summaries
텐서보드에서 시각화를 생성할 수 있도록 tf.summary
API를 사용하여 요약문 데이터를 작성합니다. 자세한 정보는 tf.summary
가이드를 참고합니다.
# Create the metrics
loss_metric = tf.keras.metrics.Mean(name='train_loss')
accuracy_metric = tf.keras.metrics.SparseCategoricalAccuracy(name='train_accuracy')
@tf.function
def train_step(inputs, labels):
with tf.GradientTape() as tape:
predictions = model(inputs, training=True)
regularization_loss=tf.math.add_n(model.losses)
pred_loss=loss_fn(labels, predictions)
total_loss=pred_loss + regularization_loss
gradients = tape.gradient(total_loss, model.trainable_variables)
optimizer.apply_gradients(zip(gradients, model.trainable_variables))
# Update the metrics
loss_metric.update_state(total_loss)
accuracy_metric.update_state(labels, predictions)
for epoch in range(NUM_EPOCHS):
# Reset the metrics
loss_metric.reset_states()
accuracy_metric.reset_states()
for inputs, labels in train_data:
train_step(inputs, labels)
# Get the metric results
mean_loss=loss_metric.result()
mean_accuracy = accuracy_metric.result()
print('Epoch: ', epoch)
print(' loss: {:.3f}'.format(mean_loss))
print(' accuracy: {:.3f}'.format(mean_accuracy))
2022-12-14 21:55:24.963973: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead. Epoch: 0 loss: 0.133 accuracy: 0.991 2022-12-14 21:55:25.238740: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead. Epoch: 1 loss: 0.113 accuracy: 1.000 2022-12-14 21:55:25.538122: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead. Epoch: 2 loss: 0.101 accuracy: 1.000 2022-12-14 21:55:25.844832: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead. Epoch: 3 loss: 0.088 accuracy: 1.000 Epoch: 4 loss: 0.079 accuracy: 1.000 2022-12-14 21:55:26.131845: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
저장과 복원
Keras 모델은 메트릭 이름을 일관성 있게 처리합니다. 메트릭 목록의 문자열을 전달하면 일치하는 문자열을 메트릭의 name
으로 사용합니다. 이러한 이름은 model.fit
로 반환한 기록 객체와 keras.callbacks
에 전달된 로그에서 볼 수 있습니다. 메트릭 목록에서 전달한 문자열로 설정됩니다.
model.compile(
optimizer = tf.keras.optimizers.Adam(0.001),
loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics = ['acc', 'accuracy', tf.keras.metrics.SparseCategoricalAccuracy(name="my_accuracy")])
history = model.fit(train_data)
5/5 [==============================] - 2s 5ms/step - loss: 0.0902 - acc: 0.9969 - accuracy: 0.9969 - my_accuracy: 0.9969 2022-12-14 21:55:27.804136: W tensorflow/core/kernels/data/cache_dataset_ops.cc:856] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.
history.history.keys()
dict_keys(['loss', 'acc', 'accuracy', 'my_accuracy'])
디버깅
즉시 실행을 사용하여 코드를 단계별로 실행하고 형상, 데이터 유형 및 값을 검사할 수 있습니다. tf.function
, tf.keras
등과 같은 특정 API는 성능 및 이식성을 위해 그래프 실행을 사용하도록 설계되었습니다. 디버깅할 때 이 코드 내에서 즉시 실행을 사용하려면 tf.config.run_functions_eagerly(True)
를 사용합니다.
예제:
@tf.function
def f(x):
if x > 0:
import pdb
pdb.set_trace()
x = x + 1
return x
tf.config.run_functions_eagerly(True)
f(tf.constant(1))
>>> f()
-> x = x + 1
(Pdb) l
6 @tf.function
7 def f(x):
8 if x > 0:
9 import pdb
10 pdb.set_trace()
11 -> x = x + 1
12 return x
13
14 tf.config.run_functions_eagerly(True)
15 f(tf.constant(1))
[EOF]
이는 Keras 모델 및 즉시 실행을 지원하는 기타 API에서도 작동합니다.
class CustomModel(tf.keras.models.Model):
@tf.function
def call(self, input_data):
if tf.reduce_mean(input_data) > 0:
return input_data
else:
import pdb
pdb.set_trace()
return input_data // 2
tf.config.run_functions_eagerly(True)
model = CustomModel()
model(tf.constant([-2, -4]))
>>> call()
-> return input_data // 2
(Pdb) l
10 if tf.reduce_mean(input_data) > 0:
11 return input_data
12 else:
13 import pdb
14 pdb.set_trace()
15 -> return input_data // 2
16
17
18 tf.config.run_functions_eagerly(True)
19 model = CustomModel()
20 model(tf.constant([-2, -4]))
참고 사항:
fit
,evaluate
,predict
와 같은tf.keras.Model
메서드는 관련된tf.function
을 사용하여 그래프로 실행합니다.tf.keras.Model.compile
을 사용할 경우run_eagerly = True
를 설정하여Model
로직이tf.function
으로 래핑되지 않도록 합니다.tf.data.experimental.enable_debug_mode
를 사용하여tf.data
에 대해 디버그 모드를 사용하도록 설정합니다. 자세한 내용은 API 문서를 참고합니다.
객체에 tf.Tensors
유지 금지
이러한 텐서 객체는 tf.function
또는 Eager 컨텍스트에서 생성될 수 있으며 이러한 텐서는 다르게 동작합니다. 중간 값에는 항상 tf.Tensor
를 사용합니다.
상태를 추적하려면 양쪽 컨텍스트에서 항상 사용할 수 있는 tf.Variable
을 사용합니다. 자세히 알아보려면tf.Variable
가이드를 읽어보세요.
리소스 및 추가 읽을거리
이전에 TF1.x를 사용한 경우 코드를 TF2로 마이그레이션하는 것이 좋습니다. 자세히 알아보려면 마이그레이션 가이드를 읽어보세요.