我正在尝试用这些标准来创建一种新的神经网络:
以下是我在Julia和Python中的实现尝试:
Python
import random
import itertools
import time
import signal
from threading import Thread
from multiprocessing import Pool
import multiprocessing
POTENTIAL_RANGE = 110000 # Resting potential: -70 mV Membrane potential range: +40 mV to -70 mV --- Difference: 110 mV = 110000 microVolt --- https://en.wikipedia.org/wiki/Membrane_potential
ACTION_POTENTIAL = 15000 # Resting potential: -70 mV Action potential: -55 mV --- Difference: 15mV = 15000 microVolt --- https://faculty.washington.edu/chudler/ap.html
AVERAGE_SYNAPSES_PER_NEURON = 8200 # The average number of synapses per neuron: 8,200 --- http://www.ncbi.nlm.nih.gov/pubmed/2778101
# https://en.wikipedia.org/wiki/Neuron
class Neuron():
neurons = []
def __init__(self):
self.connections = {}
self.potential = 0.0
self.error = 0.0
#self.create_connections()
#self.create_axon_terminals()
Neuron.neurons.append(self)
self.thread = Thread(target = self.activate)
#self.thread.start()
#self.process = multiprocessing.Process(target=self.activate)
def fully_connect(self):
for neuron in Neuron.neurons[len(self.connections):]:
if id(neuron) != id(self):
self.connections[id(neuron)] = round(random.uniform(0.1, 1.0), 2)
def partially_connect(self):
if len(self.connections) == 0:
neuron_count = len(Neuron.neurons)
for neuron in Neuron.neurons[len(self.connections):]:
if id(neuron) != id(self):
if random.randint(1,neuron_count/100) == 1:
self.connections[id(neuron)] = round(random.uniform(0.1, 1.0), 2)
print "Neuron ID: " + str(id(self))
print " Potential: " + str(self.potential)
print " Error: " + str(self.error)
print " Connections: " + str(len(self.connections))
def activate(self):
while True:
'''
for dendritic_spine in self.connections:
if dendritic_spine.axon_terminal is not None:
dendritic_spine.potential = dendritic_spine.axon_terminal.potential
print dendritic_spine.potential
self.neuron_potential += dendritic_spine.potential * dendritic_spine.excitement
terminal_potential = self.neuron_potential / len(self.axon_terminals)
for axon_terminal in self.axon_terminals:
axon_terminal.potential = terminal_potential
'''
#if len(self.connections) == 0:
# self.partially_connect()
#else:
self.partially_connect()
pass
'''
if abs(len(Neuron.neurons) - len(self.connections) + 1) > 0:
self.create_connections()
if abs(len(Neuron.neurons) - len(self.axon_terminals) + 1) > 0:
self.create_axon_terminals()
'''
class Supercluster():
def __init__(self,size):
for i in range(size):
Neuron()
print str(size) + " neurons created."
self.n = 0
self.build_connections()
#pool = Pool(4, self.init_worker)
#pool.apply_async(self.build_connections(), arguments)
#map(lambda x: x.partially_connect(),Neuron.neurons)
#map(lambda x: x.create_connections(),Neuron.neurons)
#map(lambda x: x.create_axon_terminals(),Neuron.neurons)
def build_connections(self):
for neuron in Neuron.neurons:
self.n += 1
#neuron.thread.start()
neuron.partially_connect()
print "Counter: " + str(self.n)
Supercluster(10000)
朱莉娅
^{pr2}$首先,这些部分在每个神经元之间部分且随机地连接,花费了太多时间。如何加快此过程/部件?
Python
def build_connections(self):
for neuron in Neuron.neurons:
self.n += 1
#neuron.thread.start()
neuron.partially_connect()
print "Counter: " + str(self.n)
朱莉娅
n = 0
@parallel for neuron in neurons
n += 1
partially_connect(neuron)
println("Counter: ",n)
其次,当我的目标是创造至少一百万个神经元时,给每个神经元一条自己的线是不是个好主意?这意味着它会像百万条线。在
我在这里要做的是严格意义上模仿生物神经网络,而不是使用矩阵计算。在
添加:
根据答案,partially_connect
函数的新版本:
def partially_connect(self):
if len(self.connections) == 0:
neuron_count = len(Neuron.neurons)
#for neuron in Neuron.neurons:
elected = random.sample(Neuron.neurons,100)
for neuron in elected:
if id(neuron) != id(self):
#if random.randint(1,neuron_count/100) == 1:
self.connections[id(neuron)] = round(random.uniform(0.1, 1.0), 2)
print "Neuron ID: " + str(id(self))
print " Potential: " + str(self.potential)
print " Error: " + str(self.error)
print " Connections: " + str(len(self.connections))
性能显著提高。在
在Julia中,如果性能很重要:不要使用全局变量(请参见您的
neurons
数组)也不要使用非类型数组(同样,请参见您的neurons
数组)。参见performance tips。你还应该分析一下你的瓶颈在哪里。我强烈建议您不要使用@parallel
,直到您可以快速使用它。在我亲自去看看,除此之外,我还发现了一些令人惊讶的瓶颈:
rand(1:neuron_count/100)
创建浮点范围,而不是整数范围。这是一个巨大的瓶颈,分析很快就发现了这一点。使用rand(1:neuron_count÷100)
。在object_id
,只需使用!(neuron === self)
。或者更好的方法是将neurons
作为数组和要修改的项的整数索引传递。在修复这些项目后,我设法将程序的执行时间从140秒降低到4秒(去掉了
@parallel
,这不太可能有用,并注释掉了文本显示)。几乎所有的运行时都只是用来生成随机数;您可以通过一次生成一个大的池来加速这个过程,而不是一个一个地生成它们。在它使用ProgressMeter包(必须安装)来显示进度。在
看看这个代码:
根据你对我评论的回复,这里有几点:
当您使用
L[0:]
之类的语法时,您正在制作列表的副本。slice语法为每次调用函数生成Neuron.neurons
数组的浅拷贝。这是一个O(n)操作,由于您对build_connections
函数中的每个神经元调用一次partially_connect
,所以它就变成了O(n²)。(哎呀!)您正在使用Python进行可以而且应该在库中完成的工作(我们希望是用C语言!)。看看}函数。你可以很容易地计算出
random.paretovariate()
和{num_connections = random.paretovariate(1.0) * 100
,然后说connected_nodes = random.sample(neurons, num_connections)
。从connected_nodes
中筛选出self
,就完成了。我认为通过消除n²行为和使用内置库例程,可以大大提高性能。在
添加
对于您的添加,请考虑以下内容:
^{pr2}$(我暂时忽略指纹。)
我不知道如果不迭代所有的神经元寻找
id()
值的匹配,如何从一个神经元到它连接的神经元进行通信。我建议将权重作为引用存储在一起:当然,这假设您需要遍历从源到目标的链接。在
至于线程解决方案,我没有一个好的建议。一点谷歌搜索会让我找到一些旧的邮件线索(呵呵!)其中提到405和254之类的数字是线程创建限制。我没有看到任何文档说“Python线程现在是无限的!”或者别的什么,所以我怀疑你必须改变你实现解决方案的方式。在
相关问题 更多 >
编程相关推荐