【问题标题】:Modifying perform function in Theano.tensor.nnet.softmax修改 Theano.tensor.nnet.softmax 中的执行功能
【发布时间】:2015-11-24 23:27:43
【问题描述】:

我刚刚开始使用 lasagne 和 Theano 在 Python 上进行一些机器学习。

我正在尝试修改 Theano 中的 softmax 类。我想更改激活函数(softmax)的计算方式。我不想将 e_x 除以 e_x.sum(axis=1),而是将 e_x 除以三个连续数字的总和。

例如,结果如下:

sm[0] = e_x[0]/(e_x[0]+e_x[1]+e_x[2])
sm[1] = e_x[1]/(e_x[0]+e_x[1]+e_x[2])
sm[2] = e_x[2]/(e_x[0]+e_x[1]+e_x[2])
sm[3] = e_x[3]/(e_x[3]+e_x[4]+e_x[5])
sm[4] = e_x[4]/(e_x[3]+e_x[4]+e_x[5])
sm[5] = e_x[5]/(e_x[3]+e_x[4]+e_x[5])

等等……

问题是我不能完全理解 theano 是如何进行计算的。

这是我的主要问题。只需更改 softmax 类中的 perform() 函数就足够了吗?

这是原来的 perform() 函数:

def perform(self, node, input_storage, output_storage):
    x, = input_storage
    e_x = numpy.exp(x - x.max(axis=1)[:, None])
    sm = e_x / e_x.sum(axis=1)[:, None]
    output_storage[0][0] = sm

这是我修改后的 perform()

def myPerform(self, node, input_storage, output_storage):
    x, = input_storage
    e_x = numpy.exp(x - x.max(axis=1)[:, None])
    sm = numpy.zeros_like(e_x)
    for i in range(0,symbolCount):
        total = e_x[3*i] + e_x[3*i+1] + e_x[3*i+2]
        sm[3*i] = e_x[3*i]/total
        sm[3*i+1] = e_x[3*i+1]/total
        sm[3*i+2] = e_x[3*i+2]/total
    output_storage[0][0] = sm

使用当前代码,当我在千层面中使用 predict 方法时出现“不可排序的类型:int()>str()”错误。

【问题讨论】:

    标签: deep-learning theano lasagne


    【解决方案1】:

    对于这样的事情,您最好通过符号表达式构造自定义 softmax,而不是创建(或修改)操作。

    您的自定义 softmax 可以用符号表达式来定义。这样做会“免费”为您提供渐变(以及其他 Theano 操作的点点滴滴),但运行速度可能比自定义操作稍慢。

    这是一个例子:

    import numpy
    import theano
    import theano.tensor as tt
    
    x = tt.matrix()
    
    # Use the built in softmax operation
    y1 = tt.nnet.softmax(x)
    
    # A regular softmax operation defined via ordinary Theano symbolic expressions
    y2 = tt.exp(x)
    y2 = y2 / y2.sum(axis=1)[:, None]
    
    # Custom softmax operation
    def custom_softmax(a):
        b = tt.exp(a)
        b1 = b[:, :3] / b[:, :3].sum(axis=1)[:, None]
        b2 = b[:, 3:] / b[:, 3:].sum(axis=1)[:, None]
        return tt.concatenate([b1, b2], axis=1)
    y3 = custom_softmax(x)
    
    f = theano.function([x], outputs=[y1, y2, y3])
    
    x_value = [[.1, .2, .3, .4, .5, .6], [.1, .3, .5, .2, .4, .6]]
    y1_value, y2_value, y3_value = f(x_value)
    assert numpy.allclose(y1_value, y2_value)
    assert y3_value.shape == y1_value.shape
    a = numpy.exp(.1) + numpy.exp(.2) + numpy.exp(.3)
    b = numpy.exp(.4) + numpy.exp(.5) + numpy.exp(.6)
    c = numpy.exp(.1) + numpy.exp(.3) + numpy.exp(.5)
    d = numpy.exp(.2) + numpy.exp(.4) + numpy.exp(.6)
    assert numpy.allclose(y3_value, [
        [numpy.exp(.1) / a, numpy.exp(.2) / a, numpy.exp(.3) / a, numpy.exp(.4) / b, numpy.exp(.5) / b, numpy.exp(.6) / b],
        [numpy.exp(.1) / c, numpy.exp(.3) / c, numpy.exp(.5) / c, numpy.exp(.2) / d, numpy.exp(.4) / d, numpy.exp(.6) / d]
    ]), y3_value
    

    【讨论】:

    • 问题是我想修改softmax类,因为该类在整个计算过程中被多次使用。我想知道是否可以使用符号表达式创建一个 newSoftmax 类。我找不到任何关于它的文档。
    • 只需创建一个包含自定义 softmax 代码的 Python 函数。然后,您可以根据需要多次调用该函数。一个简单的 Theano 操作是任何 Python 可调用的并且接受和返回符号变量的操作。
    • 是否可以创建一个类而不是一个函数?我不熟悉千层面的工作原理。 lasagne/nonlinearities.py def softmax(x): return theano.tensor.nnet.softmax(x) 我必须使用这个只返回一个类的函数。我应该只在这个函数中实现符号表达式吗?如果是,它应该返回什么。
    • theano.tensor.nnet.softmax 返回一个对象,一个符号变量。 custom_softmax 也是如此。 custom_softmax 可以直接替代千层面的softmax 函数。
    猜你喜欢
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 2020-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    相关资源
    最近更新 更多