使用带有Keras和Tensorflow的稀疏矩阵

使用带有Keras和Tensorflow的稀疏矩阵,tensorflow,sparse-matrix,keras,Tensorflow,Sparse Matrix,Keras,我的数据可以看作是10B条目的矩阵(100M x 100),非常稀疏(

我的数据可以看作是10B条目的矩阵(100M x 100),非常稀疏(<1/100*1/100条目的非零)。我想将数据输入到我使用Tensorflow后端制作的Keras神经网络模型中

我的第一个想法是将数据扩展为稠密的,也就是说,将所有10B条目写入一系列CSV,大多数条目为零。然而,这很快就压倒了我的资源(即使是做ETL,也会让博士后感到挣扎)。所以我需要使用真正的稀疏矩阵

我怎样才能用Keras(和Tensorflow)做到这一点?虽然numpy不支持稀疏矩阵,但scipy和tensorflow都支持。关于这个想法有很多讨论(例如),要么使用scipy的稀疏矩阵,要么直接使用Tensorflow的稀疏矩阵。但我找不到一个明确的结论,我也没能让任何事情起作用(甚至不清楚该走哪条路!)

我该怎么做

我认为有两种可能的方法:

  • 将其保持为一个scipy稀疏矩阵,然后,在给Keras一个小批量时,使其致密
  • 始终保持稀疏,并使用Tensorflow稀疏张量
  • 我还认为#2是首选,因为你会一直获得更好的性能(我相信),但#1可能更容易,也足够了。我都会很高兴的


    这两种方法如何实现?

    对不起,我没有评论的名声,但我认为你应该看看这里的答案:。我已经试过了,而且效果很好,不过只有一个注意事项,至少在我的例子中,洗牌导致了非常糟糕的结果,所以我使用了这个稍微修改过的非洗牌替代方案:

    def nn_batch_generator(X_data, y_data, batch_size):
        samples_per_epoch = X_data.shape[0]
        number_of_batches = samples_per_epoch/batch_size
        counter=0
        index = np.arange(np.shape(y_data)[0])
        while 1:
            index_batch = index[batch_size*counter:batch_size*(counter+1)]
            X_batch = X_data[index_batch,:].todense()
            y_batch = y_data[index_batch]
            counter += 1
            yield np.array(X_batch),y_batch
            if (counter > number_of_batches):
                counter=0
    

    它产生了与keras的混洗实现(在
    fit
    中设置
    shuffle=True
    )相当的精度。

    这个答案解决了问题中提到的第二种方法。 如果编写自定义训练循环,则可以使用稀疏矩阵作为带有Tensorflow后端的Keras模型的输入。在下面的示例中,模型将稀疏矩阵作为输入,并输出密集矩阵

    从keras.layers导入,输入
    从keras.models导入模型
    进口西皮
    将numpy作为np导入
    trainX=scipy.sparse.random(10241024)
    trainY=np.random.rand(10241024)
    输入=输入(形状=(trainX.shape[1],),稀疏=真)
    输出=密集(训练形状[1],激活='softmax')(输入)
    模型=模型(输入=输入,输出=输出)
    compile(loss='classifical_crossentropy',optimizer='adam',metrics=['accurity'])
    步骤=10
    对于范围内的i(步):
    #为了简单起见,我们在本例中直接使用trainX和trainY
    #通常,这是准备批次的地方
    打印(批量生产的列车型号(列车X、列车Y))
    # [3549.2546, 0.0]
    # ...
    # [3545.6448, 0.0009765625]
    
    然而,这种方法的有用性取决于您的模型是否需要加密稀疏矩阵。
    事实上,上面的模型有一层将稀疏矩阵转换为稠密矩阵。如果稀疏矩阵不适合内存,这可能是一个问题。

    尝试使用不支持的类型()转换值()。类型错误:“SparseTensor”对象不可下标