如何在tensorflow中实现sklearn的PolynomialFeatures?

Cha*_*itt 7 python polynomial-math tensorflow keras-layer

我试图将scikit-learn的PolynomialFeatures实现为tensorflow和Keras中的前馈神经网络中的一个层.为简单起见,我将举例说明使用NumPy数组.如果批次具有三个样本并且某个层的激活等于(3,2)形矩阵

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

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

>>> 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.]])
Run Code Online (Sandbox Code Playgroud)

也就是说,如果层i的激活是X(形状(batch_size, num_features))矩阵,那么对于参数选择,degree=2我希望层i + 1的激活是一个串联

  1. batch_size许多1.人的专栏,
  2. X 本身,
  3. 和所有无序对的列的元素方面的产品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())
Run Code Online (Sandbox Code Playgroud)

输出:

[[ 1  1  0  1  0  1]
 [ 1  1  2  3  4  9]
 [ 1  1  4  5 16 25]]
Run Code Online (Sandbox Code Playgroud)

也就是说,两列1s 的连接(比我想要的多一个,但我可以忍受这种重复),X本身和X元素方面的平方.

有没有办法计算不同列的产品(以自动差异化的方式)?我无法弄清楚如何在tensorflow中实现的PolynomialFeatures步骤是axis=1另一个矩阵的某些列的乘积(跨)填充矩阵的列:XP[:, i] = X[:, c].prod(axis=1),其中c是索引的元组,例如(0, 0, 1).

Eli*_*sle 1

如果构建所有 n 个基本特征的向量 v_1 并对该向量与其自身进行外积则结果将是特征的所有成对乘积的对称 (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 )

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

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

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

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

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

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