Deep learning 修改Theano.tensor.nnet.softmax中的执行函数

Deep learning 修改Theano.tensor.nnet.softmax中的执行函数,deep-learning,theano,lasagne,Deep Learning,Theano,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

我刚刚开始使用千层面和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()


在当前代码中,当我在lasagne中使用predict方法时,会出现“unorderable types:int()>str()”错误。

对于类似的情况,您最好通过符号表达式构建自定义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):返回theano.tensor.nnet.softmax(x)我必须使用这个函数,它只返回一个类。我应该在这个函数中实现符号表达式吗?如果是,它应该返回什么。
theano.tensor.nnet.softmax
返回一个对象,一个符号变量。
custom\u softmax
也是如此
custom_softmax
可直接替代千层面的
softmax
功能。
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