【问题标题】:TypeError: an integer is required when using CythonTypeError:使用 Cython 时需要整数
【发布时间】:2020-11-22 12:49:29
【问题描述】:

我正在使用 Cython 来加速一些 python 代码,但我遇到了以下错误:

Traceback (most recent call last):
  File "d:\ReinforcementLearning\BaseLines\A\Cythonver\testing.py", line 1, in <module>
    import RL_Cython
  File "RL_Cython.pyx", line 524, in init RL_Cython
    agent.fit(iterations = 3, checkpoint = 1)
  File "RL_Cython.pyx", line 430, in RL_Cython.Agent.fit
    self.es.train(iterations, print_every = checkpoint)
  File "RL_Cython.pyx", line 105, in RL_Cython.Deep_Evolution_Strategy.train
    cpdef train(self, int epoch = 100, int print_every = 1):
  File "RL_Cython.pyx", line 120, in RL_Cython.Deep_Evolution_Strategy.train
    weights_population = self._get_weight_from_population(self.weights, population[k])
TypeError: an integer is required

代码如下所示:

cdef class Deep_Evolution_Strategy:
    cdef list weights
    cdef double sigma, learning_rate
    cdef int population_size
    cdef public reward_function
    inputs = None

    def __init__(self, weights, reward_function, population_size, sigma, learning_rate):
        self.weights = weights
        self.reward_function = reward_function
        self.population_size = population_size
        self.sigma = sigma
        self.learning_rate = learning_rate

    cpdef _get_weight_from_population(self, list weights, int population):
        cdef list weights_population = []
        for index, i in enumerate(population):
            jittered = self.sigma * i
            weights_population.append(weights[index] + jittered)
        print(type(weights_population))
        return weights_population

    cdef public list get_weights(self):
        return self.weights
    
    cpdef train(self, int epoch = 100, int print_every = 1):
        lasttime = time.time()
        cdef list population
        cdef int i
        cdef rewards
        cdef int k
        for i in range(epoch):
            population = []
            rewards = np.zeros(self.population_size)
            for k in range(self.population_size):
                x = []
                for w in self.weights:
                    x.append(np.random.randn(*w.shape))
                population.append(x)
            for k in range(self.population_size):
                weights_population = self._get_weight_from_population(self.weights, population[k])
                rewards[k] = self.reward_function(weights_population)
            rewards = (rewards - np.mean(rewards)) / (np.std(rewards) + 1e-7)
            for index, w in enumerate(self.weights):
                A = np.array([p[index] for p in population])
                self.weights[index] = (
                    w
                    + self.learning_rate
                    / (self.population_size * self.sigma)
                    * np.dot(A.T, rewards).T
                )
            if (i + 1) % print_every == 0:
                print('iter %d. reward: %f' % (i + 1, self.reward_function(self.weights)))

我已经完成了 print(type(k, self.weights, population))。 Self.weights 和 population 是应有的列表,并且 k 是整数。所以我不知道为什么首先会弹出这个错误。

【问题讨论】:

  • 我觉得可能population[k]不是整数吧?
  • @DavidW 它不应该是一个整数。它是一个数组,在我的非 cython 代码中它按预期工作

标签: python cython cythonize


【解决方案1】:

问题在于您的这部分代码:

        for k in range(self.population_size):
            weights_population = self._get_weight_from_population(self.weights, population[k])
            rewards[k] = self.reward_function(weights_population)

显然,population[k] 不是整数。

现在,看看你的这部分代码:

        for k in range(self.population_size):
            x = []
            for w in self.weights:
                x.append(np.random.randn(*w.shape))
            population.append(x)

您正在定义一个list,并在其上附加数字。然后,您将 list 附加到 population 列表中,稍后您将对其进行迭代以用于这些类:

    cpdef _get_weight_from_population(self, list weights, int population):
        cdef list weights_population = []
        for index, i in enumerate(population):
            jittered = self.sigma * i
            weights_population.append(weights[index] + jittered)
        print(type(weights_population))
        return weights_population

如您所见,您不能将list 作为population 参数传递,因为您告诉python 它应该是intint population

【讨论】:

    猜你喜欢
    • 2015-03-27
    • 2019-01-11
    • 2015-07-14
    • 2019-03-22
    • 2018-05-04
    • 2015-08-10
    • 2013-02-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多