Podstawy dostosowywania: tensory i operacje

Zobacz na TensorFlow.org Uruchom w Google Colab Wyświetl źródło na GitHub Pobierz notatnik

To jest samouczek wprowadzający TensorFlow, który pokazuje, jak:

  • Zaimportuj wymagany pakiet
  • Twórz i używaj tensorów
  • Użyj akceleracji GPU
  • Zademonstruj tf.data.Dataset

Importuj przepływ tensora

Aby rozpocząć, zaimportuj moduł tensorflow . Od TensorFlow 2 szybkie wykonywanie jest domyślnie włączone. Umożliwia to bardziej interaktywny frontend do TensorFlow, którego szczegóły omówimy znacznie później.

import tensorflow as tf

Tensory

Tensor to wielowymiarowa tablica. Podobnie do obiektów ndarray NumPy, obiekty tf.Tensor mają typ danych i kształt. Dodatkowo tf.Tensor s może znajdować się w pamięci akceleratora (podobnie jak GPU). TensorFlow oferuje bogatą bibliotekę operacji ( tf.add , tf.matmul , tf.linalg.inv itp.), które zużywają i produkują tf.Tensor s. Te operacje automatycznie konwertują natywne typy Pythona, na przykład:

print(tf.add(1, 2))
print(tf.add([1, 2], [3, 4]))
print(tf.square(5))
print(tf.reduce_sum([1, 2, 3]))

# Operator overloading is also supported
print(tf.square(2) + tf.square(3))
tf.Tensor(3, shape=(), dtype=int32)
tf.Tensor([4 6], shape=(2,), dtype=int32)
tf.Tensor(25, shape=(), dtype=int32)
tf.Tensor(6, shape=(), dtype=int32)
tf.Tensor(13, shape=(), dtype=int32)

Każdy tf.Tensor ma kształt i typ danych:

x = tf.matmul([[1]], [[2, 3]])
print(x)
print(x.shape)
print(x.dtype)
tf.Tensor([[2 3]], shape=(1, 2), dtype=int32)
(1, 2)
<dtype: 'int32'>

Najbardziej oczywiste różnice między tablicami NumPy a tf.Tensor to:

  1. Tensory mogą być wspierane przez pamięć akceleratora (np. GPU, TPU).
  2. Tensory są niezmienne.

Kompatybilność NumPy

Konwersja między TensorFlow tf.Tensor s a NumPy ndarray jest łatwa:

  • Operacje TensorFlow automatycznie konwertują ndarray NumPy na tensory.
  • Operacje NumPy automatycznie konwertują tensory na ndarrays NumPy.

Tensory są jawnie konwertowane na ndarrays NumPy przy użyciu ich metody .numpy() . Te konwersje są zazwyczaj tanie, ponieważ tablica i tf.Tensor współdzielą podstawową reprezentację pamięci, jeśli to możliwe. Jednak udostępnianie podstawowej reprezentacji nie zawsze jest możliwe, ponieważ tf.Tensor może być hostowany w pamięci GPU, podczas gdy tablice NumPy są zawsze obsługiwane przez pamięć hosta, a konwersja obejmuje kopię z GPU do pamięci hosta.

import numpy as np

ndarray = np.ones([3, 3])

print("TensorFlow operations convert numpy arrays to Tensors automatically")
tensor = tf.multiply(ndarray, 42)
print(tensor)


print("And NumPy operations convert Tensors to numpy arrays automatically")
print(np.add(tensor, 1))

print("The .numpy() method explicitly converts a Tensor to a numpy array")
print(tensor.numpy())
TensorFlow operations convert numpy arrays to Tensors automatically
tf.Tensor(
[[42. 42. 42.]
 [42. 42. 42.]
 [42. 42. 42.]], shape=(3, 3), dtype=float64)
And NumPy operations convert Tensors to numpy arrays automatically
[[43. 43. 43.]
 [43. 43. 43.]
 [43. 43. 43.]]
The .numpy() method explicitly converts a Tensor to a numpy array
[[42. 42. 42.]
 [42. 42. 42.]
 [42. 42. 42.]]

Akceleracja GPU

Wiele operacji TensorFlow jest akcelerowanych przy użyciu GPU do obliczeń. Bez żadnych adnotacji TensorFlow automatycznie decyduje, czy użyć procesora graficznego, czy procesora do operacji — kopiując tensor między procesorem a pamięcią procesora graficznego, jeśli to konieczne. Tensory generowane przez operację są zwykle wspierane przez pamięć urządzenia, na którym operacja została wykonana, na przykład:

x = tf.random.uniform([3, 3])

print("Is there a GPU available: "),
print(tf.config.list_physical_devices("GPU"))

print("Is the Tensor on GPU #0:  "),
print(x.device.endswith('GPU:0'))
Is there a GPU available: 
[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
Is the Tensor on GPU #0:  
True

Nazwy urządzeń

Właściwość Tensor.device zapewnia w pełni kwalifikowaną nazwę ciągu urządzenia obsługującego zawartość tensora. Ta nazwa koduje wiele szczegółów, takich jak identyfikator adresu sieciowego hosta, na którym ten program jest wykonywany, oraz urządzenia na tym hoście. Jest to wymagane do rozproszonego wykonywania programu TensorFlow. Ciąg kończy się na GPU:<N> , jeśli tensor jest umieszczony na N -tym GPU na hoście.

Jawne umieszczanie urządzenia

W TensorFlow rozmieszczenie odnosi się do tego, w jaki sposób poszczególne operacje są przypisywane (umieszczane na) urządzeniu do wykonania. Jak wspomniano, gdy nie ma wyraźnych wskazówek, TensorFlow automatycznie decyduje, które urządzenie wykonać operację i w razie potrzeby kopiuje tensory do tego urządzenia. Jednak operacje TensorFlow można jawnie umieścić na określonych urządzeniach za pomocą menedżera kontekstu tf.device , na przykład:

import time

def time_matmul(x):
  start = time.time()
  for loop in range(10):
    tf.matmul(x, x)

  result = time.time()-start

  print("10 loops: {:0.2f}ms".format(1000*result))

# Force execution on CPU
print("On CPU:")
with tf.device("CPU:0"):
  x = tf.random.uniform([1000, 1000])
  assert x.device.endswith("CPU:0")
  time_matmul(x)

# Force execution on GPU #0 if available
if tf.config.list_physical_devices("GPU"):
  print("On GPU:")
  with tf.device("GPU:0"): # Or GPU:1 for the 2nd GPU, GPU:2 for the 3rd etc.
    x = tf.random.uniform([1000, 1000])
    assert x.device.endswith("GPU:0")
    time_matmul(x)
On CPU:
10 loops: 91.47ms
On GPU:
10 loops: 388.16ms

Zbiory danych

Ta sekcja używa interfejsu API tf.data.Dataset do zbudowania potoku do przesyłania danych do modelu. Interfejs API tf.data.Dataset służy do tworzenia wydajnych, złożonych potoków wejściowych z prostych elementów wielokrotnego użytku, które będą zasilać pętle uczenia lub oceny modelu.

Utwórz źródłowy Dataset

Utwórz źródłowy zestaw danych przy użyciu jednej z funkcji fabrycznych, takich jak Dataset.from_tensors , Dataset.from_tensor_slices , lub obiektów, które czytają z plików, takich jak TextLineDataset lub TFRecordDataset . Więcej informacji znajdziesz w przewodniku po zestawach danych TensorFlow .

ds_tensors = tf.data.Dataset.from_tensor_slices([1, 2, 3, 4, 5, 6])

# Create a CSV file
import tempfile
_, filename = tempfile.mkstemp()

with open(filename, 'w') as f:
  f.write("""Line 1
Line 2
Line 3
  """)

ds_file = tf.data.TextLineDataset(filename)

Zastosuj przekształcenia

Użyj funkcji przekształceń, takich jak map , batch i shuffle , aby zastosować przekształcenia do rekordów zestawu danych.

ds_tensors = ds_tensors.map(tf.square).shuffle(2).batch(2)

ds_file = ds_file.batch(2)

Powtarzać

Obiekty tf.data.Dataset obsługują iterację w celu zapętlenia rekordów:

print('Elements of ds_tensors:')
for x in ds_tensors:
  print(x)

print('\nElements in ds_file:')
for x in ds_file:
  print(x)
Elements of ds_tensors:
tf.Tensor([1 9], shape=(2,), dtype=int32)
tf.Tensor([16  4], shape=(2,), dtype=int32)
tf.Tensor([25 36], shape=(2,), dtype=int32)

Elements in ds_file:
tf.Tensor([b'Line 1' b'Line 2'], shape=(2,), dtype=string)
tf.Tensor([b'Line 3' b'  '], shape=(2,), dtype=string)