这是本节的多页打印视图。
点击此处打印.
返回本页常规视图.
在 Vertica 中使用外部模型
为了让您在机器学习方面获得最大的灵活性和可扩展性,Vertica 支持使用 PMML 和 TensorFlow 模型进行导入、导出和预测。
机器学习配置参数 MaxModelSizeKB 设置可以导入 Vertica 的模型的最大大小。
对 PMML 模型的支持
Vertica 支持以预测模型标记语言 (PMML) 格式导入和导出 K-means、线性回归和逻辑回归机器学习模型。借助对这种独立于平台的模型格式的支持,您可以使用其他平台上训练的模型来预测 Vertica 数据库中存储的数据。您还可以使用 Vertica 作为模型存储库。Vertica 支持 PMML 4.4 版。
通过 PREDICT_PMML 函数,您可以使用在 Vertica 中存档的 PMML 模型对 Vertica 数据库中存储的数据运行预测。
有关详细信息,请参阅使用 PMML 模型。
有关 Vertica 当前支持和不支持的 PMML 属性的详细信息,请参阅PMML 特征和属性。
对 TensorFlow 模型的支持
Vertica 现在支持导入经过训练的 TensorFlow 模型,并使用这些模型在 Vertica 中对 Vertica 数据库中存储的数据进行预测。Vertica 支持在 TensorFlow 1.15 版中训练的 TensorFlow 模型。
PREDICT_TENSORFLOW 函数可让您使用任何 TensorFlow 模型预测 Vertica 中的数据。
有关其他信息,请参阅TensorFlow 模型。
支持外部模型的其他函数
以下函数同时支持 PMML 和 TensorFlow 模型:
IMPORT_MODELS
EXPORT_MODELS
GET_MODEL_ATTRIBUTE
GET_MODEL_SUMMARY
1 - TensorFlow 模型
Tensorflow 是一个用于创建神经网络的框架。它以可扩展的方式实现基本的线性代数和多变量微积分运算,使用户可以轻松地将这些运算链接到计算图中。
Vertica 支持使用在 Vertica 外部训练的 TensorFlow 1.x 和 2.x 模型导入、导出和进行预测。
数据库内 TensorFlow 与 Vertica 的集成提供了几点好处:
-
您的模型存在于您的数据库中,因此您无需移动数据来进行预测。
-
您可以处理的数据量仅受 Vertica 数据库大小的限制,这使得 Vertica 特别适合大数据机器学习。
-
Vertica 提供数据库内模型管理,因此您可以存储任意数量的模型。
-
导入的模型是便携式的,可以导出以在其他地方使用。
当您运行 TensorFlow 模型以预测数据库中的数据时,Vertica 会调用 TensorFlow 进程来运行模型。这使 Vertica 能够支持您使用 TensorFlow 创建和训练的任何模型。Vertica 仅提供输入(您在 Vertica 数据库中的数据)并存储输出。
1.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_estimator
和 tf_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
.pb
和 tf_model_desc.json
文件描述了模型,其余文件是由 Vertica 数据库创建的组织文件。
另请参阅
1.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 模型
-
安装 TensorFlow 2。
-
训练您的模型。对于此特定示例,您可以运行 train_simple_model.py 来训练和保存模型。否则,一般而言,您可以在 Python 中手动训练您的模型,然后保存它:
$ mymodel.save('my_saved_model_dir')
-
运行 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 中进行预测
-
如果您尚未安装 TFIntegration UDX 包,请以 dbadmin
身份在任何节点上安装。您只需执行一次该操作。
$ /opt/vertica/bin/admintools -t install_package -d database_name -p 'password' --package TFIntegration
-
将 directory
复制到 Vertica 群集中的任何节点并导入模型:
=> SELECT IMPORT_MODELS('path/to/frozen_model_dir' USING PARAMETERS category='TENSORFLOW');
-
导入要对其进行预测的数据集。对于此示例:
-
将 Machine-Learning-Examples/TensorFlow/data
目录复制到 Vertica 群集中的任何节点。
-
从该 data
目录中,运行 SQL 脚本 load_tf_data.sql
以加载 MNIST 数据集:
$ vsql -f load_tf_data.sql
-
使用 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
...
-
要使用 EXPORT_MODELS 导出模型:
=> SELECT EXPORT_MODELS('/path/to/export/to', 'tf_mnist_keras');
EXPORT_MODELS
---------------
Success
(1 row)
注意
虽然您在从 Vertica 导出 TensorFlow 模型后无法继续训练它,但您可以使用它来预测另一个 Vertica 群集中的数据或 Vertica 外部另一个平台上的数据。
TensorFlow 1(已弃用)
-
使用 Python 3.7 或更低版本安装 TensorFlow 1.15。
-
在 Machine-Learning-Examples/TensorFlow/tf1
中运行 train_save_model.py
以训练模型并将其保存为 TensorFlow 和冻结图格式。
另请参阅
1.3 - tf_model_desc.json 概述
在导入外部训练的 TensorFlow 模型之前,您必须:
方便的是,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_desc 和 output_desc:TensorFlow 图中输入和输出节点的描述。其中每一个都包含以下字段:
-
op_name:创建和训练模型时设置的操作节点名称。您通常可以从
tfmodel.inputs
和
tfmodel.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 的相应值如下。
有关此过程的更详细示例,请查看 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_start 和 dim 将其指定为简单范围(例如 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
}
]
}
]
}
另请参阅
2 - 使用 PMML 模型
Vertica 可以使用 4.4 版及以下版本的 PMML 模型导入、导出和进行预测。
2.1 - 以 PMML 格式导出 Vertica 模型
您可以利用 Vertica 中的内置分布式算法来训练机器学习模型。在某些情况下,您可能希望在 Vertica 之外(例如在边缘节点上)使用这些模型进行预测。现在,您可以将模型导出为 PMML 格式,并使用导出后的模型通过一个支持读取和评估 PMML 模型的库或平台进行预测。
这里有一个在 Vertica 中训练模型后以 PMML 格式导出的示例。下图显示了示例的工作流程。我们使用 vsql 来运行该示例。
假设您想在名为“患者”的关系中训练数据的逻辑回归模型,以预测患者在接受治疗后的第二次发作和特质焦虑。
训练后,模型显示在名为 V_CATALOG.MODELS 的系统表中,其中列出了 Vertica 中存档的 ML 模型。
=> -- Training a logistic regression model on a training_data
=> SELECT logistic_reg('myModel', 'patients', 'second_attack', 'treatment, trait_anxiety');
logistic_reg
---------------------------
Finished in 5 iterations
(1 row)
=> -- Looking at the models table
=> SELECT model_name, schema_name, category, model_type, create_time, size FROM models;
model_name | schema_name | category | model_type | create_time | size
------------+-------------+----------------+---------------------+-------------------------------+------
myModel | public | VERTICA_MODELS | LOGISTIC_REGRESSION | 2020-07-28 00:05:18.441958-04 | 1845
(1 row)
可以使用 GET_MODEL_SUMMARY 函数来查看模型摘要。
=> -- Looking at the summary of the model
=> \t
Showing only tuples.
=> SELECT get_model_summary(USING PARAMETERS model_name='myModel');
=======
details
=======
predictor |coefficient|std_err |z_value |p_value
-------------+-----------+--------+--------+--------
Intercept | -6.36347 | 3.21390|-1.97998| 0.04771
treatment | -1.02411 | 1.17108|-0.87450| 0.38185
trait_anxiety| 0.11904 | 0.05498| 2.16527| 0.03037
==============
regularization
==============
type| lambda
----+--------
none| 1.00000
===========
call_string
===========
logistic_reg('public.myModel', 'patients', '"second_attack"', 'treatment, trait_anxiety'
USING PARAMETERS optimizer='newton', epsilon=1e-06, max_iterations=100, regularization='none', lambda=1, alpha=0.5)
===============
Additional Info
===============
Name |Value
------------------+-----
iteration_count | 5
rejected_row_count| 0
accepted_row_count| 20
您还可以使用 GET_MODEL_ATTRIBUTE 函数检索模型的属性。
=> \t
Tuples only is off.
=> -- The list of the attributes of the model
=> SELECT get_model_attribute(USING PARAMETERS model_name='myModel');
attr_name | attr_fields | #_of_rows
--------------------+---------------------------------------------------+-----------
details | predictor, coefficient, std_err, z_value, p_value | 3
regularization | type, lambda | 1
iteration_count | iteration_count | 1
rejected_row_count | rejected_row_count | 1
accepted_row_count | accepted_row_count | 1
call_string | call_string | 1
(6 rows)
=> -- Returning the coefficients of the model in a tabular format
=> SELECT get_model_attribute(USING PARAMETERS model_name='myModel', attr_name='details');
predictor | coefficient | std_err | z_value | p_value
---------------+-------------------+--------------------+--------------------+--------------------
Intercept | -6.36346994178182 | 3.21390452471434 | -1.97998101463435 | 0.0477056620380991
treatment | -1.02410605239327 | 1.1710801464903 | -0.874496980810833 | 0.381847663704613
trait_anxiety | 0.119044916668605 | 0.0549791755747139 | 2.16527285875412 | 0.0303667955962211
(3 rows)
您可以在一个简单的语句中使用 EXPORT_MODELS 函数将模型导出为 PMML 格式,如下所示。
=> -- Exporting the model as PMML
=> SELECT export_models('/data/username/temp', 'myModel' USING PARAMETERS category='PMML');
export_models
---------------
Success
(1 row)
另请参阅
2.2 - 使用 PMML 模型导入和预测
作为 Vertica 用户,您可以在其他平台上训练 ML 模型,将其转换为标准 PMML 格式,然后将其导入 Vertica 以对存储在 Vertica 关系中的数据进行数据库内预测。
这里有一个如何导入在 Spark 中训练的 PMML 模型的示例。下图显示了示例的工作流程。
您可以在一个简单的语句中使用 IMPORT_MODELS 函数来导入 PMML 模型。导入的模型随后会出现在名为 V_CATALOG.MODELS 的系统表中,其中列出了 Vertica 中存档的 ML 模型。
=> -- importing the PMML model trained and generated in Spark
=> SELECT import_models('/data/username/temp/spark_logistic_reg' USING PARAMETERS category='PMML');
import_models
---------------
Success
(1 row)
=> -- Looking at the models table=> SELECT model_name, schema_name, category, model_type, create_time, size FROM models;
model_name | schema_name | category | model_type | create_time | size
--------------------+-------------+----------+-----------------------+-------------------------------+------
spark_logistic_reg | public | PMML | PMML_REGRESSION_MODEL | 2020-07-28 00:12:29.389709-04 | 5831
(1 row)
可以使用 GET_MODEL_SUMMARY 函数来查看模型摘要。
=> \t
Showing only tuples.
=> SELECT get_model_summary(USING PARAMETERS model_name='spark_logistic_reg');
=============
function_name
=============
classification
===========
data_fields
===========
name |dataType| optype
-------+--------+-----------
field_0| double |continuous
field_1| double |continuous
field_2| double |continuous
field_3| double |continuous
field_4| double |continuous
field_5| double |continuous
field_6| double |continuous
field_7| double |continuous
field_8| double |continuous
target | string |categorical
==========
predictors
==========
name |exponent|coefficient
-------+--------+-----------
field_0| 1 | -0.23318
field_1| 1 | 0.73623
field_2| 1 | 0.29964
field_3| 1 | 0.12809
field_4| 1 | -0.66857
field_5| 1 | 0.51675
field_6| 1 | -0.41026
field_7| 1 | 0.30829
field_8| 1 | -0.17788
===============
Additional Info
===============
Name | Value
-------------+--------
is_supervised| 1
intercept |-1.20173
您还可以使用 GET_MODEL_ATTRIBUTE 函数检索模型的属性。
=> \t
Tuples only is off.
=> -- The list of the attributes of the PMML model
=> SELECT get_model_attribute(USING PARAMETERS model_name='spark_logistic_reg');
attr_name | attr_fields | #_of_rows
---------------+-----------------------------+-----------
is_supervised | is_supervised | 1
function_name | function_name | 1
data_fields | name, dataType, optype | 10
intercept | intercept | 1
predictors | name, exponent, coefficient | 9
(5 rows)
=> -- The coefficients of the PMML model
=> SELECT get_model_attribute(USING PARAMETERS model_name='spark_logistic_reg', attr_name='predictors');
name | exponent | coefficient
---------+----------+--------------------
field_0 | 1 | -0.2331769167607
field_1 | 1 | 0.736227459496199
field_2 | 1 | 0.29963728232024
field_3 | 1 | 0.128085369856188
field_4 | 1 | -0.668573096260048
field_5 | 1 | 0.516750679584637
field_6 | 1 | -0.41025989394959
field_7 | 1 | 0.308289533913736
field_8 | 1 | -0.177878773139411
(9 rows)
然后,您可以使用 PREDICT_PMML 函数将导入的模型应用于关系以进行数据库内预测。模型的内部参数可以通过名称或列出的位置与输入关系的列名匹配。也可以将直接输入值馈送到函数,如下所示。
=> -- Using the imported PMML model for scoring direct input values
=> SELECT predict_pmml(1.5,0.5,2,1,0.75,4.2,3.1,0.9,1.1
username(> USING PARAMETERS model_name='spark_logistic_reg', match_by_pos=true);
predict_pmml
--------------
1
(1 row)
=> -- Using the imported PMML model for scoring samples in a table
=> SELECT predict_pmml(* USING PARAMETERS model_name='spark_logistic_reg') AS prediction
=> FROM test_data;
prediction
------------
1
0
(2 rows)
另请参阅
2.3 - PMML 特征和属性
在 Vertica 中使用外部模型 概述了 Vertica 支持使用外部模型的功能。本主题提供有关 Vertica 如何支持使用 PMML 模型的限制的更多详细信息。
为了得到 Vertica 的支持,PMML 模型:
支持的 PMML 标记和属性
下表列出了支持的 PMML 标记及其属性。