帮助新手学习 TensorFlow 中的线性代数(3 阶张量)
Helping out a Newbie with Linear Algebra in TensorFlow (Rank 3 Tensors)
我怀疑已经有人问过这个问题,尽管在我的搜索中,许多其他问题都有特定的独特问题,这些问题似乎不适用于我的情况(或者可能是我无法解决的问题)。
我在 tensorflow 中有一个标准的前馈神经网络,它在大小为 [None, n_features]
、权重为 [n_features, n_neurons]
的 rank2 输入张量下表现正确,从而导致隐藏层为 tf.matmul(inputs, weight) = [None, n_neurons]
.
但是,我想在输入和输出中都将我的维度扩展一维。例如,我想要
inputs = tf.placeholder("float", shape=[None, n_type, n_features])
weight= tf.Variable(FNN_weight_initializer([n_type, n_features, n_neurons]))
Hidden1 = tf.matmul(inputs, weight)
我的最终目标是Hidden1 = [None, n_type, n_neurons]
。
然而,我没有生成所需的张量形状,而是得到了一个形状为 [n_type, n_type, n_neurons]
的张量。我不是线性代数方面的专家,我尝试了几种维序组合,但都没有成功。甚至可以将 rank3 张量与 tf.matmul
相乘吗?我应该在此处某处进行重塑或转置操作吗?
根据 OP 的评论进行编辑
您可以将输入特征向量展平为 [-1, n_type * n_features]
形状,应用精心选择的矩阵乘法并将输出从 [-1, n_type * n_neurons]
重塑为 [-1, n_type, n_neurons]
操作张量将是块对角线 [n_type * n_features, n_type * n_neurons]
张量,每个块都是 weights
.
中的 n_type
个张量之一
为了构建块对角矩阵,我使用了另一个答案(来自 )
这看起来像
inputs = tf.placeholder("float", shape=[None, n_type, n_features])
inputs = tf.reshape(inputs, shape=[-1, n_type * n_features])
weights = tf.Variable(FNN_weight_initializer([n_type, n_features, n_neurons]))
split_weights = tf.split(weights, num_or_size_splits=n_type, axis=1)
# each element of split_weights is a tensor of shape : [1, n_features, n_neurons] -> need to squeeze
split_weights = tf.map_fn(lambda elt : tf.squeeze(elt, axis=0), split_weights)
block_matrix = block_diagonal(split_weights) # from the abovementioned reference
Hidden1 = tf.matmul(inputs, block_matrix)
# shape : [None, n_type * n_neurons]
Hidden1 = tf.reshape(Hidden1, [-1, n_type, n_neurons])
# shape : [None, n_type, n_neurons]
原回答
根据 tf.matmul
(reference) 的文档,您要相乘的张量需要具有相同的秩。
当秩为>2
时,只有最后两个维度需要矩阵乘法兼容,前两个维度需要完全匹配。
所以,对于问题"Is it even possible to multiply rank3 tensors with tf.matmul?",答案是"Yes, it is possible, but conceptually, it is still rank 2 multiplication"。
因此,需要进行一些整形:
inputs = tf.placeholder("float", shape=[None, n_type, n_features])
inputs = tf.reshape(inputs, shape=[-1, n_type, 1, n_features])
weights = tf.Variable(FNN_weight_initializer([n_type, n_features, n_neurons]))
weights = tf.expand_dims(weights, 0)
# shape : [1, n_type, n_features, n_neurons]
weights = tf.tile(weights, [tf.shape(inputs)[0], 1, 1, 1])
# shape : [None, n_type, n_features, n_neurons]
Hidden1 = tf.matmul(inputs, weights)
# shape : [None, n_type, 1, n_neurons]
Hidden1 = tf.reshape(Hidden1, [-1, n_type, n_neurons])
# shape : [None, n_type, n_neurons]
我怀疑已经有人问过这个问题,尽管在我的搜索中,许多其他问题都有特定的独特问题,这些问题似乎不适用于我的情况(或者可能是我无法解决的问题)。
我在 tensorflow 中有一个标准的前馈神经网络,它在大小为 [None, n_features]
、权重为 [n_features, n_neurons]
的 rank2 输入张量下表现正确,从而导致隐藏层为 tf.matmul(inputs, weight) = [None, n_neurons]
.
但是,我想在输入和输出中都将我的维度扩展一维。例如,我想要
inputs = tf.placeholder("float", shape=[None, n_type, n_features])
weight= tf.Variable(FNN_weight_initializer([n_type, n_features, n_neurons]))
Hidden1 = tf.matmul(inputs, weight)
我的最终目标是Hidden1 = [None, n_type, n_neurons]
。
然而,我没有生成所需的张量形状,而是得到了一个形状为 [n_type, n_type, n_neurons]
的张量。我不是线性代数方面的专家,我尝试了几种维序组合,但都没有成功。甚至可以将 rank3 张量与 tf.matmul
相乘吗?我应该在此处某处进行重塑或转置操作吗?
根据 OP 的评论进行编辑
您可以将输入特征向量展平为 [-1, n_type * n_features]
形状,应用精心选择的矩阵乘法并将输出从 [-1, n_type * n_neurons]
重塑为 [-1, n_type, n_neurons]
操作张量将是块对角线 [n_type * n_features, n_type * n_neurons]
张量,每个块都是 weights
.
n_type
个张量之一
为了构建块对角矩阵,我使用了另一个答案(来自
这看起来像
inputs = tf.placeholder("float", shape=[None, n_type, n_features])
inputs = tf.reshape(inputs, shape=[-1, n_type * n_features])
weights = tf.Variable(FNN_weight_initializer([n_type, n_features, n_neurons]))
split_weights = tf.split(weights, num_or_size_splits=n_type, axis=1)
# each element of split_weights is a tensor of shape : [1, n_features, n_neurons] -> need to squeeze
split_weights = tf.map_fn(lambda elt : tf.squeeze(elt, axis=0), split_weights)
block_matrix = block_diagonal(split_weights) # from the abovementioned reference
Hidden1 = tf.matmul(inputs, block_matrix)
# shape : [None, n_type * n_neurons]
Hidden1 = tf.reshape(Hidden1, [-1, n_type, n_neurons])
# shape : [None, n_type, n_neurons]
原回答
根据 tf.matmul
(reference) 的文档,您要相乘的张量需要具有相同的秩。
当秩为>2
时,只有最后两个维度需要矩阵乘法兼容,前两个维度需要完全匹配。
所以,对于问题"Is it even possible to multiply rank3 tensors with tf.matmul?",答案是"Yes, it is possible, but conceptually, it is still rank 2 multiplication"。
因此,需要进行一些整形:
inputs = tf.placeholder("float", shape=[None, n_type, n_features])
inputs = tf.reshape(inputs, shape=[-1, n_type, 1, n_features])
weights = tf.Variable(FNN_weight_initializer([n_type, n_features, n_neurons]))
weights = tf.expand_dims(weights, 0)
# shape : [1, n_type, n_features, n_neurons]
weights = tf.tile(weights, [tf.shape(inputs)[0], 1, 1, 1])
# shape : [None, n_type, n_features, n_neurons]
Hidden1 = tf.matmul(inputs, weights)
# shape : [None, n_type, 1, n_neurons]
Hidden1 = tf.reshape(Hidden1, [-1, n_type, n_neurons])
# shape : [None, n_type, n_neurons]