使用稀疏数据训练 TensorFlow

4

我想在Python的TensorFlow中使用稀疏张量进行训练。我找到了很多关于如何做到这一点的代码,但是它们都没有起作用。

这里是一个示例代码,展示了我的意思,它会抛出一个错误:

import numpy as np
x_vals = tf.sparse.SparseTensor([[0, 0], [0, 1], [1, 2]], [1, 2, 1], [2, 3])
#x_vals = tf.sparse.to_dense(x_vals)    #this line decides, if there is an error
y_vals = np.array([0, 1])

layer_args = lambda : None
layer_args.input_shape = (3,)
layer_args.activation = "sigmoid"
layer_args.use_bias = False

model = tf.keras.models.Sequential(tf.keras.layers.Dense(1, **layer_args.__dict__))

model.compile(loss = "mse")

model.fit(x_vals, y_vals)

错误信息如下:

错误是:

ValueError: 两个结构不具有相同的嵌套结构。

...并附带大量的堆栈跟踪信息。

1个回答

4

好的,我弄清楚了它是如何工作的。最简单的解决方案是使用生成器:

from random import shuffle
def data_generator(x_vals, y_vals):
    inds = list(range(x_vals.shape[0]))
    shuffle(inds)
    for ind in inds:
        yield (x_vals[ind, :].todense(), y_vals[ind])

然后使用该生成器作为拟合中的x值:

model.fit(data_generator(x_vals, y_vals))

然而,它非常缓慢。而且你只能一次训练一个轮次,不能使用很多keras的特性。另一种可能的方法是使用tensorflow.keras.utils.Sequence:

class SparseSequence(tf.keras.utils.Sequence):
    def __init__(self, x_vals, y_vals, batch_size = 32):
        self.x_vals = x_vals
        self.y_vals = y_vals
        self.inds = list(range(x_vals.shape[0]))
        shuffle(self.inds)
        self.batch_size = batch_size
    def __getitem__(self, item):
        from_ind = self.batch_size * item
        to_ind = self.batch_size * (item + 1)
        return (self.x_vals[self.inds[from_ind:to_ind], :].todense(),
                y_vals[self.inds[from_ind:to_ind]])
    def on_epoch_end(self):
        shuffle(self.inds)
    def __len__(self):
        return math.ceil(self.x_vals.shape[0] / self.batch_size)

然后在fit函数中使用它:

model.fit(SparseSequence(x_vals, y_vals))

请记住,数据首先需要转换为scipy csr稀疏矩阵,否则代码将无法工作。还要注意不要在Model.fit()中使用“y”关键字。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接