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

TensorFlow'da NumPy API'si

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ış

TensorFlow uygular bir alt kümesi NumPy API olarak kullanılabilir, tf.experimental.numpy . Bu, TensorFlow tarafından hızlandırılan NumPy kodunun çalıştırılmasına ve aynı zamanda TensorFlow'un tüm API'lerine erişime izin verir.

Kurmak

import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
import tensorflow.experimental.numpy as tnp
import timeit

print("Using TensorFlow version %s" % tf.__version__)
Using TensorFlow version 2.6.0

NumPy davranışını etkinleştirme

Kullanmak için tnp numpy olarak, TensorFlow için NumPy davranışlara imkan veren:

tnp.experimental_enable_numpy_behavior()

Bu çağrı, TensorFlow'da tür tanıtımına olanak tanır ve aynı zamanda, değişmez değerleri tensörlere dönüştürürken, NumPy standardını daha sıkı bir şekilde takip etmek için tür çıkarımını değiştirir.

TensorFlow NumPy ND dizisi

Bir örneği tf.experimental.numpy.ndarray ND Dizi olarak adlandırılan belirli bir çok boyutlu bir yoğun dizisini temsil eder dtype belirli bir cihaz yerleştirilir. Bu bir takma olduğunu tf.Tensor . Gibi yararlı yöntemler için ND dizi sınıfını kontrol edin ndarray.T , ndarray.reshape , ndarray.ravel ve diğerleri.

Önce bir ND dizi nesnesi oluşturun ve ardından farklı yöntemleri çağırın.

# Create an ND array and check out different attributes.
ones = tnp.ones([5, 3], dtype=tnp.float32)
print("Created ND array with shape = %s, rank = %s, "
      "dtype = %s on device = %s\n" % (
          ones.shape, ones.ndim, ones.dtype, ones.device))

# `ndarray` is just an alias to `tf.Tensor`.
print("Is `ones` an instance of tf.Tensor: %s\n" % isinstance(ones, tf.Tensor))

# Try commonly used member functions.
print("ndarray.T has shape %s" % str(ones.T.shape))
print("narray.reshape(-1) has shape %s" % ones.reshape(-1).shape)
Created ND array with shape = (5, 3), rank = 2, dtype = <dtype: 'float32'> on device = /job:localhost/replica:0/task:0/device:GPU:0

Is `ones` an instance of tf.Tensor: True

ndarray.T has shape (3, 5)
narray.reshape(-1) has shape (15,)

Tip promosyonu

TensorFlow NumPy API'leri, değişmez değerleri ND dizisine dönüştürmek için ve ayrıca ND dizisi girişlerinde tür yükseltmesi gerçekleştirmek için iyi tanımlanmış semantiklere sahiptir. Bakınız np.result_type fazla ayrıntı için.

TensorFlow API'leri terk tf.Tensor girdiler değişmeden ve TensorFlow NumPy API'leri NumPy tip tanıtım kurallarına göre tüm girdileri teşvik ederken, onlara tip promosyon yapmazlar. Bir sonraki örnekte, tür promosyonu gerçekleştireceksiniz. İlk olarak, farklı türlerdeki ND dizi girişlerinde toplama işlemini çalıştırın ve çıktı türlerini not edin. Bu tür promosyonların hiçbirine TensorFlow API'leri tarafından izin verilmez.

print("Type promotion for operations")
values = [tnp.asarray(1, dtype=d) for d in
          (tnp.int32, tnp.int64, tnp.float32, tnp.float64)]
for i, v1 in enumerate(values):
  for v2 in values[i + 1:]:
    print("%s + %s => %s" % 
          (v1.dtype.name, v2.dtype.name, (v1 + v2).dtype.name))
Type promotion for operations
int32 + int64 => int64
int32 + float32 => float64
int32 + float64 => float64
int64 + float32 => float64
int64 + float64 => float64
float32 + float64 => float64

Son olarak, ND diziye dönüştürme değişmezleri kullanılarak ndarray.asarray ve elde türünü not edin.

print("Type inference during array creation")
print("tnp.asarray(1).dtype == tnp.%s" % tnp.asarray(1).dtype.name)
print("tnp.asarray(1.).dtype == tnp.%s\n" % tnp.asarray(1.).dtype.name)
Type inference during array creation
tnp.asarray(1).dtype == tnp.int64
tnp.asarray(1.).dtype == tnp.float64

ND diziye değişmezleri dönüştürürken, NumPy gibi geniş türleri tercih tnp.int64 ve tnp.float64 . Buna karşılık, tf.convert_to_tensor tercih tf.int32 ve tf.float32 için sabitleri dönüştürmek için türlerini tf.Tensor . TensorFlow NumPy API'leri, tamsayılar için NumPy davranışına uyar. Yüzen gelince, prefer_float32 bağımsız değişkeni experimental_enable_numpy_behavior tercih edip kontrol etmenizi sağlar tf.float32 üzerinde tf.float64 (için varsayılan False ). Örneğin:

tnp.experimental_enable_numpy_behavior(prefer_float32=True)
print("When prefer_float32 is True:")
print("tnp.asarray(1.).dtype == tnp.%s" % tnp.asarray(1.).dtype.name)
print("tnp.add(1., 2.).dtype == tnp.%s" % tnp.add(1., 2.).dtype.name)

tnp.experimental_enable_numpy_behavior(prefer_float32=False)
print("When prefer_float32 is False:")
print("tnp.asarray(1.).dtype == tnp.%s" % tnp.asarray(1.).dtype.name)
print("tnp.add(1., 2.).dtype == tnp.%s" % tnp.add(1., 2.).dtype.name)
When prefer_float32 is True:
tnp.asarray(1.).dtype == tnp.float32
tnp.add(1., 2.).dtype == tnp.float32
When prefer_float32 is False:
tnp.asarray(1.).dtype == tnp.float64
tnp.add(1., 2.).dtype == tnp.float64

yayın

TensorFlow'a benzer şekilde NumPy, "yayın" değerleri için zengin anlambilim tanımlar. Dışarı kontrol edebilirsiniz NumPy yayın rehberi Daha fazla bilgi için ve bu karşılaştırma TensorFlow anlambilim yayın .

x = tnp.ones([2, 3])
y = tnp.ones([3])
z = tnp.ones([1, 2, 1])
print("Broadcasting shapes %s, %s and %s gives shape %s" % (
    x.shape, y.shape, z.shape, (x + y + z).shape))
Broadcasting shapes (2, 3), (3,) and (1, 2, 1) gives shape (1, 2, 3)

indeksleme

NumPy çok karmaşık indeksleme kurallarını tanımlar. Bkz NumPy Dizin rehberi . Aşağıdaki indeksler olarak ND dizilerinin kullanımına dikkat edin.

x = tnp.arange(24).reshape(2, 3, 4)

print("Basic indexing")
print(x[1, tnp.newaxis, 1:3, ...], "\n")

print("Boolean indexing")
print(x[:, (True, False, True)], "\n")

print("Advanced indexing")
print(x[1, (0, 0, 1), tnp.asarray([0, 1, 1])])
Basic indexing
tf.Tensor(
[[[16 17 18 19]
  [20 21 22 23]]], shape=(1, 2, 4), dtype=int64) 

Boolean indexing
tf.Tensor(
[[[ 0  1  2  3]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [20 21 22 23]]], shape=(2, 2, 4), dtype=int64) 

Advanced indexing
tf.Tensor([12 13 17], shape=(3,), dtype=int64)
# Mutation is currently not supported
try:
  tnp.arange(6)[1] = -1
except TypeError:
  print("Currently, TensorFlow NumPy does not support mutation.")
Currently, TensorFlow NumPy does not support mutation.

Örnek Model

Ardından, bir modelin nasıl oluşturulacağını ve üzerinde nasıl çıkarım yapılacağını görebilirsiniz. Bu basit model, bir relu katmanı ve ardından doğrusal bir izdüşüm uygular. Daha sonra kesitler TensorFlow en kullanarak bu model için renk geçişlerini hesaplamak için nasıl gösterecektir GradientTape .

class Model(object):
  """Model with a dense and a linear layer."""

  def __init__(self):
    self.weights = None

  def predict(self, inputs):
    if self.weights is None:
      size = inputs.shape[1]
      # Note that type `tnp.float32` is used for performance.
      stddev = tnp.sqrt(size).astype(tnp.float32)
      w1 = tnp.random.randn(size, 64).astype(tnp.float32) / stddev
      bias = tnp.random.randn(64).astype(tnp.float32)
      w2 = tnp.random.randn(64, 2).astype(tnp.float32) / 8
      self.weights = (w1, bias, w2)
    else:
      w1, bias, w2 = self.weights
    y = tnp.matmul(inputs, w1) + bias
    y = tnp.maximum(y, 0)  # Relu
    return tnp.matmul(y, w2)  # Linear projection

model = Model()
# Create input data and compute predictions.
print(model.predict(tnp.ones([2, 32], dtype=tnp.float32)))
tf.Tensor(
[[-1.7706785  1.1137733]
 [-1.7706785  1.1137733]], shape=(2, 2), dtype=float32)

TensorFlow NumPy ve NumPy

TensorFlow NumPy, tam NumPy belirtiminin bir alt kümesini uygular. Zamanla daha fazla sembol eklenecek olsa da, yakın gelecekte desteklenmeyecek sistematik özellikler var. Bu NumPy Cı API desteği, Swig entegrasyonu, Fortran depolama düzeni, görüş ve bunlar arasında stride_tricks ve bazı dtype s (gibi np.recarray ve np.object ). Daha fazla ayrıntı için bakınız TensorFlow NumPy API Belgelerinin .

NumPy birlikte çalışabilirliği

TensorFlow ND dizileri, NumPy işlevleriyle birlikte çalışabilir. Bu nesneler uygulamak __array__ arayüzü. NumPy işlev argümanları dönüştürmek için bu arabirimi kullanır np.ndarray işlemeden önce değerler.

Benzer şekilde, TensorFlow NumPy fonksiyonları da dahil olmak üzere farklı tiplerde girişi kabul edebilir np.ndarray . Bu girdiler çağırarak ND dizisine dönüştürülür ndarray.asarray onlara.

Ve ND dizisinin dönüştürülmesi np.ndarray gerçek veri kopyaları tetikleyebilir. Bölümüne bakınız tampon kopya daha fazla ayrıntı için.

# ND array passed into NumPy function.
np_sum = np.sum(tnp.ones([2, 3]))
print("sum = %s. Class: %s" % (float(np_sum), np_sum.__class__))

# `np.ndarray` passed into TensorFlow NumPy function.
tnp_sum = tnp.sum(np.ones([2, 3]))
print("sum = %s. Class: %s" % (float(tnp_sum), tnp_sum.__class__))
sum = 6.0. Class: <class 'numpy.float64'>
sum = 6.0. Class: <class 'tensorflow.python.framework.ops.EagerTensor'>
# It is easy to plot ND arrays, given the __array__ interface.
labels = 15 + 2 * tnp.random.randn(1, 1000)
_ = plt.hist(labels)

png

arabellek kopyaları

TensorFlow NumPy'yi NumPy koduyla karıştırmak veri kopyalarını tetikleyebilir. Bunun nedeni, TensorFlow NumPy'nin bellek hizalaması konusunda NumPy'ninkinden daha katı gereksinimleri olmasıdır.

Bir zaman np.ndarray TensorFlow numpy geçirilir, bu hizalama gereksinimleri için kontrol edecek ve gerekirse bir kopyasını tetikler. Bir ND dizisi CPU arabelleğini NumPy'ye geçirirken, arabellek genellikle hizalama gereksinimlerini karşılar ve NumPy'nin bir kopya oluşturması gerekmez.

ND dizileri, yerel CPU belleği dışındaki aygıtlara yerleştirilen arabelleklere başvurabilir. Bu gibi durumlarda, bir NumPy işlevinin çağrılması, gerektiğinde ağ veya cihaz genelinde kopyaları tetikleyecektir.

Bu göz önüne alındığında, NumPy API çağrılarıyla karıştırma işlemi genellikle dikkatli yapılmalı ve kullanıcı veri kopyalamanın genel giderlerine dikkat etmelidir. TensorFlow NumPy çağrılarını TensorFlow çağrılarıyla araya eklemek genellikle güvenlidir ve verilerin kopyalanmasını önler. Bölümüne bakın TensorFlow birlikte çalışma Daha fazla ayrıntı için.

Operatör Önceliği

TensorFlow NumPy bir tanımlamaktadır __array_priority__ NumPy en yüksek. ND dizi ve her ikisinin de dahil operatörler için o Bu araçlar np.ndarray , eski deyişle öncelik alacak, np.ndarray girdi çağrılan alacak ND dizisinin ve operatörün TensorFlow NumPy uygulanması şuna dönüştürülür.

x = tnp.ones([2]) + np.ones([2])
print("x = %s\nclass = %s" % (x, x.__class__))
x = tf.Tensor([2. 2.], shape=(2,), dtype=float64)
class = <class 'tensorflow.python.framework.ops.EagerTensor'>

TF NumPy ve TensorFlow

TensorFlow NumPy, TensorFlow'un üzerine kurulmuştur ve bu nedenle TensorFlow ile sorunsuz bir şekilde birlikte çalışır.

tf.Tensor ve ND dizisi

ND dizisi için bir takma tf.Tensor çok açıktır ki bunlar gerçek veri kopyaları tetiklemeden düzenli olabilir.

x = tf.constant([1, 2])
print(x)

# `asarray` and `convert_to_tensor` here are no-ops.
tnp_x = tnp.asarray(x)
print(tnp_x)
print(tf.convert_to_tensor(tnp_x))

# Note that tf.Tensor.numpy() will continue to return `np.ndarray`.
print(x.numpy(), x.numpy().__class__)
tf.Tensor([1 2], shape=(2,), dtype=int32)
tf.Tensor([1 2], shape=(2,), dtype=int32)
tf.Tensor([1 2], shape=(2,), dtype=int32)
[1 2] <class 'numpy.ndarray'>

TensorFlow birlikte çalışabilirliği

ND dizisi sadece bir takma olduğundan bir ND dizisi, TensorFlow API'leri geçirilebilir tf.Tensor . Daha önce de belirtildiği gibi, bu tür bir birlikte çalışma, hızlandırıcılara veya uzak aygıtlara yerleştirilen veriler için bile veri kopyaları yapmaz.

Tersine, tf.Tensor nesneleri geçirilebilir tf.experimental.numpy veri kopyalarını yapılmadan, API'ler.

# ND array passed into TensorFlow function.
tf_sum = tf.reduce_sum(tnp.ones([2, 3], tnp.float32))
print("Output = %s" % tf_sum)

# `tf.Tensor` passed into TensorFlow NumPy function.
tnp_sum = tnp.sum(tf.ones([2, 3]))
print("Output = %s" % tnp_sum)
Output = tf.Tensor(6.0, shape=(), dtype=float32)
Output = tf.Tensor(6.0, shape=(), dtype=float32)

Gradyanlar ve Jacobians: tf.GradientTape

TensorFlow'un GradientTape'i, TensorFlow ve TensorFlow NumPy kodu aracılığıyla geri yayılım için kullanılabilir.

Oluşturulan modeli kullanın Örnek Modeli bölümünde ve geçişlerini ve Jacobians hesaplamak.

def create_batch(batch_size=32):
  """Creates a batch of input and labels."""
  return (tnp.random.randn(batch_size, 32).astype(tnp.float32),
          tnp.random.randn(batch_size, 2).astype(tnp.float32))

def compute_gradients(model, inputs, labels):
  """Computes gradients of squared loss between model prediction and labels."""
  with tf.GradientTape() as tape:
    assert model.weights is not None
    # Note that `model.weights` need to be explicitly watched since they
    # are not tf.Variables.
    tape.watch(model.weights)
    # Compute prediction and loss
    prediction = model.predict(inputs)
    loss = tnp.sum(tnp.square(prediction - labels))
  # This call computes the gradient through the computation above.
  return tape.gradient(loss, model.weights)

inputs, labels = create_batch()
gradients = compute_gradients(model, inputs, labels)

# Inspect the shapes of returned gradients to verify they match the
# parameter shapes.
print("Parameter shapes:", [w.shape for w in model.weights])
print("Gradient shapes:", [g.shape for g in gradients])
# Verify that gradients are of type ND array.
assert isinstance(gradients[0], tnp.ndarray)
Parameter shapes: [TensorShape([32, 64]), TensorShape([64]), TensorShape([64, 2])]
Gradient shapes: [TensorShape([32, 64]), TensorShape([64]), TensorShape([64, 2])]
# Computes a batch of jacobians. Each row is the jacobian of an element in the
# batch of outputs w.r.t. the corresponding input batch element.
def prediction_batch_jacobian(inputs):
  with tf.GradientTape() as tape:
    tape.watch(inputs)
    prediction = model.predict(inputs)
  return prediction, tape.batch_jacobian(prediction, inputs)

inp_batch = tnp.ones([16, 32], tnp.float32)
output, batch_jacobian = prediction_batch_jacobian(inp_batch)
# Note how the batch jacobian shape relates to the input and output shapes.
print("Output shape: %s, input shape: %s" % (output.shape, inp_batch.shape))
print("Batch jacobian shape:", batch_jacobian.shape)
Output shape: (16, 2), input shape: (16, 32)
Batch jacobian shape: (16, 2, 32)

İzleme derlemesi: tf.function

TensorFlow en tf.function kodunu "iz derleme" ve ardından çok daha hızlı performans için bu izleri optimize ederek çalışır. Bkz Grafikleri ve Fonksiyonlar için giriş .

tf.function sıra TensorFlow NumPy kodu optimize etmek için kullanılabilir. Hızlanmaları göstermek için basit bir örnek. Vücut geldiğini hatırlatırız tf.function kodu TensorFlow NumPy API'leri mesajları içerdiğinden.

inputs, labels = create_batch(512)
print("Eager performance")
compute_gradients(model, inputs, labels)
print(timeit.timeit(lambda: compute_gradients(model, inputs, labels),
                    number=10) * 100, "ms")

print("\ntf.function compiled performance")
compiled_compute_gradients = tf.function(compute_gradients)
compiled_compute_gradients(model, inputs, labels)  # warmup
print(timeit.timeit(lambda: compiled_compute_gradients(model, inputs, labels),
                    number=10) * 100, "ms")
Eager performance
1.291419400013183 ms

tf.function compiled performance
0.5561202000080812 ms

Vektörleştirme: tf.vectorized_map

TensorFlow, paralel döngülerin vektörleştirilmesi için dahili bir desteğe sahiptir ve bu, bir ila iki büyüklük derecesinde hızlanmalara izin verir. Bu speedups yoluyla erişilebilir tf.vectorized_map API ve TensorFlow NumPy kodu için geçerli de.

Bazen bir yığındaki her bir çıktının gradyanını karşılık gelen girdi yığın öğesiyle hesaplamak yararlıdır. Bu hesaplama kullanarak etkili bir şekilde yapılabilir tf.vectorized_map aşağıda gösterildiği gibi.

@tf.function
def vectorized_per_example_gradients(inputs, labels):
  def single_example_gradient(arg):
    inp, label = arg
    return compute_gradients(model,
                             tnp.expand_dims(inp, 0),
                             tnp.expand_dims(label, 0))
  # Note that a call to `tf.vectorized_map` semantically maps
  # `single_example_gradient` over each row of `inputs` and `labels`.
  # The interface is similar to `tf.map_fn`.
  # The underlying machinery vectorizes away this map loop which gives
  # nice speedups.
  return tf.vectorized_map(single_example_gradient, (inputs, labels))

batch_size = 128
inputs, labels = create_batch(batch_size)

per_example_gradients = vectorized_per_example_gradients(inputs, labels)
for w, p in zip(model.weights, per_example_gradients):
  print("Weight shape: %s, batch size: %s, per example gradient shape: %s " % (
      w.shape, batch_size, p.shape))
Weight shape: (32, 64), batch size: 128, per example gradient shape: (128, 32, 64) 
Weight shape: (64,), batch size: 128, per example gradient shape: (128, 64) 
Weight shape: (64, 2), batch size: 128, per example gradient shape: (128, 64, 2)
# Benchmark the vectorized computation above and compare with
# unvectorized sequential computation using `tf.map_fn`.
@tf.function
def unvectorized_per_example_gradients(inputs, labels):
  def single_example_gradient(arg):
    inp, label = arg
    return compute_gradients(model,
                             tnp.expand_dims(inp, 0),
                             tnp.expand_dims(label, 0))

  return tf.map_fn(single_example_gradient, (inputs, labels),
                   fn_output_signature=(tf.float32, tf.float32, tf.float32))

print("Running vectorized computation")
print(timeit.timeit(lambda: vectorized_per_example_gradients(inputs, labels),
                    number=10) * 100, "ms")

print("\nRunning unvectorized computation")
per_example_gradients = unvectorized_per_example_gradients(inputs, labels)
print(timeit.timeit(lambda: unvectorized_per_example_gradients(inputs, labels),
                    number=10) * 100, "ms")
Running vectorized computation
0.5265710999992734 ms

Running unvectorized computation
40.35122630002661 ms

Cihaz yerleşimi

TensorFlow NumPy, CPU'lara, GPU'lara, TPU'lara ve uzak cihazlara işlem yerleştirebilir. Cihaz yerleştirme için standart TensorFlow mekanizmalarını kullanır. Aşağıda basit bir örnek, tüm cihazların nasıl listeleneceğini ve ardından belirli bir cihaza bazı hesaplamaların nasıl yerleştirileceğini gösterir.

TensorFlow ayrıca, hesaplamayı cihazlar arasında çoğaltmak ve burada ele alınmayacak olan toplu azaltmalar gerçekleştirmek için API'lere sahiptir.

Cihazları listele

tf.config.list_logical_devices ve tf.config.list_physical_devices kullanmak hangi cihazların bulmak için kullanılabilir.

print("All logical devices:", tf.config.list_logical_devices())
print("All physical devices:", tf.config.list_physical_devices())

# Try to get the GPU device. If unavailable, fallback to CPU.
try:
  device = tf.config.list_logical_devices(device_type="GPU")[0]
except IndexError:
  device = "/device:CPU:0"
All logical devices: [LogicalDevice(name='/device:CPU:0', device_type='CPU'), LogicalDevice(name='/device:GPU:0', device_type='GPU')]
All physical devices: [PhysicalDevice(name='/physical_device:CPU:0', device_type='CPU'), PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]

Operasyonları Yerleştirme: tf.device

Operasyon bir o arayarak bir cihaz yerleştirilebilir tf.device kapsamı.

print("Using device: %s" % str(device))
# Run operations in the `tf.device` scope.
# If a GPU is available, these operations execute on the GPU and outputs are
# placed on the GPU memory.
with tf.device(device):
  prediction = model.predict(create_batch(5)[0])

print("prediction is placed on %s" % prediction.device)
Using device: LogicalDevice(name='/device:GPU:0', device_type='GPU')
prediction is placed on /job:localhost/replica:0/task:0/device:GPU:0

Cihazlar arasında ND dizileri kopyalama: tnp.copy

Bir çağrı tnp.copy verileri söz konusu cihazda alıncaya belli cihaz kapsamına yerleştirilir, bu cihaza veri kopyalar.

with tf.device("/device:CPU:0"):
  prediction_cpu = tnp.copy(prediction)
print(prediction.device)
print(prediction_cpu.device)
/job:localhost/replica:0/task:0/device:GPU:0
/job:localhost/replica:0/task:0/device:CPU:0

Performans karşılaştırmaları

TensorFlow NumPy, CPU'lara, GPU'lara ve TPU'lara gönderilebilen yüksek düzeyde optimize edilmiş TensorFlow çekirdeklerini kullanır. TensorFlow ayrıca, performans ve bellek iyileştirmelerine dönüşen işlem birleştirme gibi birçok derleyici optimizasyonu gerçekleştirir. Bkz grappler ile TensorFlow grafiği optimizasyonu daha fazla bilgi edinmek.

Ancak TensorFlow, NumPy'ye kıyasla gönderme işlemleri için daha yüksek genel giderlere sahiptir. Küçük işlemlerden (yaklaşık 10 mikrosaniyeden daha az) oluşan iş yükleri için bu genel giderler çalışma zamanına hükmedebilir ve NumPy daha iyi performans sağlayabilir. Diğer durumlarda, TensorFlow genellikle daha iyi performans sağlamalıdır.

Farklı giriş boyutları için NumPy ve TensorFlow NumPy performansını karşılaştırmak için aşağıdaki karşılaştırmayı çalıştırın.

def benchmark(f, inputs, number=30, force_gpu_sync=False):
  """Utility to benchmark `f` on each value in `inputs`."""
  times = []
  for inp in inputs:
    def _g():
      if force_gpu_sync:
        one = tnp.asarray(1)
      f(inp)
      if force_gpu_sync:
        with tf.device("CPU:0"):
          tnp.copy(one)  # Force a sync for GPU case

    _g()  # warmup
    t = timeit.timeit(_g, number=number)
    times.append(t * 1000. / number)
  return times


def plot(np_times, tnp_times, compiled_tnp_times, has_gpu, tnp_times_gpu):
  """Plot the different runtimes."""
  plt.xlabel("size")
  plt.ylabel("time (ms)")
  plt.title("Sigmoid benchmark: TF NumPy vs NumPy")
  plt.plot(sizes, np_times, label="NumPy")
  plt.plot(sizes, tnp_times, label="TF NumPy (CPU)")
  plt.plot(sizes, compiled_tnp_times, label="Compiled TF NumPy (CPU)")
  if has_gpu:
    plt.plot(sizes, tnp_times_gpu, label="TF NumPy (GPU)")
  plt.legend()
# Define a simple implementation of `sigmoid`, and benchmark it using
# NumPy and TensorFlow NumPy for different input sizes.

def np_sigmoid(y):
  return 1. / (1. + np.exp(-y))

def tnp_sigmoid(y):
  return 1. / (1. + tnp.exp(-y))

@tf.function
def compiled_tnp_sigmoid(y):
  return tnp_sigmoid(y)

sizes = (2 ** 0, 2 ** 5, 2 ** 10, 2 ** 15, 2 ** 20)
np_inputs = [np.random.randn(size).astype(np.float32) for size in sizes]
np_times = benchmark(np_sigmoid, np_inputs)

with tf.device("/device:CPU:0"):
  tnp_inputs = [tnp.random.randn(size).astype(np.float32) for size in sizes]
  tnp_times = benchmark(tnp_sigmoid, tnp_inputs)
  compiled_tnp_times = benchmark(compiled_tnp_sigmoid, tnp_inputs)

has_gpu = len(tf.config.list_logical_devices("GPU"))
if has_gpu:
  with tf.device("/device:GPU:0"):
    tnp_inputs = [tnp.random.randn(size).astype(np.float32) for size in sizes]
    tnp_times_gpu = benchmark(compiled_tnp_sigmoid, tnp_inputs, 100, True)
else:
  tnp_times_gpu = None
plot(np_times, tnp_times, compiled_tnp_times, has_gpu, tnp_times_gpu)

png

daha fazla okuma