Kiến thức cơ bản về TensorFlow

Xem trên TensorFlow.org Chạy trong Google Colab Xem nguồn trên GitHub Tải xuống sổ ghi chép

Hướng dẫn này cung cấp tổng quan nhanh về các khái niệm cơ bản về TensorFlow . Mỗi phần của tài liệu này là tổng quan về một chủ đề lớn hơn — bạn có thể tìm thấy các liên kết đến các hướng dẫn đầy đủ ở cuối mỗi phần.

TensorFlow là một nền tảng end-to-end dành cho học máy. Nó hỗ trợ những điều sau:

  • Tính toán số dựa trên mảng đa chiều (tương tự như NumPy .)
  • GPU và xử lý phân tán
  • Phân biệt tự động
  • Xây dựng mô hình, đào tạo và xuất khẩu
  • Và nhiều hơn nữa

Căng thẳng

TensorFlow hoạt động trên các mảng đa chiều hoặc các tensor được biểu diễn dưới dạng các đối tượng tf.Tensor . Đây là một tensor hai chiều:

import tensorflow as tf

x = tf.constant([[1., 2., 3.],
                 [4., 5., 6.]])

print(x)
print(x.shape)
print(x.dtype)
tf.Tensor(
[[1. 2. 3.]
 [4. 5. 6.]], shape=(2, 3), dtype=float32)
(2, 3)
<dtype: 'float32'>

Các thuộc tính quan trọng nhất của tf.Tensorshapedtype của nó:

  • Tensor.shape : cho bạn biết kích thước của tensor dọc theo mỗi trục của nó.
  • Tensor.dtype : cho bạn biết loại của tất cả các phần tử trong tensor.

TensorFlow thực hiện các phép toán tiêu chuẩn trên tensor, cũng như nhiều phép toán chuyên dụng cho học máy.

Ví dụ:

x + x
<tf.Tensor: shape=(2, 3), dtype=float32, numpy=
array([[ 2.,  4.,  6.],
       [ 8., 10., 12.]], dtype=float32)>
5 * x
<tf.Tensor: shape=(2, 3), dtype=float32, numpy=
array([[ 5., 10., 15.],
       [20., 25., 30.]], dtype=float32)>
x @ tf.transpose(x)
<tf.Tensor: shape=(2, 2), dtype=float32, numpy=
array([[14., 32.],
       [32., 77.]], dtype=float32)>
tf.concat([x, x, x], axis=0)
<tf.Tensor: shape=(6, 3), dtype=float32, numpy=
array([[1., 2., 3.],
       [4., 5., 6.],
       [1., 2., 3.],
       [4., 5., 6.],
       [1., 2., 3.],
       [4., 5., 6.]], dtype=float32)>
tf.nn.softmax(x, axis=-1)
<tf.Tensor: shape=(2, 3), dtype=float32, numpy=
array([[0.09003057, 0.24472848, 0.6652409 ],
       [0.09003057, 0.24472848, 0.6652409 ]], dtype=float32)>
tf.reduce_sum(x)
<tf.Tensor: shape=(), dtype=float32, numpy=21.0>

Chạy các phép tính lớn trên CPU có thể bị chậm. Khi được cấu hình đúng cách, TensorFlow có thể sử dụng phần cứng tăng tốc như GPU để thực thi các hoạt động rất nhanh chóng.

if tf.config.list_physical_devices('GPU'):
  print("TensorFlow **IS** using the GPU")
else:
  print("TensorFlow **IS NOT** using the GPU")
TensorFlow **IS** using the GPU

Tham khảo hướng dẫn Tensor để biết thêm chi tiết.

Biến

Các đối tượng tf.Tensor bình thường là bất biến. Để lưu trữ trọng số của mô hình (hoặc trạng thái có thể thay đổi khác) trong TensorFlow, hãy sử dụng tf.Variable .

var = tf.Variable([0.0, 0.0, 0.0])
var.assign([1, 2, 3])
<tf.Variable 'UnreadVariable' shape=(3,) dtype=float32, numpy=array([1., 2., 3.], dtype=float32)>
var.assign_add([1, 1, 1])
<tf.Variable 'UnreadVariable' shape=(3,) dtype=float32, numpy=array([2., 3., 4.], dtype=float32)>

Tham khảo hướng dẫn về Biến để biết chi tiết.

Phân biệt tự động

Gradient descent và các thuật toán liên quan là nền tảng của học máy hiện đại.

Để thực hiện điều này, TensorFlow thực hiện phân biệt tự động (autodiff), sử dụng phép tính để tính toán độ dốc. Thông thường, bạn sẽ sử dụng công cụ này để tính toán độ dốc của lỗi hoặc tổn thất của một mô hình liên quan đến trọng lượng của nó.

x = tf.Variable(1.0)

def f(x):
  y = x**2 + 2*x - 5
  return y
f(x)
<tf.Tensor: shape=(), dtype=float32, numpy=-2.0>

Tại x = 1.0 , y = f(x) = (1**2 + 2*1 - 5) = -2 .

Đạo hàm của yy' = f'(x) = (2*x + 2) = 4 . TensorFlow có thể tự động tính toán điều này:

with tf.GradientTape() as tape:
  y = f(x)

g_x = tape.gradient(y, x)  # g(x) = dy/dx

g_x
<tf.Tensor: shape=(), dtype=float32, numpy=4.0>

Ví dụ đơn giản này chỉ lấy đạo hàm đối với một đại lượng vô hướng ( x ), nhưng TensorFlow có thể tính toán gradient đối với bất kỳ số tensor không vô hướng nào đồng thời.

Tham khảo hướng dẫn Autodiff để biết thêm chi tiết.

Đồ thị và hàm tf.

Mặc dù bạn có thể sử dụng TensorFlow một cách tương tác như bất kỳ thư viện Python nào, nhưng TensorFlow cũng cung cấp các công cụ cho:

  • Tối ưu hóa hiệu suất : để tăng tốc độ đào tạo và suy luận.
  • Xuất : để bạn có thể lưu mô hình của mình khi đào tạo xong.

Những điều này yêu cầu bạn sử dụng tf.function để tách mã TensorFlow thuần của bạn khỏi Python.

@tf.function
def my_func(x):
  print('Tracing.\n')
  return tf.reduce_sum(x)

Lần đầu tiên bạn chạy hàm tf.function . function, mặc dù nó thực thi bằng Python, nhưng nó sẽ ghi lại một đồ thị hoàn chỉnh, được tối ưu hóa đại diện cho các tính toán TensorFlow được thực hiện trong hàm.

x = tf.constant([1, 2, 3])
my_func(x)
Tracing.
<tf.Tensor: shape=(), dtype=int32, numpy=6>

Trong các lần gọi tiếp theo, TensorFlow chỉ thực thi biểu đồ được tối ưu hóa, bỏ qua bất kỳ bước nào không phải TensorFlow. Dưới đây, lưu ý rằng my_func không theo dõi in vì print là một hàm Python, không phải một hàm TensorFlow.

x = tf.constant([10, 9, 8])
my_func(x)
<tf.Tensor: shape=(), dtype=int32, numpy=27>

Một biểu đồ có thể không được sử dụng lại cho các đầu vào có chữ ký khác ( shapedtype ), do đó, một biểu đồ mới được tạo thay thế:

x = tf.constant([10.0, 9.1, 8.2], dtype=tf.float32)
my_func(x)
Tracing.
<tf.Tensor: shape=(), dtype=float32, numpy=27.3>

Các biểu đồ được chụp này cung cấp hai lợi ích:

  • Trong nhiều trường hợp, chúng cung cấp tốc độ thực thi đáng kể (mặc dù không phải là ví dụ tầm thường này).
  • Bạn có thể xuất các biểu đồ này, sử dụng tf.saved_model , để chạy trên các hệ thống khác như máy chủ hoặc thiết bị di động , không cần cài đặt Python.

Tham khảo Giới thiệu về đồ thị để biết thêm chi tiết.

Mô-đun, lớp và mô hình

tf.Module là một lớp để quản lý các đối tượng tf.Variable của bạn và các đối tượng tf.function hoạt động trên chúng. Lớp tf.Module là cần thiết để hỗ trợ hai tính năng quan trọng:

  1. Bạn có thể lưu và khôi phục giá trị của các biến bằng tf.train.Checkpoint . Điều này rất hữu ích trong quá trình đào tạo vì nó nhanh chóng lưu và khôi phục trạng thái của mô hình.
  2. Bạn có thể nhập và xuất các giá trị tf.Variable đồ thị hàm tf.function bằng cách sử dụng tf.saved_model . Điều này cho phép bạn chạy mô hình của mình một cách độc lập với chương trình Python đã tạo ra nó.

Đây là một ví dụ hoàn chỉnh về xuất một đối tượng tf.Module đơn giản:

class MyModule(tf.Module):
  def __init__(self, value):
    self.weight = tf.Variable(value)

  @tf.function
  def multiply(self, x):
    return x * self.weight
mod = MyModule(3)
mod.multiply(tf.constant([1, 2, 3]))
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([3, 6, 9], dtype=int32)>

Lưu Module :

save_path = './saved'
tf.saved_model.save(mod, save_path)
INFO:tensorflow:Assets written to: ./saved/assets
2022-01-19 02:29:48.135588: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.

SavedModel kết quả độc lập với mã đã tạo ra nó. Bạn có thể tải SavedModel từ Python, các ràng buộc ngôn ngữ khác hoặc Cung cấp TensorFlow . Bạn cũng có thể chuyển đổi nó để chạy với TensorFlow Lite hoặc TensorFlow JS .

reloaded = tf.saved_model.load(save_path)
reloaded.multiply(tf.constant([1, 2, 3]))
<tf.Tensor: shape=(3,), dtype=int32, numpy=array([3, 6, 9], dtype=int32)>

Các tf.keras.layers.Layertf.keras.Model xây dựng trên tf.Module cung cấp chức năng bổ sung và các phương pháp tiện lợi để xây dựng, đào tạo và lưu mô hình. Một số trong số này được chứng minh trong phần tiếp theo.

Tham khảo Giới thiệu về mô-đun để biết thêm chi tiết.

Các vòng huấn luyện

Bây giờ hãy tập hợp tất cả những điều này lại với nhau để xây dựng một mô hình cơ bản và đào tạo nó từ đầu.

Đầu tiên, hãy tạo một số dữ liệu ví dụ. Điều này tạo ra một đám mây các điểm theo một đường cong bậc hai một cách lỏng lẻo:

import matplotlib
from matplotlib import pyplot as plt

matplotlib.rcParams['figure.figsize'] = [9, 6]
x = tf.linspace(-2, 2, 201)
x = tf.cast(x, tf.float32)

def f(x):
  y = x**2 + 2*x - 5
  return y

y = f(x) + tf.random.normal(shape=[201])

plt.plot(x.numpy(), y.numpy(), '.', label='Data')
plt.plot(x, f(x),  label='Ground truth')
plt.legend();

png

Tạo một mô hình:

class Model(tf.keras.Model):
  def __init__(self, units):
    super().__init__()
    self.dense1 = tf.keras.layers.Dense(units=units,
                                        activation=tf.nn.relu,
                                        kernel_initializer=tf.random.normal,
                                        bias_initializer=tf.random.normal)
    self.dense2 = tf.keras.layers.Dense(1)

  def call(self, x, training=True):
    # For Keras layers/models, implement `call` instead of `__call__`.
    x = x[:, tf.newaxis]
    x = self.dense1(x)
    x = self.dense2(x)
    return tf.squeeze(x, axis=1)
model = Model(64)
plt.plot(x.numpy(), y.numpy(), '.', label='data')
plt.plot(x, f(x),  label='Ground truth')
plt.plot(x, model(x), label='Untrained predictions')
plt.title('Before training')
plt.legend();

png

Viết một vòng lặp đào tạo cơ bản:

variables = model.variables

optimizer = tf.optimizers.SGD(learning_rate=0.01)

for step in range(1000):
  with tf.GradientTape() as tape:
    prediction = model(x)
    error = (y-prediction)**2
    mean_error = tf.reduce_mean(error)
  gradient = tape.gradient(mean_error, variables)
  optimizer.apply_gradients(zip(gradient, variables))

  if step % 100 == 0:
    print(f'Mean squared error: {mean_error.numpy():0.3f}')
Mean squared error: 16.123
Mean squared error: 0.997
Mean squared error: 0.964
Mean squared error: 0.946
Mean squared error: 0.932
Mean squared error: 0.921
Mean squared error: 0.913
Mean squared error: 0.907
Mean squared error: 0.901
Mean squared error: 0.897
plt.plot(x.numpy(),y.numpy(), '.', label="data")
plt.plot(x, f(x),  label='Ground truth')
plt.plot(x, model(x), label='Trained predictions')
plt.title('After training')
plt.legend();

png

Điều đó đang hoạt động, nhưng hãy nhớ rằng việc triển khai các tiện ích đào tạo phổ biến có sẵn trong mô-đun tf.keras . Vì vậy, hãy cân nhắc sử dụng chúng trước khi viết của riêng bạn. Để bắt đầu, các phương thức Model.compileModel.fit triển khai một vòng lặp đào tạo cho bạn:

new_model = Model(64)
new_model.compile(
    loss=tf.keras.losses.MSE,
    optimizer=tf.optimizers.SGD(learning_rate=0.01))

history = new_model.fit(x, y,
                        epochs=100,
                        batch_size=32,
                        verbose=0)

model.save('./my_model')
INFO:tensorflow:Assets written to: ./my_model/assets
plt.plot(history.history['loss'])
plt.xlabel('Epoch')
plt.ylim([0, max(plt.ylim())])
plt.ylabel('Loss [Mean Squared Error]')
plt.title('Keras training progress');

png

Tham khảo Các vòng huấn luyện cơ bảnhướng dẫn Keras để biết thêm chi tiết.