TensorFlow 基础概念

2022-07-20  本文已影响0人  hdszzwy

本章将对TensorFlow的基本概念做简介,每节会对一个大概念做一个概论--你可以在每节末尾找到更详细的链接地址。
TensorFlow是机器学习的一个端对端平台,支持以下操作:

Tensors

TensorFlow的运算是基于多维数组或张量,这些运算对象在TensorFlow中被标识为tf.Tensor对象。下面的代码描述了一个二维张量:

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

对于Tensor来说,这里有两个相当重要的概念shape和dtype:

x + x

结果为:

tf.Tensor(
[[ 2.  4.  6.]
 [ 8. 10. 12.]], shape=(2, 3), dtype=float32)
5 * x

结果为:

tf.Tensor(
[[ 5. 10. 15.]
 [20. 25. 30.]], shape=(2, 3), dtype=float32)
x @ tf.transpose(x)

结果为:

tf.Tensor(
[[14. 32.]
 [32. 77.]], shape=(2, 2), dtype=float32)
tf.concat([x, x, x], axis=0)

结果为:

tf.Tensor(
[[1. 2. 3.]
 [4. 5. 6.]
 [1. 2. 3.]
 [4. 5. 6.]
 [1. 2. 3.]
 [4. 5. 6.]], shape=(6, 3), dtype=float32)
tf.concat([x, x, x], axis=1)

结果为:

tf.Tensor(
[[1. 2. 3. 1. 2. 3. 1. 2. 3.]
 [4. 5. 6. 4. 5. 6. 4. 5. 6.]], shape=(2, 9), dtype=float32)
tf.nn.softmax(x, axis=1)

结果为:

tf.Tensor(
[[0.09003057 0.24472848 0.66524094]
 [0.09003057 0.24472848 0.66524094]], shape=(2, 3), dtype=float32)
tf.reduce_sum(x)

结果为:

tf.Tensor(21.0, shape=(), dtype=float32)

在CPU上执行大规模计算时,效率并不高。在进行配置之后,TensorFlow可以运行在如GPU之类的硬件之上执行运行操作,效率很高。

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

结果为:

TensorFlow **IS NOT** using the GPU

更多细节参考Tensor Guide

变量

tf.Tensor类型是不可变类型,当需要保存如模型参数之类的变量时,可以使用tf.Variable类型

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

更多细节参阅Variables guide

自动微分

梯度下降法及相关算法是现代机器学习的重要基础。
TensorFlow实现了基于微积分学的自动微分,可以帮助你自动计算梯度。通常你会使用这个功能来计算模型的loss关于其参数的梯度。

import tensorflow as tf

x = tf.Variable(1.0)


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


f(x)

结果为:

tf.Tensor(-2.0, shape=(), dtype=float32)

在x=1.0,y=f(x) = -2,其导数为y' = 2 * x + 2 = 4。TensorFlow可以自动计算出导数

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

g_x = tape.gradient(y, x)

g_x

运行结果为:

tf.Tensor(4.0, shape=(), dtype=float32)

这是一个对简单标量x求导数的例子。TensorFlow可以对任意数量的张量同时计算梯度。
参考自动微分获得更多的详情。

图和tf.function

TensorFlow可以让你像使用其他python库一样交互式地使用TensorFlow,TensorFlow还提供了一些工具:

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


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

print(my_func(x))

结果为:

Tracing
tf.Tensor(6, shape=(), dtype=int32)

在接下来的调用中,TensorFlow只会运行优化过的图代码,跳过非TensorFlow代码。下面的代码中my_func不会打印“Tracing”字符,因为print是一个纯python代码,不是TensorFlow的函数。

x = tf.constant([10, 9, 8])
my_func(x)

结果为:

tf.Tensor(27, shape=(), dtype=int32)

一个图方法会为不同的入参类型(shape and dtype)创建不同的实例,即下面的代码会生成一个新的图。

x = tf.constant([10.0, 9.1, 8.2], dtype=tf.float32)
my_func(x)

这种图快照提供了两个优点:

Modules, Layers 和models

tf.Module是用于管理tf.Variables对象以及基于这些对象的tf.function对象的类。tf.Module类是实现如下两个重要功能特性的必要条件:

import tensorflow as tf


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

save_path = './saved'
tf.saved_model.save(mod, save_path)


reload = tf.saved_model.load(save_path)
print(reload.multiply(tf.constant([1, 2, 3])))

保存结果SavedModel独立于创建时的代码。你可以重新载入SavedModel至Python、其他支持TensorFlow的编程语言或TensorFlow Serving。你也可以将其运行在 TensorFlow LiteTensorFlow JS
基于tf.Module的tf.keras.layers.Layer和tf.keras.Model类提供了更多的功能和便捷的方法用于编译、训练和保存模型,这些将在下一节提及。
更多细节请参考Intro to modules

Training Loops

下面,我们将上述的所有概念综合使用起来建立一个模型,并且从头开始进行训练。
首先我们创建一下测试数据,使用二次曲线产生一些数据点。

import tensorflow as tf

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

plt.show()
Figure_1.png

然后,创建一个模型

class Model(tf.keras.Model):
    def __init__(self, units):
        super(Model, self).__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):
        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()
plt.show()
Figure_1.png

编写代码进入训练阶段。由于tf.keras已经集成了大多数常用的训练工具,因此直接调用keras自带的功能即可。为此,你需要使用Model.compile和Model.fit方法来实现训练过程。

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

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

model.save("./my_model")

将训练过程中的loss打印出来:

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')
plt.show()
Figure_1.png
更多详情请参考 Basic training loopsKeras guide
上一篇下一篇

猜你喜欢

热点阅读