Python JAX中计算词向量移动平均值的最佳方法
假设我有一个矩阵Python JAX中计算词向量移动平均值的最佳方法,python,jax,Python,Jax,假设我有一个矩阵W,形状(n_单词,model_dim),其中n_单词是句子中的单词数,model_dim是表示单词向量的空间维度。计算这些向量移动平均值的最快方法是什么 例如,如果窗口大小为2(窗口长度=5),我可能会遇到类似的情况(这会引发错误TypeError:JAX'Tracer'对象不支持项分配): 从jax导入随机 将jax.numpy作为jnp导入 #伪词向量(维度为32的17个词向量) W=random.normal(random.PRNGKey(0),shape=(17,32)
W
,形状(n_单词,model_dim)
,其中n_单词
是句子中的单词数,model_dim
是表示单词向量的空间维度。计算这些向量移动平均值的最快方法是什么
例如,如果窗口大小为2(窗口长度=5),我可能会遇到类似的情况(这会引发错误TypeError:JAX'Tracer'对象不支持项分配
):
从jax导入随机
将jax.numpy作为jnp导入
#伪词向量(维度为32的17个词向量)
W=random.normal(random.PRNGKey(0),shape=(17,32))
ws=2#窗口大小
N=W.shape[0]#字数
新的W=jnp.zero(W.shape)
对于范围(N)中的i:
窗口=W[最大值(0,i-ws):最小值(N,i+ws+1)]
n=窗口形状[0]
对于范围(n)内的j:
新的W[i]+=W[j]/n
我想jnp.convolve有一个更快的解决方案,但我不太熟悉。这看起来像是在尝试卷积,所以
jnp.convolve
或类似的方法可能会更有效
也就是说,您的示例有点奇怪,因为n
从来都不大于4,所以您只能访问W
的前四个元素。此外,您在内部循环的每次迭代中都会覆盖上一个值,因此new\u W
的每一行只包含W
的前四行之一的缩放副本
将您的代码更改为我认为您的意思,并使用它使其与JAX的不可变数组兼容,这样做:
从jax导入随机
将jax.numpy作为jnp导入
#伪词向量(维度为32的17个词向量)
W=random.normal(random.PRNGKey(0),shape=(17,32))
ws=2#窗口大小
N=W.shape[0]#字数
新的W=jnp.zero(W.shape)
对于范围(N)中的i:
窗口=W[最大值(0,i-ws):最小值(N,i+ws)]
n=窗口形状[0]
对于范围(n)内的j:
new_W=new_W.at[i].添加(窗口[j]/n)
这里是一个更有效的卷积的等价物:
来自jax.scipy.signal导入卷积
kernel=jnp.ones((4,1))
new_W_2=convalve(W,kernel,mode='same')/convalve(jnp.ones_like(W),kernel,mode='same'))
jnp.allclose(新的,新的)
#真的
Thx对于更正,我确实应该编写new_W[I]+=W[j]/n
和window=W[max(0,I-ws):min(n,I+ws+1)]
!你能详细说明2个卷积器是怎么做的吗?我想我得到的形状(4,1)的那些(也可以是(4,模型尺寸)没有?),但我不知道分母!卷积(jnp.ones_-like(W),kernel,mode='same')似乎以与我的代码中的n
相同的方式进行适当的缩放。此外,在我上次编辑之后,代码中的内核应该是:kernel=jnp.ones((5,1))
,这样它就集中在中间的单词上