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

Nip*_*tra 9 python numpy matrix matrix-factorization tensorflow

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

关于矩阵的详细信息V.在其原始形式中,条目的直方图如下: 在此输入图像描述

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

f(x) = f(x)-min(V)/(max(V)-min(V))
Run Code Online (Sandbox Code Playgroud)

规范化后,数据的直方图如下所示: 在此输入图像描述

我的问题是:

  1. 鉴于数据的性质:0和1,大多数条目越接近0比1之间,这将是为最佳的初始化WH
  2. 如何根据不同的成本函数来定义学习率: |A-WH|_F|(A-WH)/A|

最小的工作示例如下:

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

因此,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
Run Code Online (Sandbox Code Playgroud)

现在,代码定义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)
Run Code Online (Sandbox Code Playgroud)

定义成本和优化器:

f_norm = tf.reduce_sum(tf.pow(V - WH, 2))
lr = 0.01
optimize = tf.train.AdagradOptimizer(lr).minimize(f_norm)
Run Code Online (Sandbox Code Playgroud)

运行会话:

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

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

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

nou*_*nal 2

我认为学习率的选择是一个反复试验的经验问题,除非您使用第二种算法来找到最佳值。这也是一个实际问题,具体取决于您有多少时间来完成计算 - 考虑到您拥有的可用计算资源。

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

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

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

对于当前使用随机梯度下降的特定算法,似乎没有简单的答案*。TensorFlow 文档引用了两个来源:

*“希望很清楚,在更新中选择一个好的矩阵 B...可以显着改进标准梯度方法...但是,通常这样的选择并不明显,并且在随机设置中...它是高度非-显然如何选择这个矩阵。此外,在许多随机设置中,我们甚至不知道我们正在最小化的真实函数,因为数据只是以流的形式到达,所以预先计算一个好的距离生成矩阵是不可能的。杜奇和辛格,2013 年,第 14 页。5