ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python-在theano中扫描张量的不同维度

2019-10-27 21:59:00  阅读:229  来源: 互联网

标签:loops iteration theano python


我正在与theano一起迈出第一步,但我想不出如何解决这个实际上很容易的问题.

我有一个3 * 4 * 2张量,如下所示:

[1 1] | [2 2] | [3 3]
[1 1] | [2 2] | [3 3]
[0 0] | [2 2] | [3 3]
[9 9] | [0 0] | [3 3]

所以我有N = 3个序列,每个序列的长度为L = 4,其元素为维d = 2的向量.实际上,序列的长度可以不同,但​​是我可以考虑用[0 0]向量填充它们,如上所示.

我想做的是,首先扫描张量的第一个轴,并将列表中的所有向量求和,直到第一个[0 0]向量为止-这就是为什么我在[]末尾添加[9 9]第一个张量切片,以便检查总和退出条件[1].我应该以[[2 2],[6 6],[12 12]]结尾.我尝试了很多方法来解决这个问题,在我看来这只是一个嵌套循环问题…但是总是会出现一些奇怪的错误[2].

谢谢,
朱利奥


[1]:实际问题是为NLP目的训练递归神经网络,其中N为批处理的维度,L为批处理中句子的最大长度,d为每个单词表示的维度.我忽略了这个问题,以便可以专注于最简单的编码方面.
[2]我忽略了失败的历史,也许以后可以添加.

解决方法:

如果序列始终填充为零,则可以沿目标轴求和,因为填充区域不会改变总和.但是,如果填充区域可能包含非零值,则有两种方法.

>使用扫描.这很慢,应尽可能避免.实际上可以避免,因为,
>创建一个二进制蒙版,并增加填充区域.

下面的代码说明了这三种方法.对于允许非零填充区域(v2和v3)的两种方法,计算需要额外的输入:一个向量,给出批中序列的长度.

import numpy
import theano
import theano.tensor as tt


def v1():
    # NOTE: [9, 9] element changed to [0, 0] 
    # since zero padding must be used for
    # this method
    x_data = [[[1, 1], [1, 1], [0, 0], [0, 0]],
              [[2, 2], [2, 2], [2, 2], [0, 0]],
              [[3, 3], [3, 3], [3, 3], [3, 3]]]
    x = tt.tensor3()
    x.tag.test_value = x_data
    y = x.sum(axis=1)
    f = theano.function([x], outputs=y)
    print f(x_data)


def v2_step(i_t, s_tm1, x, l):
    in_sequence = tt.lt(i_t, l).dimshuffle(0, 'x')
    s_t = s_tm1 + tt.switch(in_sequence, x[i_t], 0)
    return s_t


def v2():
    x_data = [[[1, 1], [1, 1], [0, 0], [9, 9]],
              [[2, 2], [2, 2], [2, 2], [0, 0]],
              [[3, 3], [3, 3], [3, 3], [3, 3]]]
    l_data = [2, 3, 4]
    x = tt.tensor3()
    x.tag.test_value = x_data
    l = tt.lvector()
    l.tag.test_value = l_data
    # Must dimshuffle first because scan can only iterate over first (0'th) axis.
    x_hat = x.dimshuffle(1, 0, 2)
    y, _ = theano.scan(v2_step, sequences=[tt.arange(x_hat.shape[0])],
                       outputs_info=[tt.zeros_like(x_hat[0])],
                       non_sequences=[x_hat, l], strict=True)
    f = theano.function([x, l], outputs=y[-1])
    print f(x_data, l_data)


def v3():
    x_data = [[[1, 1], [1, 1], [0, 0], [9, 9]],
              [[2, 2], [2, 2], [2, 2], [0, 0]],
              [[3, 3], [3, 3], [3, 3], [3, 3]]]
    l_data = [2, 3, 4]
    x = tt.tensor3()
    x.tag.test_value = x_data
    l = tt.lvector()
    l.tag.test_value = l_data
    indexes = tt.arange(x.shape[1]).dimshuffle('x', 0)
    mask = tt.lt(indexes, l.dimshuffle(0, 'x')).dimshuffle(0, 1, 'x')
    y = (mask * x).sum(axis=1)
    f = theano.function([x, l], outputs=y)
    print f(x_data, l_data)


def main():
    theano.config.compute_test_value = 'raise'
    v1()
    v2()
    v3()


main()

通常,如果您的步进功能取决于上一步的输出,则需要使用扫描.

如果原则上每个步骤/迭代都可以同时执行(即它们根本不依赖彼此),那么通常有一种更有效的方法可以不使用扫描

标签:loops,iteration,theano,python
来源: https://codeday.me/bug/20191027/1947654.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有