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.Adagrad1.0에서0.001까지optimizers.Adadelta0.002에서0.001까지optimizers.Adamax0.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로 마이그레이션하는 것이 좋습니다. 자세히 알아보려면 마이그레이션 가이드를 읽어보세요.
TensorFlow.org에서보기
Google Colab에서 실행하기
GitHub에서 소스 보기
노트북 다운로드하기