本頁面由 Cloud Translation API 翻譯而成。
Switch to English

定制基礎:張量和操作

在TensorFlow.org上查看 在Google Colab中運行 在GitHub上查看源代碼 下載筆記本

這是TensorFlow入門教程,顯示如何:

  • 導入所需的包
  • 創建和使用張量
  • 使用GPU加速
  • 演示tf.data.Dataset

導入TensorFlow

首先,導入tensorflow模塊。從TensorFlow 2開始,默認情況下將打開急切執行功能。這樣可以使TensorFlow更具交互性的前端,我們將在以後詳細討論其細節。

 import tensorflow as tf
 

張量

張量是一個多維數組。與NumPy ndarray對象相似, tf.Tensor對象具有數據類型和形狀。此外, tf.Tensor可以駐留在加速器內存(如GPU)中。 TensorFlow提供了豐富的操作庫( tf.addtf.matmultf.linalg.inv等),這些操作消耗並產生了tf.Tensor 。這些操作會自動轉換本機Python類型,例如:

 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)

每個tf.Tensor都有一個形狀和一個數據類型:

 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'>

NumPy數組和tf.Tensor之間最明顯的區別是:

  1. 張量可以由加速器存儲器(例如GPU,TPU)支持。
  2. 張量是不變的。

NumPy兼容性

在TensorFlow tf.Tensor和NumPy ndarray之間進行轉換很容易:

  • TensorFlow操作會自動將NumPy ndarray轉換為Tensors。
  • NumPy操作自動將張量轉換為NumPy ndarray。

使用其.numpy()方法將張量顯式轉換為NumPy ndarray。這些轉換通常很便宜,因為如果可能的話,數組和tf.Tensor共享底層的內存表示形式。但是,共享底層表示並不總是可能的,因為tf.Tensor可能託管在GPU內存中,而NumPy數組始終由主機內存支持,並且轉換涉及從GPU到主機內存的複制。

 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.]]

GPU加速

使用GPU進行計算可加速許多TensorFlow操作。沒有任何註釋,TensorFlow會自動決定是使用GPU還是CPU進行操作-如有必要,在CPU和GPU內存之間複製張量。由操作產生的張量通常由執行操作的設備的內存支持,例如:

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

print("Is there a GPU available: "),
print(tf.config.experimental.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

設備名稱

Tensor.device屬性提供託管張量內容的設備的標準字符串名稱。此名稱編碼許多詳細信息,例如正在執行此程序的主機的網絡地址以及該主機中的設備的標識符。這是分佈式執行TensorFlow程序所必需的。如果張量放置在主機的第N個GPU上,則字符串以GPU:<N>結尾。

顯式設備放置

在TensorFlow中, 放置是指如何將單個操作分配(放置)在設備上以執行。如前所述,當沒有提供明確的指導時,TensorFlow會自動決定執行哪個設備並在需要時將張量複製到該設備。但是,可以使用tf.device上下文管理器將TensorFlow操作顯式放置在特定設備上,例如:

 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.experimental.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: 99.19ms
On GPU:
10 loops: 239.31ms

數據集

本節使用tf.data.Dataset API來構建用於向模型提供數據的管道。 tf.data.Dataset API用於從簡單,可重複使用的部分構建高性能,複雜的輸入管道,這些輸入管道將為模型的訓練或評估循環提供支持。

創建一個源Dataset

使用工廠功能之一(如Dataset.from_tensorsDataset.from_tensor_slices )或使用從文件(如TextLineDatasetTFRecordDataset讀取的對象來創建數據集。有關更多信息,請參見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)
 

應用轉換

使用諸如mapbatchshuffle類的轉換函數將轉換應用於數據集記錄。

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

ds_file = ds_file.batch(2)
 

重複

tf.data.Dataset對象支持迭代以循環記錄:

 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 4], shape=(2,), dtype=int32)
tf.Tensor([ 9 25], shape=(2,), dtype=int32)
tf.Tensor([16 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)