Grafiklere ve tf.fonksiyonuna giriş

TensorFlow.org'da görüntüleyin Google Colab'da çalıştırın Kaynağı GitHub'da görüntüleyin Not defterini indir

genel bakış

Bu kılavuz, TensorFlow'un nasıl çalıştığını göstermek için TensorFlow ve Keras'ın yüzeyinin altına iner. Bunun yerine Keras'ı hemen kullanmaya başlamak istiyorsanız , Keras kılavuzları koleksiyonuna göz atın .

Bu kılavuzda, TensorFlow'un grafikler almak için kodunuzda basit değişiklikler yapmanıza nasıl izin verdiğini, grafiklerin nasıl saklandığını ve temsil edildiğini ve modellerinizi hızlandırmak için bunları nasıl kullanabileceğinizi öğreneceksiniz.

Bu, tf.function hevesli yürütmeden grafik yürütmeye geçmenize nasıl izin verdiğini kapsayan büyük resmi bir genel bakıştır. tf.function ile ilgili daha eksiksiz bir belirtim için, tf.function tf.function gidin.

grafikler nedir?

Önceki üç kılavuzda, TensorFlow'u hevesle çalıştırdınız. Bu, TensorFlow işlemlerinin Python tarafından yürütüldüğü, operasyondan operasyona ve sonuçların Python'a geri döndürüldüğü anlamına gelir.

İstekli yürütmenin birkaç benzersiz avantajı olsa da, grafik yürütme Python dışında taşınabilirlik sağlar ve daha iyi performans sunma eğilimindedir. Grafik yürütme , tensör hesaplamalarının bazen bir tf.Graph veya yalnızca bir "grafik" olarak adlandırılan bir TensorFlow grafiği olarak yürütüldüğü anlamına gelir.

Grafikler, hesaplama birimlerini temsil eden bir dizi tf.Operation nesnesi içeren veri yapılarıdır; ve işlemler arasında akan veri birimlerini temsil eden tf.Tensor nesneleri. Bir tf.Graph bağlamında tanımlanırlar. Bu grafikler veri yapıları olduğundan, orijinal Python kodu olmadan kaydedilebilir, çalıştırılabilir ve geri yüklenebilir.

İki katmanlı bir sinir ağını temsil eden bir TensorFlow grafiği, TensorBoard'da görselleştirildiğinde böyle görünür.

Basit bir TensorFlow grafiği

Grafiklerin faydaları

Bir grafikle büyük bir esnekliğe sahipsiniz. TensorFlow grafiğinizi, mobil uygulamalar, gömülü cihazlar ve arka uç sunucuları gibi Python yorumlayıcısı olmayan ortamlarda kullanabilirsiniz. TensorFlow, Python'dan dışa aktarırken kaydedilen modeller için format olarak grafikleri kullanır.

Grafikler de kolayca optimize edilerek derleyicinin aşağıdaki gibi dönüşümler yapmasına olanak tanır:

  • Hesaplamanızdaki sabit düğümleri katlayarak ("sabit katlama") tensörlerin değerini statik olarak çıkarın.
  • Bir hesaplamanın bağımsız olan ve bunları iş parçacıkları veya aygıtlar arasında bölen ayrı alt bölümleri.
  • Ortak alt ifadeleri ortadan kaldırarak aritmetik işlemleri basitleştirin.

Bu ve diğer hızlandırmaları gerçekleştirmek için eksiksiz bir optimizasyon sistemi Grappler var.

Kısacası, grafikler son derece kullanışlıdır ve TensorFlow'unuzun hızlı çalışmasına , paralel çalışmasına ve birden çok cihazda verimli çalışmasına izin verir.

Ancak yine de kolaylık sağlamak için makine öğrenimi modellerinizi (veya diğer hesaplamaları) Python'da tanımlamak ve ardından ihtiyacınız olduğunda otomatik olarak grafikler oluşturmak istiyorsunuz.

Kurmak

import tensorflow as tf
import timeit
from datetime import datetime

Grafiklerden yararlanma

Doğrudan çağrı veya dekoratör olarak tf.function kullanarak tf.function bir grafik oluşturur ve çalıştırırsınız. tf.function normal bir işlevi girdi olarak alır ve bir Function döndürür. Function , Python işlevinden TensorFlow grafikleri oluşturan bir Python çağrılabilir. Bir Function Python eşdeğeriyle aynı şekilde kullanırsınız.

# Define a Python function.
def a_regular_function(x, y, b):
  x = tf.matmul(x, y)
  x = x + b
  return x

# `a_function_that_uses_a_graph` is a TensorFlow `Function`.
a_function_that_uses_a_graph = tf.function(a_regular_function)

# Make some tensors.
x1 = tf.constant([[1.0, 2.0]])
y1 = tf.constant([[2.0], [3.0]])
b1 = tf.constant(4.0)

orig_value = a_regular_function(x1, y1, b1).numpy()
# Call a `Function` like a Python function.
tf_function_value = a_function_that_uses_a_graph(x1, y1, b1).numpy()
assert(orig_value == tf_function_value)

Dışarıdan bir Function , TensorFlow işlemlerini kullanarak yazdığınız normal bir işleve benzer. Ancak alt tarafı çok farklı . Bir Function , bir API'nin arkasında birkaç tf.Graph s içerir . Function , grafik yürütmenin hız ve konuşlandırılabilirlik gibi avantajlarını bu şekilde sağlayabilir.

tf.function bir işleve ve çağırdığı diğer tüm işlevlere uygulanır:

def inner_function(x, y, b):
  x = tf.matmul(x, y)
  x = x + b
  return x

# Use the decorator to make `outer_function` a `Function`.
@tf.function
def outer_function(x):
  y = tf.constant([[2.0], [3.0]])
  b = tf.constant(4.0)

  return inner_function(x, y, b)

# Note that the callable will create a graph that
# includes `inner_function` as well as `outer_function`.
outer_function(tf.constant([[1.0, 2.0]])).numpy()
tutucu3 l10n-yer
array([[12.]], dtype=float32)

TensorFlow 1.x kullandıysanız, hiçbir zaman Placeholder veya tf.Session tanımlamanız gerekmediğini fark edeceksiniz.

Python fonksiyonlarını grafiklere dönüştürme

TensorFlow ile yazdığınız herhangi bir işlev, yerleşik TF işlemleri ile if-then yan tümceleri, döngüler, break , return , continue ve daha fazlası gibi Python mantığının bir karışımını içerecektir. TensorFlow işlemleri bir tf.Graph tarafından kolayca yakalanırken, Python'a özgü mantığın grafiğin bir parçası olabilmesi için fazladan bir adımdan geçmesi gerekir. tf.function Python kodunu grafik oluşturan koda dönüştürmek için AutoGraph ( tf.autograph ) adlı bir kitaplık kullanır.

def simple_relu(x):
  if tf.greater(x, 0):
    return x
  else:
    return 0

# `tf_simple_relu` is a TensorFlow `Function` that wraps `simple_relu`.
tf_simple_relu = tf.function(simple_relu)

print("First branch, with graph:", tf_simple_relu(tf.constant(1)).numpy())
print("Second branch, with graph:", tf_simple_relu(tf.constant(-1)).numpy())
tutucu5 l10n-yer
First branch, with graph: 1
Second branch, with graph: 0

Grafikleri doğrudan görüntülemeniz pek olası olmasa da, kesin sonuçları kontrol etmek için çıktıları inceleyebilirsiniz. Bunları okumak kolay değil, bu yüzden çok dikkatli bakmanıza gerek yok!

# This is the graph-generating output of AutoGraph.
print(tf.autograph.to_code(simple_relu))
def tf__simple_relu(x):
    with ag__.FunctionScope('simple_relu', 'fscope', ag__.ConversionOptions(recursive=True, user_requested=True, optional_features=(), internal_convert_user_code=True)) as fscope:
        do_return = False
        retval_ = ag__.UndefinedReturnValue()

        def get_state():
            return (do_return, retval_)

        def set_state(vars_):
            nonlocal retval_, do_return
            (do_return, retval_) = vars_

        def if_body():
            nonlocal retval_, do_return
            try:
                do_return = True
                retval_ = ag__.ld(x)
            except:
                do_return = False
                raise

        def else_body():
            nonlocal retval_, do_return
            try:
                do_return = True
                retval_ = 0
            except:
                do_return = False
                raise
        ag__.if_stmt(ag__.converted_call(ag__.ld(tf).greater, (ag__.ld(x), 0), None, fscope), if_body, else_body, get_state, set_state, ('do_return', 'retval_'), 2)
        return fscope.ret(retval_, do_return)
yer tutucu8 l10n-yer
# This is the graph itself.
print(tf_simple_relu.get_concrete_function(tf.constant(1)).graph.as_graph_def())
node {
  name: "x"
  op: "Placeholder"
  attr {
    key: "_user_specified_name"
    value {
      s: "x"
    }
  }
  attr {
    key: "dtype"
    value {
      type: DT_INT32
    }
  }
  attr {
    key: "shape"
    value {
      shape {
      }
    }
  }
}
node {
  name: "Greater/y"
  op: "Const"
  attr {
    key: "dtype"
    value {
      type: DT_INT32
    }
  }
  attr {
    key: "value"
    value {
      tensor {
        dtype: DT_INT32
        tensor_shape {
        }
        int_val: 0
      }
    }
  }
}
node {
  name: "Greater"
  op: "Greater"
  input: "x"
  input: "Greater/y"
  attr {
    key: "T"
    value {
      type: DT_INT32
    }
  }
}
node {
  name: "cond"
  op: "StatelessIf"
  input: "Greater"
  input: "x"
  attr {
    key: "Tcond"
    value {
      type: DT_BOOL
    }
  }
  attr {
    key: "Tin"
    value {
      list {
        type: DT_INT32
      }
    }
  }
  attr {
    key: "Tout"
    value {
      list {
        type: DT_BOOL
        type: DT_INT32
      }
    }
  }
  attr {
    key: "_lower_using_switch_merge"
    value {
      b: true
    }
  }
  attr {
    key: "_read_only_resource_inputs"
    value {
      list {
      }
    }
  }
  attr {
    key: "else_branch"
    value {
      func {
        name: "cond_false_34"
      }
    }
  }
  attr {
    key: "output_shapes"
    value {
      list {
        shape {
        }
        shape {
        }
      }
    }
  }
  attr {
    key: "then_branch"
    value {
      func {
        name: "cond_true_33"
      }
    }
  }
}
node {
  name: "cond/Identity"
  op: "Identity"
  input: "cond"
  attr {
    key: "T"
    value {
      type: DT_BOOL
    }
  }
}
node {
  name: "cond/Identity_1"
  op: "Identity"
  input: "cond:1"
  attr {
    key: "T"
    value {
      type: DT_INT32
    }
  }
}
node {
  name: "Identity"
  op: "Identity"
  input: "cond/Identity_1"
  attr {
    key: "T"
    value {
      type: DT_INT32
    }
  }
}
library {
  function {
    signature {
      name: "cond_false_34"
      input_arg {
        name: "cond_placeholder"
        type: DT_INT32
      }
      output_arg {
        name: "cond_identity"
        type: DT_BOOL
      }
      output_arg {
        name: "cond_identity_1"
        type: DT_INT32
      }
    }
    node_def {
      name: "cond/Const"
      op: "Const"
      attr {
        key: "dtype"
        value {
          type: DT_BOOL
        }
      }
      attr {
        key: "value"
        value {
          tensor {
            dtype: DT_BOOL
            tensor_shape {
            }
            bool_val: true
          }
        }
      }
    }
    node_def {
      name: "cond/Const_1"
      op: "Const"
      attr {
        key: "dtype"
        value {
          type: DT_BOOL
        }
      }
      attr {
        key: "value"
        value {
          tensor {
            dtype: DT_BOOL
            tensor_shape {
            }
            bool_val: true
          }
        }
      }
    }
    node_def {
      name: "cond/Const_2"
      op: "Const"
      attr {
        key: "dtype"
        value {
          type: DT_INT32
        }
      }
      attr {
        key: "value"
        value {
          tensor {
            dtype: DT_INT32
            tensor_shape {
            }
            int_val: 0
          }
        }
      }
    }
    node_def {
      name: "cond/Const_3"
      op: "Const"
      attr {
        key: "dtype"
        value {
          type: DT_BOOL
        }
      }
      attr {
        key: "value"
        value {
          tensor {
            dtype: DT_BOOL
            tensor_shape {
            }
            bool_val: true
          }
        }
      }
    }
    node_def {
      name: "cond/Identity"
      op: "Identity"
      input: "cond/Const_3:output:0"
      attr {
        key: "T"
        value {
          type: DT_BOOL
        }
      }
    }
    node_def {
      name: "cond/Const_4"
      op: "Const"
      attr {
        key: "dtype"
        value {
          type: DT_INT32
        }
      }
      attr {
        key: "value"
        value {
          tensor {
            dtype: DT_INT32
            tensor_shape {
            }
            int_val: 0
          }
        }
      }
    }
    node_def {
      name: "cond/Identity_1"
      op: "Identity"
      input: "cond/Const_4:output:0"
      attr {
        key: "T"
        value {
          type: DT_INT32
        }
      }
    }
    ret {
      key: "cond_identity"
      value: "cond/Identity:output:0"
    }
    ret {
      key: "cond_identity_1"
      value: "cond/Identity_1:output:0"
    }
    attr {
      key: "_construction_context"
      value {
        s: "kEagerRuntime"
      }
    }
    arg_attr {
      key: 0
      value {
        attr {
          key: "_output_shapes"
          value {
            list {
              shape {
              }
            }
          }
        }
      }
    }
  }
  function {
    signature {
      name: "cond_true_33"
      input_arg {
        name: "cond_identity_1_x"
        type: DT_INT32
      }
      output_arg {
        name: "cond_identity"
        type: DT_BOOL
      }
      output_arg {
        name: "cond_identity_1"
        type: DT_INT32
      }
    }
    node_def {
      name: "cond/Const"
      op: "Const"
      attr {
        key: "dtype"
        value {
          type: DT_BOOL
        }
      }
      attr {
        key: "value"
        value {
          tensor {
            dtype: DT_BOOL
            tensor_shape {
            }
            bool_val: true
          }
        }
      }
    }
    node_def {
      name: "cond/Identity"
      op: "Identity"
      input: "cond/Const:output:0"
      attr {
        key: "T"
        value {
          type: DT_BOOL
        }
      }
    }
    node_def {
      name: "cond/Identity_1"
      op: "Identity"
      input: "cond_identity_1_x"
      attr {
        key: "T"
        value {
          type: DT_INT32
        }
      }
    }
    ret {
      key: "cond_identity"
      value: "cond/Identity:output:0"
    }
    ret {
      key: "cond_identity_1"
      value: "cond/Identity_1:output:0"
    }
    attr {
      key: "_construction_context"
      value {
        s: "kEagerRuntime"
      }
    }
    arg_attr {
      key: 0
      value {
        attr {
          key: "_output_shapes"
          value {
            list {
              shape {
              }
            }
          }
        }
      }
    }
  }
}
versions {
  producer: 898
  min_consumer: 12
}

Çoğu zaman, tf.function özel hususlar olmadan çalışacaktır. Ancak, bazı uyarılar vardır ve tf.function kılavuzunun yanı sıra tam Otomatik Grafik referansı da burada yardımcı olabilir.

Polimorfizm: bir Function , birçok grafik

Bir tf.Graph , belirli bir girdi türü için özelleştirilir (örneğin, belirli bir dtype sahip tensörler veya aynı id() ile nesneler).

tf.Graph değişkenlerinde yeni türler ve şekiller içeren bir Function her çağırdığınızda, Function yeni bağımsız değişkenler için yeni bir dtypes oluşturur. Bir dtypes girdilerinin tf.Graph ve şekilleri, bir girdi imzası veya sadece bir imza olarak bilinir.

Function , bu imzaya karşılık gelen tf.Graph bir ConcreteFunction içinde saklar. Bir ConcreteFunction , bir tf.Graph etrafındaki bir tf.Graph .

@tf.function
def my_relu(x):
  return tf.maximum(0., x)

# `my_relu` creates new graphs as it observes more signatures.
print(my_relu(tf.constant(5.5)))
print(my_relu([1, -1]))
print(my_relu(tf.constant([3., -3.])))
tutucu11 l10n-yer
tf.Tensor(5.5, shape=(), dtype=float32)
tf.Tensor([1. 0.], shape=(2,), dtype=float32)
tf.Tensor([3. 0.], shape=(2,), dtype=float32)

Function bu imzayla zaten çağrıldıysa, Function yeni bir tf.Graph oluşturmaz.

# These two calls do *not* create new graphs.
print(my_relu(tf.constant(-2.5))) # Signature matches `tf.constant(5.5)`.
print(my_relu(tf.constant([-1., 1.]))) # Signature matches `tf.constant([3., -3.])`.
tutucu13 l10n-yer
tf.Tensor(0.0, shape=(), dtype=float32)
tf.Tensor([0. 1.], shape=(2,), dtype=float32)

Birden çok grafikle desteklendiğinden, bir Function polimorfiktir . Bu, tek bir tf.Graph temsil edebileceğinden daha fazla girdi türünü desteklemesini ve her bir tf.Graph daha iyi performans için optimize etmesini sağlar.

# There are three `ConcreteFunction`s (one for each graph) in `my_relu`.
# The `ConcreteFunction` also knows the return type and shape!
print(my_relu.pretty_printed_concrete_signatures())
tutucu15 l10n-yer
my_relu(x)
  Args:
    x: float32 Tensor, shape=()
  Returns:
    float32 Tensor, shape=()

my_relu(x=[1, -1])
  Returns:
    float32 Tensor, shape=(2,)

my_relu(x)
  Args:
    x: float32 Tensor, shape=(2,)
  Returns:
    float32 Tensor, shape=(2,)

tf.function kullanma

Şimdiye kadar, bir dekoratör veya sarmalayıcı olarak tf.function kullanarak bir Python fonksiyonunu bir grafiğe nasıl dönüştüreceğinizi öğrendiniz. Ancak pratikte, tf.function işlevinin doğru şekilde çalışmasını sağlamak zor olabilir! Aşağıdaki bölümlerde, kodunuzu tf.function ile beklendiği gibi nasıl çalıştırabileceğinizi öğreneceksiniz.

Grafik yürütme ve istekli yürütme

Bir Function kod hem hevesle hem de grafik olarak yürütülebilir. Varsayılan olarak, Function kodunu bir grafik olarak yürütür:

@tf.function
def get_MSE(y_true, y_pred):
  sq_diff = tf.pow(y_true - y_pred, 2)
  return tf.reduce_mean(sq_diff)
y_true = tf.random.uniform([5], maxval=10, dtype=tf.int32)
y_pred = tf.random.uniform([5], maxval=10, dtype=tf.int32)
print(y_true)
print(y_pred)
tf.Tensor([1 0 4 4 7], shape=(5,), dtype=int32)
tf.Tensor([3 6 3 0 6], shape=(5,), dtype=int32)
get_MSE(y_true, y_pred)
<tf.Tensor: shape=(), dtype=int32, numpy=11>

Function grafiğinizin eşdeğer Python işleviyle aynı hesaplamayı yaptığını doğrulamak için, tf.config.run_functions_eagerly(True) ile hevesle çalışmasını sağlayabilirsiniz. Bu, İşlev'in kodu normal şekilde yürütmek yerine Function oluşturma ve çalıştırma yeteneğini kapatan bir anahtardır.

tf.config.run_functions_eagerly(True)
get_MSE(y_true, y_pred)
yer tutucu23 l10n-yer
<tf.Tensor: shape=(), dtype=int32, numpy=11>
# Don't forget to set it back when you are done.
tf.config.run_functions_eagerly(False)

Bununla birlikte, Function , grafik ve istekli yürütme altında farklı davranabilir. Python print işlevi, bu iki modun nasıl farklılaştığına bir örnektir. Fonksiyonunuza bir print deyimi eklediğinizde ve onu tekrar tekrar çağırdığınızda ne olduğuna bakalım.

@tf.function
def get_MSE(y_true, y_pred):
  print("Calculating MSE!")
  sq_diff = tf.pow(y_true - y_pred, 2)
  return tf.reduce_mean(sq_diff)

Ne basıldığını gözlemleyin:

error = get_MSE(y_true, y_pred)
error = get_MSE(y_true, y_pred)
error = get_MSE(y_true, y_pred)
tutucu27 l10n-yer
Calculating MSE!

Çıktı şaşırtıcı mı? get_MSE , üç kez çağrılmasına rağmen yalnızca bir kez yazdırılır.

Açıklamak için, print ifadesi, "tracing" olarak bilinen bir işlemde grafiği oluşturmak için Function orijinal kodu çalıştırdığında yürütülür. İzleme, TensorFlow işlemlerini bir grafikte yakalar ve print grafikte yakalanmaz. Bu grafik daha sonra Python kodunu tekrar çalıştırmadan üç çağrının tümü için yürütülür.

Akıl sağlığı kontrolü olarak, karşılaştırmak için grafik yürütmeyi kapatalım:

# Now, globally set everything to run eagerly to force eager execution.
tf.config.run_functions_eagerly(True)
# Observe what is printed below.
error = get_MSE(y_true, y_pred)
error = get_MSE(y_true, y_pred)
error = get_MSE(y_true, y_pred)
yer tutucu30 l10n-yer
Calculating MSE!
Calculating MSE!
Calculating MSE!
tf.config.run_functions_eagerly(False)

print bir Python yan etkisidir ve bir Function bir İşleve dönüştürürken bilmeniz gereken başka farklılıklar da vardır. tf ile daha iyi performans kılavuzunun Sınırlamalar bölümünde daha fazla bilgi edinin.

katı olmayan yürütme

Grafik yürütme, yalnızca aşağıdakileri içeren gözlemlenebilir etkileri üretmek için gerekli işlemleri yürütür:

  • Fonksiyonun dönüş değeri
  • Aşağıdakiler gibi belgelenmiş iyi bilinen yan etkiler:

Bu davranış genellikle "Kesin olmayan yürütme" olarak bilinir ve gerekli olsun veya olmasın tüm program işlemlerinde adım adım ilerleyen istekli yürütmeden farklıdır.

Özellikle, çalışma zamanı hata denetimi, gözlemlenebilir bir etki olarak sayılmaz. Bir işlem gereksiz olduğu için atlanırsa, herhangi bir çalışma zamanı hatası oluşturamaz.

Aşağıdaki örnekte, grafik yürütme sırasında "gereksiz" tf.gather işlemi atlanır, bu nedenle çalışma zamanı hatası InvalidArgumentError , istekli yürütmede olacağı için ortaya çıkmaz. Bir grafiği yürütürken ortaya çıkan bir hataya güvenmeyin.

def unused_return_eager(x):
  # Get index 1 will fail when `len(x) == 1`
  tf.gather(x, [1]) # unused 
  return x

try:
  print(unused_return_eager(tf.constant([0.0])))
except tf.errors.InvalidArgumentError as e:
  # All operations are run during eager execution so an error is raised.
  print(f'{type(e).__name__}: {e}')
tf.Tensor([0.], shape=(1,), dtype=float32)
yer tutucu34 l10n-yer
@tf.function
def unused_return_graph(x):
  tf.gather(x, [1]) # unused
  return x

# Only needed operations are run during graph exection. The error is not raised.
print(unused_return_graph(tf.constant([0.0])))
tf.Tensor([0.], shape=(1,), dtype=float32)

tf.function en iyi uygulamaları

Function davranışına alışmak biraz zaman alabilir. Hızlı bir şekilde başlamak için, ilk kez kullananlar, hevesliden grafik yürütmeye geçme konusunda deneyim kazanmak için @tf.function ile oyuncak fonksiyonlarını süslemelidir.

tf.function için tasarım yapmak , grafik uyumlu TensorFlow programları yazmak için en iyi seçeneğiniz olabilir. İşte bazı ipuçları:

  • tf.config.run_functions_eagerly ile istekli ve grafik yürütme arasında erken ve sıklıkla geçiş yapın ve iki modun birbirinden ayrılıp ayrılmadığını/ne zaman ayrıldığını tam olarak belirleyin.
  • Python işlevinin dışında tf.Variable s oluşturun ve bunları içeride değiştirin. tf.Variable , keras.layers, keras.Model s ve tf.optimizers gibi keras.layers kullanan nesneler için de geçerlidir.
  • tf.Variable s ve Keras nesneleri hariç , dış Python değişkenlerine bağlı işlevler yazmaktan kaçının.
  • Girdi olarak tensörleri ve diğer TensorFlow türlerini alan fonksiyonlar yazmayı tercih edin. Diğer nesne türlerini de geçebilirsin ama dikkatli ol !
  • Performans kazancını en üst düzeye çıkarmak için bir tf.function . işlevi altında mümkün olduğunca fazla hesaplama ekleyin. Örneğin, tüm eğitim adımını veya tüm eğitim döngüsünü süsleyin.

Hızlanmayı görmek

tf.function genellikle kodunuzun performansını artırır, ancak hızlanma miktarı, çalıştırdığınız hesaplama türüne bağlıdır. Küçük hesaplamalar, bir grafiği çağırmanın ek yükü tarafından domine edilebilir. Performans farkını şu şekilde ölçebilirsiniz:

x = tf.random.uniform(shape=[10, 10], minval=-1, maxval=2, dtype=tf.dtypes.int32)

def power(x, y):
  result = tf.eye(10, dtype=tf.dtypes.int32)
  for _ in range(y):
    result = tf.matmul(x, result)
  return result
print("Eager execution:", timeit.timeit(lambda: power(x, 100), number=1000))
Eager execution: 2.5637862179974036
power_as_graph = tf.function(power)
print("Graph execution:", timeit.timeit(lambda: power_as_graph(x, 100), number=1000))
Graph execution: 0.6832536700021592

tf.function genellikle eğitim döngülerini hızlandırmak için kullanılır ve bununla ilgili daha fazla bilgiyi Keras ile sıfırdan eğitim döngüsü yazma bölümünde bulabilirsiniz.

Performans ve takaslar

Grafikler kodunuzu hızlandırabilir, ancak bunları oluşturma sürecinin biraz yükü vardır. Bazı işlevler için grafiğin oluşturulması, grafiğin yürütülmesinden daha fazla zaman alır. Bu yatırım, genellikle sonraki yürütmelerin performans artışıyla hızlı bir şekilde geri ödenir, ancak herhangi bir büyük model eğitiminin ilk birkaç adımının izleme nedeniyle daha yavaş olabileceğini bilmek önemlidir.

Modeliniz ne kadar büyük olursa olsun, sık sık takip etmekten kaçınmak istersiniz. tf.function kılavuzu, giriş özelliklerinin nasıl ayarlanacağını ve geri izlemeyi önlemek için tensör bağımsız değişkenlerinin nasıl kullanılacağını açıklar. Alışılmadık derecede düşük performans aldığınızı fark ederseniz, yanlışlıkla geri dönüp bakmadığınızı kontrol etmek iyi bir fikirdir.

Bir Function izleme ne zaman yapılır?

Function ne zaman izleme yaptığını anlamak için koduna bir print deyimi ekleyin. Temel bir kural olarak, Function , her izlediğinde print deyimini yürütür.

@tf.function
def a_function_with_python_side_effect(x):
  print("Tracing!") # An eager-only side effect.
  return x * x + tf.constant(2)

# This is traced the first time.
print(a_function_with_python_side_effect(tf.constant(2)))
# The second time through, you won't see the side effect.
print(a_function_with_python_side_effect(tf.constant(3)))
Tracing!
tf.Tensor(6, shape=(), dtype=int32)
tf.Tensor(11, shape=(), dtype=int32)
yer tutucu43 l10n-yer
# This retraces each time the Python argument changes,
# as a Python argument could be an epoch count or other
# hyperparameter.
print(a_function_with_python_side_effect(2))
print(a_function_with_python_side_effect(3))
Tracing!
tf.Tensor(6, shape=(), dtype=int32)
Tracing!
tf.Tensor(11, shape=(), dtype=int32)

Yeni Python argümanları her zaman yeni bir grafiğin oluşturulmasını tetikler, dolayısıyla ekstra izleme.

Sonraki adımlar

API referans sayfasından ve tf.function ile daha iyi performans kılavuzunu izleyerek tf.function hakkında daha fazla bilgi edinebilirsiniz.