首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用tensorflow 2进行矩阵分解的简单方法

用tensorflow 2进行矩阵分解的简单方法
EN

Stack Overflow用户
提问于 2020-10-30 09:18:14
回答 1查看 1K关注 0票数 0

我一直在研究如何对这个非常简单和基本的情况进行矩阵分解,但是没有找到任何东西。我只找到了复杂而漫长的解决方案,所以我将介绍我想要解决的问题:

代码语言:javascript
运行
复制
U x V = A

我只想知道如何在Tensorflow 2中求解这个方程,A是一个已知的稀疏矩阵,UV是两个随机初始化矩阵。所以我想找出U和V,使它们的乘法近似等于A。

例如,拥有以下变量:

代码语言:javascript
运行
复制
# I use this function to build a toy dataset for the sparse matrix
def build_rating_sparse_tensor(ratings):

  indices = ratings[['U_num', 'V_num']].values 

  values = ratings['rating'].values

  return tf.SparseTensor(
                indices=indices,
                values=values,
                dense_shape=[ratings.U_num.max()+1, ratings.V_num.max()+1])

# here I create what will be the matrix A
ratings = (pd.DataFrame({'U_num': list(range(0,10_000))*30,
                        'V_num': list(range(0,60_000))*5,
                        'rating': np.random.randint(6, size=300_000)})
                       .sample(1000)
                       .drop_duplicates(subset=['U_num','V_num'])
                       .sort_values(['U_num','V_num'], ascending=[1,1]))


# Variables

A = build_rating_sparse_tensor(ratings)

U = tf.Variable(tf.random_normal(
        [A_Sparse.shape[0], embeddings], stddev=init_stddev))

# this matrix would be transposed in the equation
V = tf.Variable(tf.random_normal(
        [A_Sparse.shape[1], embeddings], stddev=init_stddev))


# loss function
def sparse_mean_square_error(sparse_ratings, user_embeddings, movie_embeddings):

  predictions = tf.reduce_sum(
                    tf.gather(user_embeddings, sparse_ratings.indices[:, 0]) *
                    tf.gather(movie_embeddings, sparse_ratings.indices[:, 1]),
                    axis=1)
  loss = tf.losses.mean_squared_error(sparse_ratings.values, predictions)
  return loss

是否有可能通过一个特定的损失函数、优化器和学习时间表来完成这个任务?

非常感谢。

EN

回答 1

Stack Overflow用户

发布于 2020-10-30 17:37:19

使用TensorFlow 2的简单明了的方法:

注意,评级已转换为float32。TensorFlow无法计算整数上的梯度,请参阅https://github.com/tensorflow/tensorflow/issues/20524

代码语言:javascript
运行
复制
A = build_rating_sparse_tensor(ratings)
indices = ratings[["U_num", "V_num"]].values
embeddings = 3000

U = tf.Variable(tf.random.normal([A.shape[0], embeddings]), dtype=tf.float32)
V = tf.Variable(tf.random.normal([embeddings, A.shape[1]]), dtype=tf.float32)

optimizer = tf.optimizers.Adam()

trainable_weights = [U, V]

for step in range(100):
    with tf.GradientTape() as tape:
        A_prime = tf.matmul(U, V)
        # indexing the result based on the indices of A that contain a value
        A_prime_sparse = tf.gather(
            tf.reshape(A_prime, [-1]),
            indices[:, 0] * tf.shape(A_prime)[1] + indices[:, 1],
        )
        loss = tf.reduce_sum(tf.metrics.mean_squared_error(A_prime_sparse, A.values))
    grads = tape.gradient(loss, trainable_weights)
    optimizer.apply_gradients(zip(grads, trainable_weights))
    if step % 20 == 0:
        print(f"Training loss at step {step}: {loss:.4f}")

我们利用A的稀疏性,仅在A的实际值上计算损失,但是对于可训练权值UV,我们仍然需要分配两个非常大的稠密张量。对于大的数字,如您的例子,您可能会遇到一些OOM错误。

也许值得为您的数据探索另一种表示形式。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64605596

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档