Numpy 在Theano中模拟布尔掩码

Numpy 在Theano中模拟布尔掩码,numpy,theano,Numpy,Theano,我正在向theano移植一个numpy表达式。该表达式为每个类找到真正预测的数量,给定基本真值类的一个热矩阵Y,以及预测类的一个热矩阵Y\u hat。numpy代码是: import numpy as np y = np.array([1, 0, 1, 2, 2]) y_hat = np.array([2, 0, 1, 1, 0]) Y = np.zeros(shape=(len(y), len(np.unique(y)))) Y_hat = np.zeros_like(Y) rows =

我正在向theano移植一个numpy表达式。该表达式为每个类找到真正预测的数量,给定基本真值类的一个热矩阵
Y
,以及预测类的一个热矩阵
Y\u hat
。numpy代码是:

import numpy as np

y = np.array([1, 0, 1, 2, 2])
y_hat = np.array([2, 0, 1, 1, 0])

Y = np.zeros(shape=(len(y), len(np.unique(y))))
Y_hat = np.zeros_like(Y)

rows = np.arange(len(y))

Y[rows, y] = 1
Y_hat[rows, y_hat] = 1

((Y_hat == Y) & (Y == 1)).sum(axis=0)
最后一个表达式生成
数组([1,1,0])
。我试过使用theano的非零:

from theano import shared
Yt = shared(Y)
Yt_hat = shared(Y_hat)
Yt_hat[Yt.nonzero()].eval()

eval生成
数组([0,1,1,0,0.])
,这是预测正确的
Yt\u hat
行的0-1掩码。有什么建议可以让这项工作顺利进行吗?有不同的方法吗?谢谢。

这里有三个变体,演示如何在Theano中重新实现部分numpy代码

请注意,Theano的
Unique
操作不支持在GPU上运行,也不支持渐变。因此,第3版的许多版本没有多大用处。第2版提供了一种解决方法:在Theano之外计算唯一值并将其传入。版本1只是numpy代码最后一行的Theano实现

为了解决您的特定问题:无需使用
非零
;在本例中,索引在Theano中工作就像在numpy中工作一样。也许你把
y
y
搞混了?(常见的Python风格是所有变量和参数名都使用小写)


非常感谢。我应该首先报告导致我提出这个问题的错误——这是我提出问题的首要规则之一。我知道我第一次尝试简单地使用
((Y_hat==Y)和(Y==1)).sum(axis=0)
,错误与布尔值没有
sum
方法有关。在任何情况下,您的解决方案都是有效的。再次感谢。
import numpy as np
import theano
import theano.tensor as tt
import theano.tensor.extra_ops


def numpy_ver(y, y_hat):
    Y = np.zeros(shape=(len(y), len(np.unique(y))), dtype=np.int64)
    Y_hat = np.zeros_like(Y, dtype=np.int64)
    rows = np.arange(len(y), dtype=np.int64)
    Y[rows, y] = 1
    Y_hat[rows, y_hat] = 1
    return ((Y_hat == Y) & (Y == 1)).sum(axis=0), Y, Y_hat


def compile_theano_ver1():
    Y = tt.matrix(dtype='int64')
    Y_hat = tt.matrix(dtype='int64')
    z = (tt.eq(Y_hat, Y) & tt.eq(Y, 1)).sum(axis=0)
    return theano.function([Y, Y_hat], outputs=z)


def compile_theano_ver2():
    y = tt.vector(dtype='int64')
    y_hat = tt.vector(dtype='int64')
    y_uniq = tt.vector(dtype='int64')
    Y = tt.zeros(shape=(y.shape[0], y_uniq.shape[0]), dtype='int64')
    Y_hat = tt.zeros_like(Y, dtype='int64')
    rows = tt.arange(y.shape[0], dtype='int64')
    Y = tt.set_subtensor(Y[rows, y], 1)
    Y_hat = tt.set_subtensor(Y_hat[rows, y_hat], 1)
    z = (tt.eq(Y_hat, Y) & tt.eq(Y, 1)).sum(axis=0)
    return theano.function([y, y_hat, y_uniq], outputs=z)


def compile_theano_ver3():
    y = tt.vector(dtype='int64')
    y_hat = tt.vector(dtype='int64')
    y_uniq = tt.extra_ops.Unique()(y)
    Y = tt.zeros(shape=(y.shape[0], y_uniq.shape[0]), dtype='int64')
    Y_hat = tt.zeros_like(Y, dtype='int64')
    rows = tt.arange(y.shape[0], dtype='int64')
    Y = tt.set_subtensor(Y[rows, y], 1)
    Y_hat = tt.set_subtensor(Y_hat[rows, y_hat], 1)
    z = (tt.eq(Y_hat, Y) & tt.eq(Y, 1)).sum(axis=0)
    return theano.function([y, y_hat], outputs=z)


def main():
    y = np.array([1, 0, 1, 2, 2], dtype=np.int64)
    y_hat = np.array([2, 0, 1, 1, 0], dtype=np.int64)
    y_uniq = np.unique(y)
    result, Y, Y_hat = numpy_ver(y, y_hat)
    print result
    theano_ver1 = compile_theano_ver1()
    print theano_ver1(Y, Y_hat)
    theano_ver2 = compile_theano_ver2()
    print theano_ver2(y, y_hat, y_uniq)
    theano_ver3 = compile_theano_ver3()
    print theano_ver3(y, y_hat)


main()