如何在tensorflow中实现sklearn的PolynomialFeatures?

Posted

技术标签:

【中文标题】如何在tensorflow中实现sklearn的PolynomialFeatures?【英文标题】:How to implement sklearn's PolynomialFeatures in tensorflow? 【发布时间】:2017-09-04 21:53:28 【问题描述】:

我正在尝试将 scikit-learn 的 PolynomialFeatures 实现为 tensorflow 和 Keras 中的前馈神经网络中的一个层。为简单起见,我将举一个使用 NumPy 数组的示例。如果一个batch有3个样本,并且某一层的激活等于(3, 2)形矩阵

>>> X = np.arange(0, 6).reshape(2, 3)
>>> X
array([[0, 1],
       [2, 3],
       [4, 5]])

那么我希望下一层的激活等于X 的 2 次多项式特征扩展:

>>> from sklearn.preprocessing import PolynomialFeatures
>>> PolynomialFeatures(degree=2).fit_transform(X)
array([[  1.,   0.,   1.,   0.,   0.,   1.],
       [  1.,   2.,   3.,   4.,   6.,   9.],
       [  1.,   4.,   5.,  16.,  20.,  25.]])

也就是说,如果层 i 的激活是矩阵X(形状为(batch_size, num_features)),那么对于参数选择degree=2 我想要层的激活i + 1

的串联
    一列batch_size 很多1.X 自己, 以及X 的所有无序列对的元素乘积:X[:, 0] * X[:, 0]X[:, 0] * X[:, 1]X[:, 1] * X[:, 1]

到目前为止,我最接近的解决方案是连接X 的一些幂:

import keras.backend as K
X = K.reshape(K.arange(0, 6), (3, 2))
with K.get_session().as_default():
    print(K.concatenate([K.pow(X, 0), K.pow(X, 1), K.pow(X, 2)]).eval())

输出:

[[ 1  1  0  1  0  1]
 [ 1  1  2  3  4  9]
 [ 1  1  4  5 16 25]]

即,1s 的两列(比我想要的多一个,但我可以忍受这种重复)、X 本身和X 平方元素的连接。

有没有办法计算 不同 列的乘积(以自动可微分的方式)?我无法弄清楚如何在张量流中实现的step of PolynomialFeatures 是用另一个矩阵的某些列的乘积(跨越axis=1)填充矩阵的列:XP[:, i] = X[:, c].prod(axis=1),其中c 是一个元组(0, 0, 1) 等索引。

【问题讨论】:

【参考方案1】:

如果你构建一个包含所有 n 个基本特征的向量 v_1 并用它自己创建该向量的 outer product,则结果将是所有特征成对乘积的对称 (n,n) 矩阵 M_2(在对角线)。您可以使用tensorflow_probability.math.fill_triangular_inverse 将唯一条目的三角形切片提取到向量 v_2 中。然后,v_1 和 v_2 的串联将用作高达 2 次的多项式特征向量。这是一个只有两个特征维度的示例:

v_1 = (x,y) ==> M_2 = (xx, xy; yx, yy) = (x^2, xy; xy, y^2) ==> v_2 = (x^2, xy, y^2)

通过将 v_1 增加 1,您还将在同一输出中获得常数 1 和一阶值。

v_2 和 v_1 的外积将返回一个矩形矩阵 M_3,其中包含具有重复项的三次项。可能有一些技巧可以过滤掉重复项,甚至可以推广到更高的程度 d. (生成外积 d-cube 并提取广义三角形切片是一种低效的解决方案。)

当然可以通过其他方式使唯一多项式特征的向量达到所需程度(即枚举有界基数的多集),但是生成的特征的绝对数量将不可避免地变得难以管理/臃肿,除非输入维度中的任何一个n 或度数 d 非常小。 (见https://en.wikipedia.org/wiki/Multiset#Counting_multisets)

对于有限数量的多项式(或一般乘积(xi^wi))特征,是否可以使用可训练的维度选择器?对于某些应用,Deepmind 的 NALU 单元可能很有用。他们能够学习加权加法和加权乘法(数)。

另一种提取有限多项式特征的方法是堆叠 f(PI(wij*xj+bij)) 形式的乘法层(具有统一激活 f),如 Yadav, Kalra & John (2006) 所述并由我自己实现here(尚未彻底测试)。

PolynomialCrossing 定义了一种在堆叠时提供(有损)多项式特征提取的层类型。每一层基本上将前一个输出层的线性投影与初始输入相乘。它被证明是有用的。

【讨论】:

以上是关于如何在tensorflow中实现sklearn的PolynomialFeatures?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 TensorFlow 中实现递归神经网络?

如何在tensorflow中实现stdp?

如何在tensorflow中实现多元线性随机梯度下降算法?

如何在 LSTM 中实现 Tensorflow 批量归一化

如何从 pandas 数据帧在 tensorflow v1 中实现 LSTM

在 TensorFlow 2.0 中实现自定义损失函数