神经网络作为激活数据库

为了使神经网络上的AI通用,您需要了解神经网络不足以实现多功能性。为此,请尝试在神经网络上实现所有程序的完整执行。这将需要条件转换,条件,读写数据结构。之后,将有可能创建面向对象的神经网络。文章将必须分为几部分。



考虑不同类型的神经簇。感觉和效应簇已经被提及。
如果And,则仅在所有条件都有效的情况下才激活它-即,信号已到达所有突触。
-如果至少一项功能已激活则触发。如果此群集是链的一部分,则必须进行反向链接-它通过And条件连接。换句话说,仅当链中的上一个集群处于活动状态并且其自身的任何条件也有效时,集群才被激活。与编程语言类似,链式通信在中央处理器中充当指令指针-信号“我允许执行集群的其余条件”。让我们看一些代码。

NC类; //神经簇
类链接{
	公开:
		NC&_from;
		NC&_to;
		...
};
Class LinksO; / *传出链接的容器。基于boost :: intrusive方便做
 -节省内存并提高性能* /
class LinksI; //也基于boost :: intrusive
结构NeuronA1 {
	qreal _activation = 0;
	static const qreal _threashold = 1;//          ,   .
	bool activated()const {
		return _activation >= _threshold;
	}
};
struct NeuronAT {
	qreal _activation = 0;
	qreal _threashold = 1;//  
	bool activated()const {
		return _activation >= _threshold;
	}
};
class NC {
	public:
		LinksO _next;
		LinksO _down;
		
		LinksI _prev;
		LinksI _up;
		
		NeuronA1 _nrnSumPrev;
		NeuronAT _nrnSumFromBottom;
		...
}
//  ,     _nrnSumPrev:
void NC::sendActivationToNext() {
	for(Link& link: _next) {
		link._to._nrnSumPrev._activation += 1;
	}
}
//      - and/or/not  :
bool NC::allowedToActivateByPrevChain()const {
	if(_prev.isEmpty())//    ,    ,    .
		return true;//    ,     .
	return _nrnSumPrev.activated();
	//         ,         .
	//      0    .
	// -     ,   -     ,    .
}

请注意,在_prev中通常没有链接或只有一个链接。这使前缀树脱离了内存链:在_next中,可以有任意数量的链接,而在_prev中,可以有不超过一个。仅在普通的前缀树中,每个位置只有一个字母,而在神经网络中则存在任意数量的字符。因此,即使存储Zalizniak的字典也不会占用太多内存。

现在,为了方便起见,我们将继续进行,以便以后不必重写此类代码,我们将立即消除神经元和激活。
如果集群以某种方式保留了激活历史记录,并且没有将其激活发送给其他集群,我们可以这样重写该函数:

bool NC :: allowedToActivateByPrevChain()const {
	对于(链接和链接:_prev){
		NC&nc = link._from;
		if(!nc.wasActivated())//检查最后一个周期
			返回false;
	}
	返回true;
}


然后,许多问题将立即消失:
1)经过几个预测周期后,无需恢复神经网络的状态-集群既存储又存储有关相应周期的激活信息。可以更频繁地包括更长的时间进行预测。
2)神经网络可以抵抗变化:如果将与集群的连接延迟地添加到集群中,则无需再次发送信号来总结目标集群上的激活-您可以立即检查条件。该代码变得更加功能化-副作用最少。
3)可以引入任意信号延迟:如果激活缓存可以存储不同周期的数据,则可以检查N个周期之前的集群是否处于活动状态。
为此,向连接添加一个可变参数-延迟时间:
类链接{
	...
	int _delay = 1;
};

然后像下面这样修改函数:
bool NC :: allowedToActivateByPrevChain()const {
	对于(链接和链接:_prev){
		NC&nc = link._from;
		if(!nc.wasActivated(link._delay))//检查N个循环
			返回false;
	}
	返回true;
}


4)我们摆脱了口吃的“院子里的草,草上的柴草……”:来自新周期的信号不会覆盖旧周期,反之亦然。
5)没有激活会在需要时消失的危险(它本身会不时地消失)。您可以很早地检查条件。
6)最后,您无法撰写关于“通过有节奏的活动管理进行神经网络管理”,“脑电图控制信号的可视化方法”,“用于控制脑电图的特殊DSL”主题的十几篇文章,而仅此而已:



现在,关于实现这种激活缓存:
1)ENS为我们提供了三个放置激活缓存的选项:当前神经团簇中其神经元的激活,激活(以识别波的形式?)在海马中(此处存储的时间长于簇本身的存储时间)以及长期记忆。事实证明,就像现代处理器一样,三级缓存也是如此。
2)在软件模型中,乍一看激活缓存位于每个集群中。
3)更具体地说,我们已经知道:该模型中的海马建立了一条记忆链,并且到该时刻处于活动状态且未被抑制的所有群集的链接都被输入到记忆链中。每个连接作为传出存储在一个群集中,而作为传入存储在另一个群集中。这表明“高速缓存”实际上不是高速缓存,而是长期存储器。只有生物神经网络无法通过激活直接从长期记忆中提取信息,而人工神经网络则可以。这是AI相对ENS的优势,这是不可使用的,这很愚蠢-如果我们需要语义信息,为什么还要打扰激活呢?

因此,要检查集群是否向后退了N个活动状态,可以使用以下(未优化的)伪代码:

NC * Brain :: _ hippo; //当前事件已添加到的当前簇
NC* NC::prevNC(int stepsBack)const {
	//       _prev
	//   link._delay,       .
	// , () 
}
bool NC::wasActivated(int stepsAgo)const {
	NC* timeStamp = _brain._hippo->prevNC(stepsAgo);
	if(!timeStamp)//       
		return false;
	return linkExists(timeStamp, this);
//      ,   boost    intrusive ,
//  ,    node    2  3 
}

如果不是必须取消激活,而不仅要保留连接的存在,而且还必须保持激活力,那么可以将相应的字段添加到连接本身。其他领域也可以用于此目的,而无需引入其他领域:例如,通信寿命所依赖的“重要性”。
但是,对于那些激活没有达到阈值但仍然有用的集群,例如对于模糊识别或概率的错误计算等,该怎么办?未优化的解决方案是使用所有相同的连接。为此,请在群集中创建其他链接容器,然后在其中添加它们(以免与正常工作的容器混合在一起),或者甚至干扰堆中的所有内容,并仅通过强制分离它们。由于此类连接比其他连接大一个数量级,因此需要更快地将其删除。一种更优化的解决方案:每个群集存储一个普通的激活缓存-例如,由16个元素组成的循环缓冲区(环形),其中每个元素都存储一个循环编号和该循环的激活力。有两级缓存:对于弱信号,亚阈值和最新缓存-集群中的缓冲区,否则,请进行长期记忆通信。不要忘记,在这些文章中仅显示了伪代码和朴素算法,并且优化问题会占用更多空间。

Source: https://habr.com/ru/post/zh-CN388797/


All Articles