Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python TensorFlow(或Numpy)中的高级广播_Python_Numpy_Tensorflow_Array Broadcasting - Fatal编程技术网

Python TensorFlow(或Numpy)中的高级广播

Python TensorFlow(或Numpy)中的高级广播,python,numpy,tensorflow,array-broadcasting,Python,Numpy,Tensorflow,Array Broadcasting,在TensorFlow中,我有一个形状为[D,D]的秩2张量M(矩阵)和形状为[D,D,D]的秩3张量T 我需要将它们组合起来,形成一个新的矩阵R,如下所示:元素R[a,b+c-a]由所有元素的总和T[a,b,c]*M[b,c]给出,其中b+c-a是常数(其中b+c-a必须介于0和D-1) 创建R的一种低效方法是在索引上嵌套for循环,并检查b+c-a不超过D-1(例如在numpy中): R=np.zero([D,D]) 对于范围(D)内的a: 对于范围(D)中的b: 对于范围(D)中的c: 如

在TensorFlow中,我有一个形状为
[D,D]
的秩2张量
M
(矩阵)和形状为
[D,D,D]
的秩3张量
T

我需要将它们组合起来,形成一个新的矩阵
R
,如下所示:元素
R[a,b+c-a]
由所有元素的总和
T[a,b,c]*M[b,c]
给出,其中
b+c-a
是常数(其中
b+c-a
必须介于0和
D-1

创建
R
的一种低效方法是在索引上嵌套
for
循环,并检查
b+c-a
不超过
D-1
(例如在numpy中):

R=np.zero([D,D])
对于范围(D)内的a:
对于范围(D)中的b:
对于范围(D)中的c:

如果0,则可以按如下方式对该计算进行矢量化:

import numpy as np

np.random.seed(0)
D = 10
M = np.random.rand(D, D)
T = np.random.rand(D, D, D)
# Original calculation
R = np.zeros([D, D])
for a in range(D):
    for b in range(D):
        for c in range(D):
            if 0 <= b + c - a < D:
                R[a, b + c - a] += T[a, b, c] * M[b, c]
# Vectorized calculation
tm = T * M
a = np.arange(D)[:, np.newaxis, np.newaxis]
b, c = np.ogrid[:D, :D]
col_idx = b + c - a
m = (col_idx >= 0) & (col_idx < D)
row_idx = np.tile(a, [1, D, D])
R2 = np.zeros([D, D])
np.add.at(R2, (row_idx[m], col_idx[m]), tm[m])
# Check result
print(np.allclose(R, R2))
# True

在一些快速测试中,即使没有并行化,这也比NumPy快得多。

您可以按如下方式对该计算进行矢量化:

import numpy as np

np.random.seed(0)
D = 10
M = np.random.rand(D, D)
T = np.random.rand(D, D, D)
# Original calculation
R = np.zeros([D, D])
for a in range(D):
    for b in range(D):
        for c in range(D):
            if 0 <= b + c - a < D:
                R[a, b + c - a] += T[a, b, c] * M[b, c]
# Vectorized calculation
tm = T * M
a = np.arange(D)[:, np.newaxis, np.newaxis]
b, c = np.ogrid[:D, :D]
col_idx = b + c - a
m = (col_idx >= 0) & (col_idx < D)
row_idx = np.tile(a, [1, D, D])
R2 = np.zeros([D, D])
np.add.at(R2, (row_idx[m], col_idx[m]), tm[m])
# Check result
print(np.allclose(R, R2))
# True

在两个快速测试中,即使没有并行化,这也比NumPy快得多。

显示循环代码的
,无法从这个解释中理解您想要什么。但是
b+c-a
可能对
a
b
c
的多个组合采用相同的值,即使
a
是固定的(例如对于
(a=2,b=1,c=3)
(a=2,b=3,c=1)
,结果也是2)。
R[a,b+c-a]
应该取哪一个值?还是应该是一个组合(添加,产品)?@jedhesa我纠正了这一部分,感谢你指出了循环码的
,从这个解释中你不可能理解你想要什么。但是
b+c-a
可能对
a
b
c
的多个组合采用相同的值,即使
a
是固定的(例如对于
(a=2,b=1,c=3)
(a=2,b=3,c=1)
,结果也是2)。
R[a,b+c-a]
应该取哪一个值?还是应该是一个组合(添加,产品)?@jedhesa我更正了那个部分,谢谢你指出
import numpy as np
import numba as nb

@nb.njit
def calculation_nb(T, M, D):
    tm = T * M
    R = np.zeros((D, D), dtype=tm.dtype)
    for a in nb.prange(D):
      for b in range(D):
        for c in range(max(a - b, 0), min(D + a - b, D)):
          R[a, b + c - a] += tm[a, b, c]
    return R

print(np.allclose(R, calculation_nb(T, M, D)))
# True