zoukankan      html  css  js  c++  java
  • Keras:

    https://keras.io/zh/layers/core/


    keras使用稀疏输入进行训练

    2018.06.14 12:55:46字数 902阅读 760

    稀疏矩阵

    稀疏矩阵是指矩阵中数值为0的元素数目远远多于非0元素的数目,在实际中遇到的大矩阵基本都是稀疏的。如果使用普通的ndarray存储稀疏矩阵,会有很大的内存浪费。在python中我们可以使用scipy中的sparse模块存储这些矩阵,但是在用keras搭建神经网络使用这些矩阵作为神经网络的输入时,则需要做一些处理才能使用sparse格式的数据。


    方法一、使用keras函数式API中的参数实现

    keras的Sequential顺序模型是不支持稀疏输入的,如果非要用Sequential模型,可以参考方法二。在使用函数式API模型时,Input层初始化时有一个sparse参数,用来指明要创建的占位符是否是稀疏的,如图:

     
    Input的参数,可以用sparse来指明是否是稀疏的输入数据

    在使用时也很直接,一个参数就可以搞定:

    ipt_layer = Input((shape, ), sparse=True)
    

    网络的定义过程和常规方法没有什么区别,后边compile、fit等操作也都没有变化。不过目前这么用有一个问题,就是指定的batch_size不生效,不管设置多大的batch_size,训练的时候都是按照batch_size为1来进行,可能是人家觉得都用稀疏数据了,数据肯定大到可怕,用大一些batch会引入内存问题吧。如果要使用指定的batch_size来训练稀疏数据,或者需要调整batch_size,可以参考方法二。

    方法二、使用生成器方法实现

    还有一种方法可以实现,是使用生成器的方法,最早看到这个方法是在stackoverflow上,参考链接

    这种方法是利用生成器配合keras模型的fit_generator来实现,核心代码如下:

    # batch_generator
    def batch_generator(x, y, batch_size):
        number_of_batches = x.shape[0]//batch_size
        counter = 0
        shuffle_index = np.arange(x.shape[0])
        np.random.shuffle(shuffle_index)
        x = x[shuffle_index, :]
        y = y[shuffle_index, :]
        while 1:
            index_batch = shuffle_index[batch_size*counter: batch_size*(counter+1)]
            x_batch = x[index_batch, :].todense()
            y_batch = y[index_batch, :].todense()
            counter += 1
            yield(np.array(x_batch), np.array(y_batch))
            if counter >= number_of_batches:
                np.random.shuffle(shuffle_index)
                counter = 0
    
    # fit时要先根据batch_size和样本总量计算一下总共的steps_per_epoch
    train_steps = x.shape[0]//batch_size
    # 在fit时使用fit_generator
    model.fit_generator(generator=batch_generator(x, y, batch_size), steps_per_epoch=train_steps......)
    

    除了生成器函数,这里需要注意的是在fit之前先要计算每个epoch需要训练多少个step。

    在用这个方法进行训练的时候,对于validation数据,有几种场景区分:

    • 如果比较大,也可以使用这个生成器,直接将fit_generator的validation_data这个参数设置为生成器并且使用对应的验证数据即可;
    • 如果数据不大,可以选择把所有的validation数据都todense转为常规的ndarray;
    • 另外如果在训练中使用tensorboard,并且histogram_freq参数设置不为0,那么验证数据就不能使用生成器来生成了,必须转为ndarray才可以。

    方法总结

    时间就是金钱,在多数场景下,推荐使用方法一,节省生命。但如果对于需要调整batch_size或者铁了头要用Sequential模型的,方法二是比较好的选择,鉴于方法二对于tensorboard不是很友好,所以建议在使用方法二的时候不要在验证集上也使用生成器。

    对于稀疏的输入,上边的方法应该可以解决大部分问题了,不过有一些输出也是稀疏的情况,虽然训练过程跟着batch_size走,不会有什么影响,但在需要大规模predict的时候,比如要对几千万上亿条数据进行预测,目前还没有很好的办法能够直接输出稀疏格式存储的数据。


  • 相关阅读:
    JavaEE 第四周
    JavaEE 第三周
    JavaEE 第二周
    JavaEE 第一周
    js字符串方法
    javaee项目库存管理系统总结
    javaee期末团队项目库存管理系统概要信息
    JAVAEE第十一周
    JSON
    Facelets
  • 原文地址:https://www.cnblogs.com/cx2016/p/11752060.html
Copyright © 2011-2022 走看看