TensorFlow.org'da görüntüleyin | Google Colab'da çalıştırın | Kaynağı GitHub'da görüntüleyin | Not defterini indir |
Bu not defteri, TF2'ye geçiş yapılırken eğitim hattında nasıl hata ayıklanacağını gösterir. Aşağıdaki bileşenlerden oluşur:
- Eğitim hattında hata ayıklamak için önerilen adımlar ve kod örnekleri
- Hata ayıklama araçları
- Diğer ilgili kaynaklar
Bir varsayım, karşılaştırma için TF1.x kodunuz ve eğitimli modelleriniz var ve benzer doğrulama doğruluğu sağlayan bir TF2 modeli oluşturmak istiyorsunuz.
Bu dizüstü bilgisayar, eğitim/çıkarım hızı veya bellek kullanımı için hata ayıklama performans sorunlarını KAPSAMAZ .
Hata ayıklama iş akışı
Aşağıda, TF2 eğitim işlem hatlarınızda hata ayıklamaya yönelik genel bir iş akışı verilmiştir. Bu adımları sırayla izlemeniz gerekmediğini unutmayın. Modeli bir ara adımda test ettiğiniz ve hata ayıklama kapsamını daralttığınız ikili arama yaklaşımını da kullanabilirsiniz.
Derleme ve çalışma zamanı hatalarını düzeltin
Tek ileri geçiş doğrulaması (ayrı bir kılavuzda )
a. Tek CPU cihazında
- Değişkenlerin yalnızca bir kez oluşturulduğunu doğrulayın
- Değişken sayıları, adları ve şekillerin eşleşmesini kontrol edin
- Tüm değişkenleri sıfırlayın, tüm rastgelelik devre dışı bırakılarak sayısal denkliği kontrol edin
- Rastgele sayı üretimini hizalayın, çıkarımda sayısal denkliği kontrol edin
- (İsteğe bağlı) Kontrol noktalarının düzgün yüklenip yüklenmediğini ve TF1.x/TF2 modelleri aynı çıktıyı üretir
B. Tek GPU/TPU cihazında
C. Çoklu cihaz stratejileri ile
Birkaç adım için model eğitimi sayısal denklik doğrulaması (kod örnekleri aşağıda mevcuttur)
a. Tek CPU cihazında küçük ve sabit veriler kullanılarak tek eğitim adımı doğrulaması. Spesifik olarak, aşağıdaki bileşenler için sayısal denkliği kontrol edin
- kayıp hesaplama
- metrikler
- öğrenme oranı
- gradyan hesaplama ve güncelleme
B. Tek CPU cihazında sabit verilerle momentum gibi optimize edici davranışlarını doğrulamak için 3 veya daha fazla adımı eğittikten sonra istatistikleri kontrol edin
C. Tek GPU/TPU cihazında
D. Çoklu cihaz stratejileriyle (en alttaki MultiProcessRunner girişine bakın)
Gerçek veri kümesi üzerinde uçtan uca kapsama testi
a. TensorBoard ile eğitim davranışlarını kontrol edin
- SGD gibi basit optimize ediciler ve önce
tf.distribute.OneDeviceStrategy
basit dağıtım stratejileri kullanın - eğitim metrikleri
- değerlendirme metrikleri
- doğal rastgelelik için makul toleransın ne olduğunu anlayın
B. Gelişmiş optimize edici/öğrenme oranı planlayıcı/dağıtım stratejileri ile denkliği kontrol edin
C. Karma hassasiyet kullanırken denkliği kontrol edin
- SGD gibi basit optimize ediciler ve önce
Ek ürün karşılaştırmaları
Kurmak
pip uninstall -y -q tensorflow
tutucu1 l10n-yer# Install tf-nightly as the DeterministicRandomTestTool is only available in
# Tensorflow 2.8
pip install -q tf-nightly
Tek ileri geçiş doğrulaması
Kontrol noktası yüklemesi de dahil olmak üzere tek ileri geçiş doğrulaması, farklı bir ortak çalışma kapsamında ele alınmaktadır .
import sys
import unittest
import numpy as np
import tensorflow as tf
import tensorflow.compat.v1 as v1
Birkaç adım için model eğitimi sayısal denklik doğrulaması
Model konfigürasyonunu ayarlayın ve sahte bir veri seti hazırlayın.
params = {
'input_size': 3,
'num_classes': 3,
'layer_1_size': 2,
'layer_2_size': 2,
'num_train_steps': 100,
'init_lr': 1e-3,
'end_lr': 0.0,
'decay_steps': 1000,
'lr_power': 1.0,
}
# make a small fixed dataset
fake_x = np.ones((2, params['input_size']), dtype=np.float32)
fake_y = np.zeros((2, params['num_classes']), dtype=np.int32)
fake_y[0][0] = 1
fake_y[1][1] = 1
step_num = 3
TF1.x modelini tanımlayın.
# Assume there is an existing TF1.x model using estimator API
# Wrap the model_fn to log necessary tensors for result comparison
class SimpleModelWrapper():
def __init__(self):
self.logged_ops = {}
self.logs = {
'step': [],
'lr': [],
'loss': [],
'grads_and_vars': [],
'layer_out': []}
def model_fn(self, features, labels, mode, params):
out_1 = tf.compat.v1.layers.dense(features, units=params['layer_1_size'])
out_2 = tf.compat.v1.layers.dense(out_1, units=params['layer_2_size'])
logits = tf.compat.v1.layers.dense(out_2, units=params['num_classes'])
loss = tf.compat.v1.losses.softmax_cross_entropy(labels, logits)
# skip EstimatorSpec details for prediction and evaluation
if mode == tf.estimator.ModeKeys.PREDICT:
pass
if mode == tf.estimator.ModeKeys.EVAL:
pass
assert mode == tf.estimator.ModeKeys.TRAIN
global_step = tf.compat.v1.train.get_or_create_global_step()
lr = tf.compat.v1.train.polynomial_decay(
learning_rate=params['init_lr'],
global_step=global_step,
decay_steps=params['decay_steps'],
end_learning_rate=params['end_lr'],
power=params['lr_power'])
optmizer = tf.compat.v1.train.GradientDescentOptimizer(lr)
grads_and_vars = optmizer.compute_gradients(
loss=loss,
var_list=graph.get_collection(
tf.compat.v1.GraphKeys.TRAINABLE_VARIABLES))
train_op = optmizer.apply_gradients(
grads_and_vars,
global_step=global_step)
# log tensors
self.logged_ops['step'] = global_step
self.logged_ops['lr'] = lr
self.logged_ops['loss'] = loss
self.logged_ops['grads_and_vars'] = grads_and_vars
self.logged_ops['layer_out'] = {
'layer_1': out_1,
'layer_2': out_2,
'logits': logits}
return tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op)
def update_logs(self, logs):
for key in logs.keys():
model_tf1.logs[key].append(logs[key])
Aşağıdaki v1.keras.utils.DeterministicRandomTestTool
sınıfı, durum bilgisi olan rastgele işlemlerin hem TF1 grafiklerinde/oturumlarında hem de istekli yürütmede aynı tohumu kullanmasını sağlayan bir bağlam yöneticisi scope()
sağlar,
Araç iki test modu sağlar:
- kaç kez çağrıldığına bakılmaksızın her bir işlem için aynı tohumu kullanan
constant
ve, - İşlem çekirdeği olarak önceden gözlemlenen durum bilgisi olan rastgele işlemlerin sayısını kullanan
num_random_ops
.
Bu, hem değişkenleri oluşturmak ve başlatmak için kullanılan durum bilgisi olan rasgele işlemler hem de hesaplamada kullanılan durum bilgisi olan rasgele işlemler (örneğin bırakma katmanları için) için geçerlidir.
random_tool = v1.keras.utils.DeterministicRandomTestTool(mode='num_random_ops')
tutucu6 l10n-yerWARNING:tensorflow:From /tmp/ipykernel_26769/2689227634.py:1: The name tf.keras.utils.DeterministicRandomTestTool is deprecated. Please use tf.compat.v1.keras.utils.DeterministicRandomTestTool instead.
TF1.x modelini grafik modunda çalıştırın. Sayısal denklik karşılaştırması için ilk 3 eğitim adımı için istatistikleri toplayın.
with random_tool.scope():
graph = tf.Graph()
with graph.as_default(), tf.compat.v1.Session(graph=graph) as sess:
model_tf1 = SimpleModelWrapper()
# build the model
inputs = tf.compat.v1.placeholder(tf.float32, shape=(None, params['input_size']))
labels = tf.compat.v1.placeholder(tf.float32, shape=(None, params['num_classes']))
spec = model_tf1.model_fn(inputs, labels, tf.estimator.ModeKeys.TRAIN, params)
train_op = spec.train_op
sess.run(tf.compat.v1.global_variables_initializer())
for step in range(step_num):
# log everything and update the model for one step
logs, _ = sess.run(
[model_tf1.logged_ops, train_op],
feed_dict={inputs: fake_x, labels: fake_y})
model_tf1.update_logs(logs)
tutucu8 l10n-yer/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:14: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead. /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/keras/legacy_tf_layers/core.py:261: UserWarning: `layer.apply` is deprecated and will be removed in a future version. Please use `layer.__call__` method instead. return layer.apply(inputs) /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:15: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead. from ipykernel import kernelapp as app /tmpfs/src/tf_docs_env/lib/python3.7/site-packages/ipykernel_launcher.py:16: UserWarning: `tf.layers.dense` is deprecated and will be removed in a future version. Please use `tf.keras.layers.Dense` instead. app.launch_new_instance()
TF2 modelini tanımlayın.
class SimpleModel(tf.keras.Model):
def __init__(self, params, *args, **kwargs):
super(SimpleModel, self).__init__(*args, **kwargs)
# define the model
self.dense_1 = tf.keras.layers.Dense(params['layer_1_size'])
self.dense_2 = tf.keras.layers.Dense(params['layer_2_size'])
self.out = tf.keras.layers.Dense(params['num_classes'])
learning_rate_fn = tf.keras.optimizers.schedules.PolynomialDecay(
initial_learning_rate=params['init_lr'],
decay_steps=params['decay_steps'],
end_learning_rate=params['end_lr'],
power=params['lr_power'])
self.optimizer = tf.keras.optimizers.SGD(learning_rate_fn)
self.compiled_loss = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
self.logs = {
'lr': [],
'loss': [],
'grads': [],
'weights': [],
'layer_out': []}
def call(self, inputs):
out_1 = self.dense_1(inputs)
out_2 = self.dense_2(out_1)
logits = self.out(out_2)
# log output features for every layer for comparison
layer_wise_out = {
'layer_1': out_1,
'layer_2': out_2,
'logits': logits}
self.logs['layer_out'].append(layer_wise_out)
return logits
def train_step(self, data):
x, y = data
with tf.GradientTape() as tape:
logits = self(x)
loss = self.compiled_loss(y, logits)
grads = tape.gradient(loss, self.trainable_weights)
# log training statistics
step = self.optimizer.iterations.numpy()
self.logs['lr'].append(self.optimizer.learning_rate(step).numpy())
self.logs['loss'].append(loss.numpy())
self.logs['grads'].append(grads)
self.logs['weights'].append(self.trainable_weights)
# update model
self.optimizer.apply_gradients(zip(grads, self.trainable_weights))
return
TF2 modelini istekli modda çalıştırın. Sayısal denklik karşılaştırması için ilk 3 eğitim adımı için istatistikleri toplayın.
random_tool = v1.keras.utils.DeterministicRandomTestTool(mode='num_random_ops')
with random_tool.scope():
model_tf2 = SimpleModel(params)
for step in range(step_num):
model_tf2.train_step([fake_x, fake_y])
İlk birkaç eğitim adımı için sayısal denkliği karşılaştırın.
Sayısal denklik için ek tavsiyeler için Doğruluğu doğrulama ve sayısal denklik not defterine de bakabilirsiniz.
np.testing.assert_allclose(model_tf1.logs['lr'], model_tf2.logs['lr'])
np.testing.assert_allclose(model_tf1.logs['loss'], model_tf2.logs['loss'])
for step in range(step_num):
for name in model_tf1.logs['layer_out'][step]:
np.testing.assert_allclose(
model_tf1.logs['layer_out'][step][name],
model_tf2.logs['layer_out'][step][name])
Birim testleri
Taşıma kodunuzda hata ayıklamaya yardımcı olabilecek birkaç birim testi türü vardır.
- Tek ileri geçiş doğrulaması
- Birkaç adım için model eğitimi sayısal denklik doğrulaması
- Karşılaştırmalı çıkarım performansı
- Eğitilmiş model, sabit ve basit veri noktalarında doğru tahminler yapar
Farklı konfigürasyonlara sahip modelleri test etmek için @parameterized.parameters
kullanabilirsiniz. Kod örneği ile ayrıntılar .
Aynı test senaryosunda oturum API'lerini ve istekli yürütmeyi çalıştırmanın mümkün olduğunu unutmayın. Aşağıdaki kod parçacıkları nasıl olduğunu gösterir.
import unittest
class TestNumericalEquivalence(unittest.TestCase):
# copied from code samples above
def setup(self):
# record statistics for 100 training steps
step_num = 100
# setup TF 1 model
random_tool = v1.keras.utils.DeterministicRandomTestTool(mode='num_random_ops')
with random_tool.scope():
# run TF1.x code in graph mode with context management
graph = tf.Graph()
with graph.as_default(), tf.compat.v1.Session(graph=graph) as sess:
self.model_tf1 = SimpleModelWrapper()
# build the model
inputs = tf.compat.v1.placeholder(tf.float32, shape=(None, params['input_size']))
labels = tf.compat.v1.placeholder(tf.float32, shape=(None, params['num_classes']))
spec = self.model_tf1.model_fn(inputs, labels, tf.estimator.ModeKeys.TRAIN, params)
train_op = spec.train_op
sess.run(tf.compat.v1.global_variables_initializer())
for step in range(step_num):
# log everything and update the model for one step
logs, _ = sess.run(
[self.model_tf1.logged_ops, train_op],
feed_dict={inputs: fake_x, labels: fake_y})
self.model_tf1.update_logs(logs)
# setup TF2 model
random_tool = v1.keras.utils.DeterministicRandomTestTool(mode='num_random_ops')
with random_tool.scope():
self.model_tf2 = SimpleModel(params)
for step in range(step_num):
self.model_tf2.train_step([fake_x, fake_y])
def test_learning_rate(self):
np.testing.assert_allclose(
self.model_tf1.logs['lr'],
self.model_tf2.logs['lr'])
def test_training_loss(self):
# adopt different tolerance strategies before and after 10 steps
first_n_step = 10
# abosolute difference is limited below 1e-5
# set `equal_nan` to be False to detect potential NaN loss issues
abosolute_tolerance = 1e-5
np.testing.assert_allclose(
actual=self.model_tf1.logs['loss'][:first_n_step],
desired=self.model_tf2.logs['loss'][:first_n_step],
atol=abosolute_tolerance,
equal_nan=False)
# relative difference is limited below 5%
relative_tolerance = 0.05
np.testing.assert_allclose(self.model_tf1.logs['loss'][first_n_step:],
self.model_tf2.logs['loss'][first_n_step:],
rtol=relative_tolerance,
equal_nan=False)
Hata ayıklama araçları
tf.baskı
tf.print ve print/logging.info karşılaştırması
- Yapılandırılabilir argümanlarla,
tf.print
, basılı tensörler için her boyutun ilk ve son birkaç öğesini yinelemeli olarak gösterebilir. Ayrıntılar için API belgelerine bakın. - İstekli yürütme için, hem
print
hem detf.print
, tensörün değerini yazdırır. Ancakprint
, kodunuzu potansiyel olarak yavaşlatabilecek aygıttan ana bilgisayara kopyalamayı içerebilir. -
tf.function
içindeki kullanımı içeren grafik modu için, gerçek tensör değerini yazdırmak içintf.print
kullanmanız gerekir.tf.print
grafikte bir op olarak derlenirken,print
velogging.info
yalnızca izleme zamanında oturum açar, bu genellikle istediğiniz şey değildir. -
tf.print
ayrıcatf.RaggedTensor
vetf.sparse.SparseTensor
gibi bileşik tensörlerin yazdırılmasını da destekler. - Metrikleri ve değişkenleri izlemek için bir geri arama da kullanabilirsiniz. Lütfen günlükler dict ve self.model özniteliği ile özel geri aramaların nasıl kullanılacağını kontrol edin.
tf.print vs tf.function içindeki baskı
# `print` prints info of tensor object
# `tf.print` prints the tensor value
@tf.function
def dummy_func(num):
num += 1
print(num)
tf.print(num)
return num
_ = dummy_func(tf.constant([1.0]))
# Output:
# Tensor("add:0", shape=(1,), dtype=float32)
# [2]
tutucu14 l10n-yerTensor("add:0", shape=(1,), dtype=float32) [2]
tf.distribute.Strateji
-
tf.function
içerentf.print
, örneğinTPUStrategy
veyaParameterServerStrategy
kullanırken işçiler üzerinde yürütülürse, yazdırılan değerleri bulmak için çalışan/parametre sunucusu günlüklerini kontrol etmeniz gerekir. -
print
veyalogging.info
için,ParameterServerStrategy
kullanılırken günlükler koordinatörde yazdırılacak ve TPU'lar kullanılırken günlükler işçi0 üzerindeki STDOUT'ta yazdırılacaktır.
tf.keras.Model
- Sıralı ve Fonksiyonel API modellerini kullanırken bazı katmanlardan sonra model girdileri veya ara özellikler gibi değerleri yazdırmak istiyorsanız aşağıdaki seçeneklere sahipsiniz.
- Girdileri
tf.print
özel bir katman yazın . - İncelemek istediğiniz ara çıktıları model çıktılarına dahil edin.
- Girdileri
-
tf.keras.layers.Lambda
katmanları (de)serileştirme sınırlamalarına sahiptir. Kontrol noktası yükleme sorunlarını önlemek için bunun yerine özel bir alt sınıf katmanı yazın. Daha fazla ayrıntı için API belgelerine bakın. - Gerçek değerlere erişiminiz yoksa, bunun yerine yalnızca sembolik Keras tensör nesnelerine erişiminiz varsa, bir
tf.print
içinde ara çıktılarıtf.keras.callbacks.LambdaCallback
.
Seçenek 1: özel bir katman yazın
class PrintLayer(tf.keras.layers.Layer):
def call(self, inputs):
tf.print(inputs)
return inputs
def get_model():
inputs = tf.keras.layers.Input(shape=(1,))
out_1 = tf.keras.layers.Dense(4)(inputs)
out_2 = tf.keras.layers.Dense(1)(out_1)
# use custom layer to tf.print intermediate features
out_3 = PrintLayer()(out_2)
model = tf.keras.Model(inputs=inputs, outputs=out_3)
return model
model = get_model()
model.compile(optimizer="adam", loss="mse")
model.fit([1, 2, 3], [0.0, 0.0, 1.0])
tutucu16 l10n-yer[[-0.327884018] [-0.109294668] [-0.218589336]] 1/1 [==============================] - 0s 280ms/step - loss: 0.6077 <keras.callbacks.History at 0x7f63d46bf190>
Seçenek 2: incelemek istediğiniz ara çıktıları model çıktılarına dahil edin.
Böyle bir durumda Model.fit
kullanmak için bazı özelleştirmelere ihtiyacınız olabileceğini unutmayın.
def get_model():
inputs = tf.keras.layers.Input(shape=(1,))
out_1 = tf.keras.layers.Dense(4)(inputs)
out_2 = tf.keras.layers.Dense(1)(out_1)
# include intermediate values in model outputs
model = tf.keras.Model(
inputs=inputs,
outputs={
'inputs': inputs,
'out_1': out_1,
'out_2': out_2})
return model
pdb
Hata ayıklama için ara değerleri incelemek için hem terminalde hem de Colab'da pdb'yi kullanabilirsiniz.
Grafiği TensorBoard ile görselleştirin
TensorFlow grafiğini TensorBoard ile inceleyebilirsiniz . TensorBoard ayrıca colab üzerinde desteklenir . TensorBoard, özetleri görselleştirmek için harika bir araçtır. Öğrenme hızını, model ağırlıklarını, gradyan ölçeğini, eğitim/doğrulama ölçümlerini karşılaştırmak ve hatta eğitim süreci aracılığıyla TF1.x modeli ile taşınan TF2 modeli arasındaki ara çıktıları modellemek ve değerlerin beklendiği gibi görünüp görünmediğini görmek için kullanabilirsiniz.
TensorFlow Profil Oluşturucu
TensorFlow Profiler , GPU'larda/TPU'larda yürütme zaman çizelgesini görselleştirmenize yardımcı olabilir. Temel kullanımı için bu Colab Demosuna göz atabilirsiniz.
MultiProcessRunner
MultiProcessRunner , MultiWorkerMirrorredStrategy ve ParameterServerStrategy ile hata ayıklama yaparken kullanışlı bir araçtır. Kullanımı için bu somut örneğe göz atabilirsiniz.
Spesifik olarak bu iki stratejinin durumları için, 1) yalnızca akışlarını kapsayacak birim testlerine sahip olmanız değil, 2) aynı zamanda her girişimde gerçek dağıtılmış işi başlatmaktan kaçınmak için birim testinde kullanarak hataları yeniden oluşturmaya çalışmanız önerilir. bir düzeltme.