我正在 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))
我的问题是:
- 鉴于数据的性质:介于 0 和 1 之间以及大多数条目接近 0 而不是 1,对于
W
和的最佳初始化是H
什么? - 应该如何根据不同的成本函数定义学习率:
|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
因此,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 可能太慢了。
我想知道是否有任何经验法则可以为矩阵分解问题定义良好的初始化和学习率。