在python中使用autograd时如何解决“无法区分w.r.t.类型<class'numpy.int64'=“”>”错误

时间:2019-01-04 18:15:37

标签: python logistic-regression glm autograd

在python中使用autograd函数时,出现错误“无法区分w.r.t.类型”。

基本上,我正在尝试为广义线性模型(GLM)编写代码,并且我想使用autograd来获得一个函数,该函数描述相对于w(权重)的损失函数的导数,然后将其插入scipy.optimize.minimize()。

在执行scipy步骤之前,我一直在尝试通过输入变量的值(在我的情况下是数组)并为渐变输出值(再次作为数组)来测试函数是否正常工作。这是我的代码:

def generate_data(n,k,m):
    w = np.zeros((k,1)) # make first column of weights all zeros
    w[:,[0]] = np.random.randint(-10, high=10,size=(k,m)) # choose length random inputs between -10 and 10
    x = np.random.randint(-10, high=10,size=(n,m)) # choose length random inputs between -10 and 10

return x,w

def logpyx(x,w):
    p = np.exp(np.dot(x,w.T)) # get exponentials e^wTx
    norm = np.sum(p,axis=1) # get normalization constant (sum of exponentials)
    pnorm = np.divide(p.T,norm).T # normalize the exponentials 

    ind = [] # initialize empty list
    for n in np.arange(0,len(x)):
        ind.append(np.random.choice(len(w),p = pnorm[n,:])) # choose index where y = 1 based on probabilities

    ind = np.array(ind) # recast list as array

    ys = [] # initialize empty list
    for n in np.arange(0,len(x)):
        y = [0] * (len(w)-1) # initialize list of zeros
        y.insert(ind[n],1) # assign value "1" to appropriate index in row
        ys.append(y) # add row to matrix of ys

    y = np.array(ys) # recast list as array

    pyx = np.diagonal(np.dot(pnorm,y.T)) # p(y|x)

    log_pyx = np.log(pyx)

    return log_pyx

# input data
n = 100 # number of data points
C = 2 # number of classes (e.g. turn right, turn left, move forward)
m = 1 # number of features in x (e.g. m = 2 for # of left trials and # of right trials)

log_pyx = logpyx(x,w) # calculate log likelihoods

grad_logpyx = grad(logpyx) # take gradient of log_pyx to find updated weights

x,w = generate_data(n,C,m)

print(grad_logpyx(x,w))

因此,当我执行此操作时,一切运行良好,直到最后一行,我收到前面提到的错误。

我显然不明白如何很好地使用autograd,并且由于错误似乎与数据类型不匹配有关,因此我必须以错误的格式放置内容。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

问题在于,logpyx()的至少一个输入是标量(在generate_data()中为x或w)。这是一些复制您的错误的代码:

from autograd import grad, numpy as anp

f = lambda x: 100 * (x[1] - x[0]**2) ** 2 + (1 - x[0])**2
x0 = anp.array([-2, 2])

grad_f = grad(f)
x1 = grad_f(x0)

TypeError: Can't differentiate w.r.t. type <class 'numpy.int64'>

将输入更改为x0 = anp.array([-2. 2.])即可。