首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是什么使我的安花了更少的时间跑?

是什么使我的安花了更少的时间跑?
EN

Stack Overflow用户
提问于 2014-11-04 07:17:27
回答 1查看 55关注 0票数 0

我目前正在开发一个开源神经网络 (为了好玩和学习经验),我最近对我的代码做了一个相对较小的修改,但出于某种原因,它使ANN的运行速度提高了16倍。(至少根据我的测试)

安/安·皮:(老安)

代码语言:javascript
复制
from random import uniform


class Neuron(object):
    def __init__(self, parents=[]):
        self.parents = [{
            'neuron': parent,
            'weight': uniform(-1, 1),
            'slope': uniform(-1, 1),
        } for parent in parents]

    def calculate(self, increment=0):
        self.output = sum([parent['neuron'].output * (parent['weight'] + increment * parent['slope']) for parent in self.parents]) > 0

    def mutate(self, increment):
        for parent in self.parents:
            parent['weight'] += increment * parent['slope']
            parent['slope'] = uniform(-1, 1)

    def get_genome(self):
        return [parent['weight'] for parent in self.parents]

    def set_genome(self, value):
        for i, parent in enumerate(self.parents):
            parent['weight'] = value[i]

    genome = property(get_genome, set_genome)


class NeuralNetwork(object):
    def __init__(self, inputs, outputs, hidden, rows):
        self.bias = Neuron()
        self.neurons = []
        for row in xrange(rows):
            if row == 0:
                self.neurons.append([Neuron(parents=[]) for input_ in xrange(inputs)])
            elif row == rows - 1:
                self.neurons.append([Neuron(parents=self.neurons[row - 1] + [self.bias]) for output in xrange(outputs)])
            else:
                self.neurons.append([Neuron(parents=self.neurons[row - 1] + [self.bias]) for column in xrange(hidden)])
        self.bias.output = True

    def calculate(self, inputs, increment=0):
        for i, neuron_row in enumerate(self.neurons):
            for j, neuron in enumerate(neuron_row):
                if i == 0:
                    neuron.output = inputs[j]
                else:
                    neuron.calculate(increment=increment)
        return [neuron.output for neuron in self.neurons[-1]]

    def mutate(self, increment):
        for neuron_row in self.neurons:
            for neuron in neuron_row:
                neuron.mutate(increment=increment)

    def get_genome(self):
        genome = []
        for neuron_row in self.neurons[1:]:
            genome.append([neuron.genome for neuron in neuron_row])
        return genome

    def set_genome(self, value):
        for i, neuron_row in enumerate(self.neurons[1:]):
            for j, neuron in enumerate(neuron_row):
                neuron.genome = value[i][j]

    genome = property(get_genome, set_genome)

安/安:(新安)

代码语言:javascript
复制
from random import uniform


class Neuron(object):
    def __init__(self, parents=[]):
        self.parents = [{
            'neuron': parent,
            'weight': uniform(-1, 1),
            'slope': uniform(-1, 1),
        } for parent in parents]

    def calculate(self, increment=0):
        self.output = sum([parent['neuron'].output * (parent['weight'] + increment * parent['slope']) for parent in self.parents]) > 0

    def mutate(self, increment):
        for parent in self.parents:
            parent['weight'] += increment * parent['slope']
            parent['slope'] = uniform(-1, 1)

    def get_genome(self):
        return [parent['weight'] for parent in self.parents]

    def set_genome(self, value):
        for i, parent in enumerate(self.parents):
            parent['weight'] = value[i]

    genome = property(get_genome, set_genome)


class NeuralNetwork(object):
    def __init__(self, inputs, outputs, hidden, rows):
        self.bias = Neuron()
        self.neurons = [[Neuron(parents=[]) for input_ in xrange(inputs)]]
        for row in xrange(rows - 2):
            self.neurons.append([Neuron(parents=self.neurons[-1] + [self.bias]) for output in xrange(outputs)])
        self.neurons.append([Neuron(parents=self.neurons[-1] + [self.bias]) for output in xrange(outputs)])
        self.bias.output = True

    def calculate(self, inputs, increment=0):
        for i, neuron_row in enumerate(self.neurons):
            for j, neuron in enumerate(neuron_row):
                if i == 0:
                    neuron.output = inputs[j]
                else:
                    neuron.calculate(increment=increment)
        return [neuron.output for neuron in self.neurons[-1]]

    def mutate(self, increment):
        for neuron_row in self.neurons:
            for neuron in neuron_row:
                neuron.mutate(increment=increment)

    def get_genome(self):
        genome = []
        for neuron_row in self.neurons[1:]:
            genome.append([neuron.genome for neuron in neuron_row])
        return genome

    def set_genome(self, value):
        for i, neuron_row in enumerate(self.neurons[1:]):
            for j, neuron in enumerate(neuron_row):
                neuron.genome = value[i][j]

    genome = property(get_genome, set_genome)

从ANN/ANN5.py到ANN/ANN.py的区别:

代码语言:javascript
复制
-    self.neurons = []
-    for row in xrange(rows):
-        if row == 0:
-            self.neurons.append([Neuron(parents=[]) for input_ in xrange(inputs)])
-        elif row == rows - 1:
-            self.neurons.append([Neuron(parents=self.neurons[row - 1] + [self.bias]) for output in xrange(outputs)])
-        else:
-            self.neurons.append([Neuron(parents=self.neurons[row - 1] + [self.bias]) for column in xrange(hidden)])
+    self.neurons = [[Neuron(parents=[]) for input_ in xrange(inputs)]]
+    for row in xrange(rows - 2):
+        self.neurons.append([Neuron(parents=self.neurons[-1] + [self.bias]) for output in xrange(outputs)])
+    self.neurons.append([Neuron(parents=self.neurons[-1] + [self.bias]) for output in xrange(outputs)])

(全部在神经网络的__init__中)

tests.py:

代码语言:javascript
复制
from random import randint
from time import time

from ANN.ANN import NeuralNetwork
# from ANN.ANN2 import NeuralNetwork as NeuralNetwork2
# from ANN.ANN3 import NeuralNetwork as NeuralNetwork3
# from ANN.ANN4 import NeuralNetwork as NeuralNetwork4
from ANN.ANN5 import NeuralNetwork as NeuralNetwork5


def test(NeuralNetwork=NeuralNetwork):
    time_ = time()
    ANNs = []
    for i in xrange(10):
        ANNs.append(NeuralNetwork(inputs=49, outputs=3, hidden=49, rows=5))
    for i, ANN in enumerate(ANNs[:1]):
        for j in xrange(11):
            for k in xrange(len(ANNs) / 2):
                for l in xrange(20):
                    ANN.calculate([randint(0, 1) for _ in xrange(49)], increment=j/10)
                    ANNs[k + len(ANNs)/2 * (i < len(ANNs)/2)].calculate([randint(0, 1) for _ in xrange(49)])
                    # print 'ANN {0} mutation {1:02d} opponent {2} turn {3:02d}'.format(i + 1, j + 1, k + 1, l + 1)
            ANN.mutate(increment=randint(1, 100))
    return time() - time_


if __name__ == '__main__':
    print 'time: {0}'.format(test())
    # print 'time 2: {0}'.format(test(NeuralNetwork2))
    # print 'time 3: {0}'.format(test(NeuralNetwork3))
    # print 'time 4: {0}'.format(test(NeuralNetwork4))
    print 'time 5: {0}'.format(test(NeuralNetwork5))

我注释掉了ANN2、ANN3和ANN4,因为它们甚至是我存储的ANN的较旧版本(仅在本地,它们都不在Github上),以便比较性能。目前,我只担心ANN5.py和ANN.py之间的性能变化。

我做for i, ANN in enumerate(ANNs[:1]):而不是for i, ANN in enumerate(ANNs):的原因是因为对后者的测试花费的时间太长,而且我认为结果仍然是完全足够的,而不需要重复10个ANN的测试过程(我偶尔会对所有的10个进行测试以确保)。

当我上次运行tests.py时,我得到的是:

代码语言:javascript
复制
time: 0.454416036606
time 5: 8.02504611015

它总是给出一些接近这一点的东西。

我做了各种测试,比较ANN.py和ANN5.py的功能,到目前为止,它们在相同的情况下做了完全相同的事情。我用基因组属性制作了两个相同的ANN,一个在ANN.py中使用ANN.py类,另一个在ANN5.py中使用NeuralNetwork类,它们总是给出相同的结果,只要输入相同。

所以我的问题是,发生了什么事?我意识到我的问题不是很精确,但老实说,我完全不知道为什么会有如此巨大的性能差异。我希望的是,旧的ANN (ANN5.py)只是在后台做了一些非常低效的事情,因为我初始化了ANN,而新的ANN (ANN.py)正在正确地初始化它,但是我担心新的ANN完全丢失了一些东西,在我手动测试这两种神经网络时,由于某种原因没有出现/造成了任何不同。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-01-21 23:35:55

我有点忘了这个问题,我认为以前发生过一些不好的事情,但最近我注意到,正在产生的基因组相当短。这时,我注意到我正在遍历长度为3的xrange(输出),而不是长度为49的xrange(隐藏的)。

在我改变后:

代码语言:javascript
复制
for row in xrange(rows - 2):
    self.neurons.append([Neuron(parents=self.neurons[-1] + [self.bias]) for output in xrange(outputs)])

至:

代码语言:javascript
复制
for row in xrange(rows - 2):
    self.neurons.append([Neuron(parents=self.neurons[-1] + [self.bias]) for output in xrange(hidden)])

它回到了类似于旧代码的速度,但至少它产生了一个正确大小的神经网络。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26729615

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档