TypeError: an integer is required when using Cython

TypeError: an integer is required when using Cython

我正在使用 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 是一个整数。所以我不知道为什么首先会弹出这个错误。

问题出在你这部分代码:

        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