Tensorflow中的“Optimal`变量初始化和学习速率用于矩阵分解

时间:2017-03-28 13:18:38

标签: python numpy matrix tensorflow matrix-factorization

我在Tensorflow中尝试了一个非常简单的优化 - 矩阵分解的问题。给定矩阵V (m X n),将其分解为W (m X r)H (r X n)。我借用基于张度下降的基于张量流的实现来进行here的矩阵分解。

矩阵V的详细信息。在原始形式中,条目的直方图如下: enter image description here

要以[0,1]的比例输入条目,我执行以下预处理。

f(x) = f(x)-min(V)/(max(V)-min(V))

标准化后,数据的直方图如下所示: enter image description here

我的问题是:

  1. 鉴于数据的性质:介于0和1之间,大多数条目接近0而不是1,WH的最佳初始化是什么?
  2. 如何根据不同的成本函数定义学习率:  |A-WH|_F|(A-WH)/A|
  3. 最小的工作示例如下:

    import tensorflow as tf
    import numpy as np
    import pandas as pd
    
    V_df = pd.DataFrame([[3, 4, 5, 2],
                   [4, 4, 3, 3],
                   [5, 5, 4, 4]], dtype=np.float32).T
    

    因此,V_df看起来像:

        0   1   2
    0   3.0 4.0 5.0
    1   4.0 4.0 5.0
    2   5.0 3.0 4.0
    3   2.0 3.0 4.0
    

    现在,代码定义了W,H

    V = tf.constant(V_df.values)
    shape = V_df.shape
    rank = 2 #latent factors
    
    initializer = tf.random_normal_initializer(mean=V_df.mean().mean()/5,stddev=0.1 )
    #initializer = tf.random_uniform_initializer(maxval=V_df.max().max())
    
    H =  tf.get_variable("H", [rank, shape[1]],
                                     initializer=initializer)
    W =  tf.get_variable(name="W", shape=[shape[0], rank],
                                     initializer=initializer)
    WH = tf.matmul(W, H)
    

    定义成本和优化器:

    f_norm = tf.reduce_sum(tf.pow(V - WH, 2))
    lr = 0.01
    optimize = tf.train.AdagradOptimizer(lr).minimize(f_norm)
    

    运行会话:

    max_iter=10000
    display_step = 50
    
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
    
        for i in xrange(max_iter):
    
            loss, _ = sess.run([f_norm, optimize])
            if i%display_step==0:
                print loss, i
        W_out = sess.run(W)
        H_out = sess.run(H)
        WH_out = sess.run(WH)
    

    我意识到当我使用像initializer = tf.random_uniform_initializer(maxval=V_df.max().max())这样的东西时,我得到了矩阵W和H,使得它们的产品比V大得多。我也意识到保持学习率(lr)。 0001可能太慢了。

    我想知道是否有任何经验法则来定义矩阵分解问题的良好初始化和学习率。

1 个答案:

答案 0 :(得分:2)

我认为学习率的选择是试验和错误的经验问题,除非您设计第二个算法来找到最佳值。这也是一个实际问题,取决于计算完成所需的时间 - 给定您可用的计算资源。

但是,在设置初始化和学习速率时应该小心,因为某些值永远不会收敛,这取决于机器学习问题。一个经验法则是以3步而不是10步手动改变幅度(根据Andrew Ng):不是从0.1移动到1.0,而是从0.1到0.3。

对于具有接近0的多个值的特定数据,可以在给定特定"假设" /模型的情况下找到最佳初始化值。但是,您需要定义"最佳"。该方法应该尽可能快,尽可能准确,还是这些极端之间的某个中点? (在寻求精确解决方案时,准确性并不总是一个问题。但是,如果是这样,停止规则的选择和减少错误的标准会影响结果。)

即使您确实为这组数据找到了最佳参数,也可能在使用其他数据集的相同公式时遇到问题。如果您希望对不同的问题使用相同的参数,那么您将失去普遍性,除非您有充分的理由期望其他数据集遵循类似的分布。

对于手头的特定算法,它使用随机渐变,似乎没有简单的答案*。 TensorFlow文档引用了两个来源:

*"有希望清楚的是,在更新中选择一个好的矩阵B ......可以大大改善标准的梯度方法......但是,这种选择通常并不明显,并且在随机设置......如何选择这个矩阵是非常不明显的。此外,在许多随机设置中,我们甚至不知道我们正在最小化的真正功能,因为数据只是到达流中,因此预先计算好的距离生成矩阵是不可能的。" Duchi & Singer, 2013, p. 5