Yardım Kaggle üzerinde TensorFlow ile Büyük Bariyer Resifi korumak Meydan Üyelik

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 hemen keras başlamak istiyorsanız, check out Keras kılavuzları koleksiyonu .

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 nasıl kapakları o büyük bir çerçeveden bakış niteliğindedir tf.function de grafik yürütme istekli yürütme arasında geçiş sağlar. Daha tam teknik özellikleri için tf.function , gidin tf.function rehberi .

Grafikler nedir?

Bir önceki üç kılavuzları, sen hevesle TensorFlow koştu. 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 aracı tensör hesaplamaları bazen şu şekilde ifade edilen bir TensorFlow grafik olarak yürütülür ki tf.Graph veya basitçe bir "grafiği."

Grafikler bir dizi içeren veri yapıları tf.Operation hesaplama birimini temsil eden nesneler; ve tf.Tensor işlemleri arasında akış veri birimlerini temsil eden nesneleri. Bir tanımlanır tf.Graph bağlamında. 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 için biçim olarak grafikler kullanır kaydedilen modeller Python onları ihraç ediyor.

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

  • Statik için hesaplama ( "sabit katlama") sabit düğümleri katlanarak tansörleri değerini çıkarılabilir.
  • 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.

Bütün bir optimizasyon sistemi vardır Grappler bu ve diğer kat hızlanma gerçekleştirmek.

Kısacası, grafikler oldukça yararlıdır ve sizin TensorFlow paralel olarak çalıştıran hızlı çalışmasına izin ve birden fazla cihazda verimli çalışır.

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

Oluşturabilir ve kullanarak TensorFlow bir grafik çalıştırmak tf.function doğrudan çağrı olarak veya bir dekoratör olarak ister. tf.function girdi olarak düzenli bir işlev alır ve bir döner Function . Bir Function Python işlevinden TensorFlow grafikleri oluşturur bir Python çağrılabilir. Bir kullanmak Function onun Python eşdeğeri olarak aynı şekilde.

# 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 düzenli fonksiyonu gibi görünüyor Eğer TensorFlow işlemlerini kullanarak yazma. Altında ise çok farklıdır. Bir Function kapsüller birkaç tf.Graph bir API arkasında s . Yani nasıl Function size verebilecek grafik yürütme faydalarını hız ve konuşlandırılabilirliğini gibi.

tf.function bir fonksiyonu ve onu çağıran tüm diğer fonksiyonlar için de geçerlidir:

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()
array([[12.]], dtype=float32)

Eğer TensorFlow 1.x kullandıysanız, hiçbir zaman bir tanımlamanız gerekir yaptığını göreceksiniz Placeholder veya tf.Session .

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

Eğer TensorFlow ile yazma Herhangi fonksiyon bir karışımını içerecektir yerleşik gibi TF operasyonları ve Python mantık, if-then cümlecikleri, döngüler, break , return , continue üzeri ve. TensorFlow işlemleri kolayca tarafından yakalanır iken tf.Graph , Python özgü mantık ihtiyaçları grafiğin parçası olabilmek için fazladan bir adım geçirmesi. tf.function bir imza (denilen bir kütüphane kullanır tf.autograph grafik üreten koduna Python kodu çevirmek için).

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())
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)
# 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
          }
        }
      }
      experimental_debug_info {
        original_node_names: "cond/Const"
      }
    }
    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
          }
        }
      }
      experimental_debug_info {
        original_node_names: "cond/Const_1"
      }
    }
    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
          }
        }
      }
      experimental_debug_info {
        original_node_names: "cond/Const_2"
      }
    }
    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
          }
        }
      }
      experimental_debug_info {
        original_node_names: "cond/Const_3"
      }
    }
    node_def {
      name: "cond/Identity"
      op: "Identity"
      input: "cond/Const_3:output:0"
      attr {
        key: "T"
        value {
          type: DT_BOOL
        }
      }
      experimental_debug_info {
        original_node_names: "cond/Identity"
      }
    }
    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
          }
        }
      }
      experimental_debug_info {
        original_node_names: "cond/Const_4"
      }
    }
    node_def {
      name: "cond/Identity_1"
      op: "Identity"
      input: "cond/Const_4:output:0"
      attr {
        key: "T"
        value {
          type: DT_INT32
        }
      }
      experimental_debug_info {
        original_node_names: "cond/Identity_1"
      }
    }
    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
          }
        }
      }
      experimental_debug_info {
        original_node_names: "cond/Const"
      }
    }
    node_def {
      name: "cond/Identity"
      op: "Identity"
      input: "cond/Const:output:0"
      attr {
        key: "T"
        value {
          type: DT_BOOL
        }
      }
      experimental_debug_info {
        original_node_names: "cond/Identity"
      }
    }
    node_def {
      name: "cond/Identity_1"
      op: "Identity"
      input: "cond_identity_1_x"
      attr {
        key: "T"
        value {
          type: DT_INT32
        }
      }
      experimental_debug_info {
        original_node_names: "cond/Identity_1"
      }
    }
    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: 808
  min_consumer: 12
}

Çoğu zaman, tf.function özel hususlar olmadan çalışacaktır. Ancak, bazı uyarılar vardır ve tf.function kılavuzu yanı sıra, burada yardımcı olabilecek komple imzanı referans

Polimorfizm: Bir Function , birçok grafikleri

Bir tf.Graph girişlerinin belli bir türüne uzmanlaşmış (örneğin, belirli bir ile tansörleri dtype ile aynı ya da nesnelerin id() ).

Bir çağırmak her Function yeni olan dtypes bağımsız değişkenleri ve şekiller, Function yeni oluşturur tf.Graph yeni argümanlar için. dtypes a ve şekiller tf.Graph bireyin girişlerin giriş imza ya da sadece bir imza olarak bilinir.

Function saklar tf.Graph bir o imzaya karşı gelen ConcreteFunction . Bir ConcreteFunction bir etrafında sarıcı 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.])))
tf.Tensor(5.5, shape=(), dtype=float32)
tf.Tensor([1. 0.], shape=(2,), dtype=float32)
tf.Tensor([3. 0.], shape=(2,), dtype=float32)

Eğer Function zaten imzayla anılmış, Function yeni yaratmaz tf.Graph .

# 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.])`.
tf.Tensor(0.0, shape=(), dtype=float32)
tf.Tensor([0. 1.], shape=(2,), dtype=float32)

Çoklu grafikler tarafından desteklenen Çünkü, bir Function polimorfik olduğunu. Bu da tek bir daha girişi tipleri destek olmasını sağlar tf.Graph temsil edebilir, ve her bir duruma getirmek için tf.Graph daha iyi performans için.

# 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())
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,)

kullanılması tf.function

Şimdiye kadar, sadece kullanarak bir grafiğin içine bir Python işlevi dönüştürmek öğrendik tf.function bir dekoratör veya sargı olarak. Ama pratikte, elde tf.function işe doğru yanıltıcı olabilir! Aşağıdaki bölümlerde, beklendiği gibi size kod çalışması yapabilir öğreneceksiniz tf.function .

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

Bir kod Function heyecanla ve bir grafik olarak hem de yürütülebilir. Varsayılan olarak, Function bir grafik olarak kodunu çalıştırmaktadı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([6 1 7 8 0], shape=(5,), dtype=int32)
tf.Tensor([6 0 1 8 6], shape=(5,), dtype=int32)
get_MSE(y_true, y_pred)
<tf.Tensor: shape=(), dtype=int32, numpy=14>

Senin doğrulamak için Function 'ın grafiği eşdeğer Python işleviyle aynı hesaplama yapıyor, bunu birlikte heyecanla yürütmek yapabilirsiniz tf.config.run_functions_eagerly(True) . Bu kapalı dönüşler bir geçiş olacak Function oluşturmak için 'ın yetenek ve çalıştırmak grafikler yerine normal kod yürütme.

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

Bununla birlikte, Function grafiği ve istekli yürütme altında farklı davranabilirler. Python print işlevi bu iki mod nasıl farklı bir örnektir. Bir eklemek ne olur dışarı Let çeki print fonksiyonunuza deyimi ve defalarca diyoruz.

@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)

Neyin yazdırı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)
Calculating MSE!

Çıktı şaşırtıcı mı? get_MSE sadece üç kez aramış olsa bile bir kez basılmış.

Açıklamak için print yaparken deyimi yürütüldüğünde Function olarak bilinen bir süreçte grafik oluşturmak amacıyla orijinal kodu çalıştırır "izleme" . Bir grafiğin içine yakalayan TensorFlow işlemlerini izleme ve print grafiğinde yakalanan değildir. Bu grafiği daha sonra bir daha asla Python kodunu çalıştırmadan üç arama 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)
Calculating MSE!
Calculating MSE!
Calculating MSE!
tf.config.run_functions_eagerly(False)

print bir Python yan etkisidir ve orada diğer farklılıklar , bir içine bir işlev dönüştürürken farkında olmalı Function .

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 ya da 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, "gereksiz" işlemi tf.gather çalışma zamanı hatası böyledir, grafik yürütme sırasında atlanır InvalidArgumentError bu istekli yürütme içinde olması gibi yükseltilmez. Bir grafik yürütülü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)
@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 iyi uygulamalar

Bu davranışına alışmak biraz zaman alabilir Function . Hemen başlamak için, ilk kez kullananlar ile oyuncak fonksiyonlarını dekorasyon etrafında oynaması gereken @tf.function grafik yürütme için istekli giden ile deneyim elde etmek.

İçin Tasarım tf.function grafiği uyumlu TensorFlow programları yazmak için en iyi bahis olabilir. İşte bazı ipuçları:

Hızlanmayı görmek

tf.function genellikle kod performansını artırır, ancak hız-up miktarı çalıştırmak 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.0122516460000384
power_as_graph = tf.function(power)
print("Graph execution:", timeit.timeit(lambda: power_as_graph(x, 100), number=1000))
Graph execution: 0.6084441319999883

tf.function yaygın eğitim döngüler hızlandırmak için kullanılır ve daha bu konuda bilgi edinebilirsiniz sıfırdan bir eğitim döngü yazma keras ile.

Performans ve takaslar

Grafikler kodunuzu hızlandırabilir, ancak bunları oluşturma sürecinin biraz ek 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 uygulamaların 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ğinin farkında olmak önemlidir.

Modeliniz ne kadar büyük olursa olsun, sık sık takip etmekten kaçınmak istersiniz. tf.function kılavuz geçen ne kadar ayar girişi özellikleri ve kullanım tensör argümanları retracing önlemek için. 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 zaman olduğu Function izleme?

Senin ne zaman anlamaya Function izleme, yani bir ekleme print kodunda deyimi. Genel bir kural olarak, Function çalıştırır print deyimi o izleri her zaman.

@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)
# 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

Sen hakkında daha fazla bilgi edinebilirsiniz tf.function API başvuru sayfasında ve izleyerek ile daha iyi performans tf.function rehberi.