这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

TensorFlow 模型

Tensorflow 是一个用于创建神经网络的框架。它以可扩展的方式实现基本的线性代数和多变量微积分运算,使用户可以轻松地将这些运算链接到计算图中。

Vertica 支持使用在 Vertica 外部训练的 TensorFlow 1.x 和 2.x 模型导入、导出和进行预测。

数据库内 TensorFlow 与 Vertica 的集成提供了几点好处:

  • 您的模型存在于您的数据库中,因此您无需移动数据来进行预测。

  • 您可以处理的数据量仅受 Vertica 数据库大小的限制,这使得 Vertica 特别适合大数据机器学习。

  • Vertica 提供数据库内模型管理,因此您可以存储任意数量的模型。

  • 导入的模型是便携式的,可以导出以在其他地方使用。

当您运行 TensorFlow 模型以预测数据库中的数据时,Vertica 会调用 TensorFlow 进程来运行模型。这使 Vertica 能够支持您使用 TensorFlow 创建和训练的任何模型。Vertica 仅提供输入(您在 Vertica 数据库中的数据)并存储输出。

1 - TensorFlow 集成和目录结构

本页介绍如何将 Tensorflow 模型导入 Vertica、对 Vertica 数据库中的数据进行预测、导出模型以使其可在其他 Vertica 群集或第三方平台上使用。

有关每个操作的从头到尾的示例,请参阅 TensorFlow 示例

Vertica 支持借助于 TensorFlow 1.x 和 2.x 创建的模型,但强烈建议使用 2.x 来创建模型。

要将 TensorFlow 与 Vertica 结合使用,请在任何节点上安装 TFIntegration UDX 包。您只需执行一次该操作:

$ /opt/vertica/bin/admintools -t install_package -d database_name -p 'password' --package TFIntegration

TensorFlow 模型的目录和文件结构

在导入模型之前,您应当为每个模型创建一个单独的目录,其中包含以下各项之一。请注意,Vertica 在导入时使用目录名称作为模型名称:

  • model_name.pb:冻结图格式的训练模型

  • tf_model_desc.json:模型的描述

您可以使用 Machine-Learning-Examples/TensorFlow 存储库(或 opt/vertica/packages/TFIntegration/examples)中包含的脚本 freeze_tf2_model.py 来为给定的 TensorFlow 2 模型生成两个文件,但您可能需要根据您的用例以及您希望 Vertica 数据库与模型交互的方式对描述进行修改:

$ python3 Tensorflow/freeze_tf2_model.py your/model/directory

例如,tf_models 目录包含两个模型 tf_mnist_estimatortf_mnist_keras

tf_models/
├── tf_mnist_estimator
│   ├── mnist_estimator.pb
│   └── tf_model_desc.json
└── tf_mnist_keras
    ├── mnist_keras.pb
    └── tf_model_desc.json

tf_model_desc.json

tf_model_desc.json 文件构成了 TensorFlow 和 Vertica 之间的桥梁。它描述了模型的结构,以便 Vertica 可以将其输入和输出正确匹配到输入/输出表。

请注意,freeze_tf2_model.py 脚本会自动为您的模型生成此文件,并且此生成的文件通常可以按原样使用。对于较复杂的模型或用例,您可能必须编辑此文件。有关每个字段的详细分类,请参阅tf_model_desc.json 概述

将 TensorFlow 模型导入 Vertica

要导入 TensorFlow 模型,请使用 IMPORT_MODELS 和类别 'TENSORFLOW'

导入单个模型。请记住,Vertica 数据库使用目录名称作为模型名称:

select IMPORT_MODELS ( '/path/tf_models/tf_mnist_keras' USING PARAMETERS category='TENSORFLOW');
 import_models
---------------
 Success
(1 row)

使用通配符 (*) 导入目录中的所有模型(每个模型都有自己的目录):

select IMPORT_MODELS ('/path/tf_models/*' USING PARAMETERS category='TENSORFLOW');
 import_models
---------------
 Success
(1 row)

使用导入的 TensorFlow 模型进行预测

导入 TensorFlow 模型后,您可以使用该模型来预测 Vertica 表中的数据。

PREDICT_TENSORFLOW 函数与其他预测函数的不同之处在于它不接受任何影响输入列的参数,例如 "exclude_columns" 或 "id_column";相反,该函数总是对提供的所有输入列进行预测。但是,它确实接受 num_passthru_cols 参数,该参数允许用户“跳过”一些输入列,如下所示。

OVER(PARTITION BEST) 子句告知 Vertica 跨多个节点并行化操作。有关详细信息,请参阅窗口分区子句

=> select PREDICT_TENSORFLOW (*
                   USING PARAMETERS model_name='tf_mnist_keras', num_passthru_cols=1)
                   OVER(PARTITION BEST) FROM tf_mnist_test_images;

--example output, the skipped columns are displayed as the first columns of the output
 ID | col0 | col1 | col2 | col3 | col4 | col5 | col6 | col7 | col8 | col9
----+------+------+------+------+------+------+------+------+------+------
  1 |    0 |    0 |    1 |    0 |    0 |    0 |    0 |    0 |    0 |    0
  3 |    1 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0
  6 |    0 |    0 |    0 |    0 |    1 |    0 |    0 |    0 |    0 |    0
...

导出 TensorFlow 模型

Vertica 将模型导出为冻结图,然后可以随时重新导入。请记住,保存为冻结图的模型无法进一步训练。

使用 EXPORT_MODELS 导出 TensorFlow 模型。例如,要将 tf_mnist_keras 模型导出到 /path/to/export/to 目录:

=> SELECT EXPORT_MODELS ('/path/to/export/to', 'tf_mnist_keras');
 export_models
---------------
 Success
(1 row)

导出 TensorFlow 模型时,Vertica 数据库会创建并使用指定的目录来存储描述模型的文件:

$ ls tf_mnist_keras/
crc.json  metadata.json  mnist_keras.pb  model.json  tf_model_desc.json

.pbtf_model_desc.json 文件描述了模型,其余文件是由 Vertica 数据库创建的组织文件。

另请参阅

2 - TensorFlow 示例

Vertica 使用 TFIntegration UDX 包与 TensorFlow 集成。您可以在 Vertica 数据库之外训练模型,然后将它们导入 Vertica 并对数据进行预测。

TensorFlow 脚本和数据集包含在 Machine-Learning-Examples/TensorFlow 下的 GitHub 存储库中。

下面的示例创建一个在 MNIST 手写数字分类数据集上训练的 Keras(一种 TensorFlow API)神经网络模型,其各层如下所示。

数据从上到下穿过每一层,每一层在返回分数之前修改输入。在此示例中,传入的数据是一组手写阿拉伯数字图像,输出内容是输入图像为特定数字的概率:

inputs = keras.Input(shape=(28, 28, 1), name="image")
x = layers.Conv2D(32, 5, activation="relu")(inputs)
x = layers.MaxPooling2D(2)(x)
x = layers.Conv2D(64, 5, activation="relu")(x)
x = layers.MaxPooling2D(2)(x)
x = layers.Flatten()(x)
x = layers.Dense(10, activation='softmax', name='OUTPUT')(x)
tfmodel = keras.Model(inputs, x)

有关 TensorFlow 如何与 Vertica 数据库交互以及如何导入更复杂模型的详细信息,请参阅TensorFlow 集成和目录结构

为 Vertica 准备 TensorFlow 模型

以下过程在 Vertica 之外进行。

训练和保存 TensorFlow 模型

  1. 安装 TensorFlow 2

  2. 训练您的模型。对于此特定示例,您可以运行 train_simple_model.py 来训练和保存模型。否则,一般而言,您可以在 Python 中手动训练您的模型,然后保存它

    $ mymodel.save('my_saved_model_dir')
    
  3. 运行 Machine-Learning-Examples 存储库opt/vertica/packages/TFIntegration/examples 中包含的 freeze_tf2_model.py 脚本,指定您的模型和输出目录(可选,默认为 frozen_tfmodel)。

    此脚本将您保存的模型转换为与 Vertica 兼容的冻结图格式并创建 tf_model_desc.json 文件,该文件描述了 Vertica 应如何将其表转换为 TensorFlow 张量:

    $ ./freeze_tf2_model.py path/to/tf/model frozen_model_dir
    

导入 TensorFlow 模型并在 Vertica 中进行预测

  1. 如果您尚未安装 TFIntegration UDX 包,请以 dbadmin 身份在任何节点上安装。您只需执行一次该操作。

    $ /opt/vertica/bin/admintools -t install_package -d database_name -p 'password' --package TFIntegration
    

  2. directory 复制到 Vertica 群集中的任何节点并导入模型:

    => SELECT IMPORT_MODELS('path/to/frozen_model_dir' USING PARAMETERS category='TENSORFLOW');
    
  3. 导入要对其进行预测的数据集。对于此示例:

    1. Machine-Learning-Examples/TensorFlow/data 目录复制到 Vertica 群集中的任何节点。

    2. 从该 data 目录中,运行 SQL 脚本 load_tf_data.sql 以加载 MNIST 数据集:

      $ vsql -f load_tf_data.sql
      
  4. 使用 PREDICT_TENSORFLOW 在数据集上使用您的模型进行预测。在此示例中,该模型用于对 MNIST 数据集中的手写数字图像进行分类:

    => SELECT PREDICT_TENSORFLOW (*
                       USING PARAMETERS model_name='tf_mnist_keras', num_passthru_cols=1)
                       OVER(PARTITION BEST) FROM tf_mnist_test_images;
    
    --example output, the skipped columns are displayed as the first columns of the output
     ID | col0 | col1 | col2 | col3 | col4 | col5 | col6 | col7 | col8 | col9
    ----+------+------+------+------+------+------+------+------+------+------
      1 |    0 |    0 |    1 |    0 |    0 |    0 |    0 |    0 |    0 |    0
      3 |    1 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0 |    0
      6 |    0 |    0 |    0 |    0 |    1 |    0 |    0 |    0 |    0 |    0
    ...
    
  5. 要使用 EXPORT_MODELS 导出模型:

    => SELECT EXPORT_MODELS('/path/to/export/to', 'tf_mnist_keras');
     EXPORT_MODELS
    ---------------
     Success
    (1 row)
    

TensorFlow 1(已弃用)

  1. 使用 Python 3.7 或更低版本安装 TensorFlow 1.15

  2. Machine-Learning-Examples/TensorFlow/tf1 中运行 train_save_model.py 以训练模型并将其保存为 TensorFlow 和冻结图格式。

另请参阅

3 - tf_model_desc.json 概述

在导入外部训练的 TensorFlow 模型之前,您必须:

  • 将模型保存为冻结图 (.pb) 格式

  • 创建 tf_model_desc.json,向 Vertica 数据库描述如何将其输入和输出映射到输入/输出表

方便的是,Machine-Learning-Examples 存储库的 TensorFlow 目录中(和opt/vertica/packages/TFIntegration/examples中)包含的脚本 freeze_tf2_model.py 会自动完成这两项工作。在大多数情况下,生成的 tf_model_desc.json 可以按原样使用,但对于较复杂的数据集和用例,您可能需要对其进行编辑。

用于示例数据集的 tf_model_desc.json

下面的 tf_model_desc.json 是从 TensorFlow 示例 使用的 MNIST 手写数据集生成的。

{
    "frozen_graph": "mnist_keras.pb",
    "input_desc": [
        {
            "op_name": "image_input",
            "tensor_map": [
                {
                    "idx": 0,
                    "dim": [
                        1,
                        28,
                        28,
                        1
                    ],
                    "col_start": 0
                }
            ]
        }
    ],
    "output_desc": [
        {
            "op_name": "OUTPUT/Softmax",
            "tensor_map": [
                {
                    "idx": 0,
                    "dim": [
                        1,
                        10
                    ],
                    "col_start": 0
                }
            ]
        }
    ]
}

该文件描述了模型输入和输出的结构。它必须包含一个与 .pb 模型的文件名匹配的 frozen_graph 字段、一个 input_desc 字段和一个 output_desc 字段。

  • input_descoutput_desc:TensorFlow 图中输入和输出节点的描述。其中每一个都包含以下字段:
    • op_name:创建和训练模型时设置的操作节点名称。您通常可以从 tfmodel.inputstfmodel.outputs 检索这些参数的名称。例如:

      
      $ print({t.name:t for t in tfmodel.inputs})
      {'image_input:0': <tf.Tensor 'image_input:0' shape=(?, 28, 28, 1) dtype=float32>}
      
      $ print({t.name:t for t in tfmodel.outputs})
      {'OUTPUT/Softmax:0': <tf.Tensor 'OUTPUT/Softmax:0' shape=(?, 10) dtype=float32>}
      

      在本例中,op_name 的相应值如下。

      • input_descimage_input

      • output_descOUTPUT/Softmax

      有关此过程的更详细示例,请查看 freeze_tf2_model.py 的代码。

    • tensor_map:如何将张量映射到可通过以下方式指定的 Vertica 列:

      • idx:张量的索引(第一个输入/输出应为 0,第二个输入/输出应为 1,等等)

      • dim:保存张量维度的向量;它提供了列数

      • col_start(仅在未指定 col_idx 时使用):起始列索引。当与 dim 一起使用时,它指定从 col_start 开始、在 col_start+dim 结束的 Vertica 列的索引范围;Vertica 从索引 col_start 指定的列处开始,获取接下来的 dim

      • col_idx:Vertica 列中对应于修整张量的索引。这允许您显式指定 Vertica 列的索引,否则无法使用 col_startdim 将其指定为简单范围(例如 1、3、5、7)

      • data_type(未显示):输入或输出的数据类型,为以下之一:

        • TF_FLOAT(默认值)

        • TF_DOUBLE

        • TF_INT8

        • TF_INT16

        • TF_INT32

        • TF_INT64

复杂 tf_model_desc.json 示例

下面是一个包含多个输入和输出的较复杂示例:

{
    "input_desc": [
        {
            "op_name": "input1",
            "tensor_map": [
                {
                    "idx": 0,
                    "dim": [
                        4
                    ],
                    "col_idx": [
                        0,
                        1,
                        2,
                        3
                    ]
                },
                {
                    "idx": 1,
                    "dim": [
                        2,
                        2
                    ],
                    "col_start": 4
                }
            ]
        },
        {
            "op_name": "input2",
            "tensor_map": [
                {
                    "idx": 0,
                    "dim": [],
                    "col_idx": [
                        8
                    ]
                },
                {
                    "idx": 1,
                    "dim": [
                        2
                    ],
                    "col_start": 9
                }
            ]
        }
    ],
    "output_desc": [
        {
            "op_name": "output",
            "tensor_map": [
                {
                    "idx": 0,
                    "dim": [
                        2
                    ],
                    "col_start": 0
                }
            ]
        }
    ]
}

另请参阅