TensorFlow:如何以‘笛卡尔积’方式实现两个张量相减?
当然可以实现!不过你的循环写法在TensorFlow里走不通,得用向量化的方式来做
首先得明确:TensorFlow是基于计算图的符号化框架,你不能像遍历普通Python列表那样去遍历一个形状带None的placeholder——因为在构建计算图的时候,这个None对应的实际长度还没确定,根本没法逐个取出元素。
不过别担心,TensorFlow的广播机制正好能帮你实现想要的效果,而且效率比循环高得多。你的需求本质上是把一维的p(形状[None])和一维的v(形状[N])做“逐元素配对减法”,得到一个二维张量(每行是p的一个元素减去v的所有元素)。
直接用下面的代码就能实现:
import tensorflow as tf # 假设N是你定义的具体数值,比如5 N = 5 v = tf.get_variable('v', [N], dtype=tf.float32) p = tf.placeholder(shape=[None], dtype=tf.float32) # 记得指定dtype,要和v一致 # 把p从形状[None]扩展成[None, 1] p_expanded = tf.expand_dims(p, axis=1) # 利用广播自动完成配对减法,结果形状就是[None, N] ret = p_expanded - v # 验证形状 print(ret.get_shape().as_list()) # 输出 [None, 5](对应你设置的N)
为什么这个方法可行?
TensorFlow的广播规则会自动把形状为[None, 1]的p_expanded和形状为[N]的v扩展成相同的二维形状[None, N]:
p_expanded的每一行(单个元素)会被复制N次,变成[1, N]的行v会被复制None次(也就是批量的大小),变成[None, N]的矩阵
然后逐元素做减法,正好得到你想要的结果。
如果你用的是TensorFlow 2.x,写法几乎一样,只是tf.get_variable可以换成更直观的tf.Variable,placeholder可以用普通的tf.Tensor或者函数参数替代,核心的广播逻辑完全不变:
import tensorflow as tf N = 5 v = tf.Variable(tf.random.normal([N])) # 用Tensor替代placeholder,TF2里更常用这种方式 p = tf.constant([1.0, 2.0, 3.0]) # 示例批量数据,实际可以是任意长度的一维张量 p_expanded = tf.expand_dims(p, axis=1) ret = p_expanded - v print(ret.shape) # 输出 (3, 5),对应批量大小3和N=5
内容的提问来源于stack exchange,提问作者calciferzh
相关产品推荐
相关产品推荐

