Código de neuroelemento



¡Hola, querida comunidad de GeekTimes! No hace mucho tiempo, se publicó aquí una serie de artículos dedicados al trabajo sobre la creación de un modelo del sistema nervioso. Y la mejor manera de comprender la lógica del modelo es estudiar el código del programa para su implementación. No solo quiero transmitir mis ideas con más detalle, sino también pedir ayuda a la comunidad. Sé que entre los lectores de GT hay muchos profesionales en el campo de la escritura de código de software y su experiencia, el conocimiento puede ayudar al desarrollo del proyecto. A veces, los consejos o recomendaciones competentes son suficientes para que la solución de una tarea tan poco habitual se vuelva elegante y fácil.

Ciclo de contenido
1. . 1.
2. . 2.
3. . 3.
4. ,
5.
6.
7.

El entorno de desarrollo es Unity3D, un motor de juego muy popular. Este entorno resultó ser muy conveniente y accesible tanto en el trabajo con el editor como en presencia de una gran cantidad de referencias, explicaciones y comentarios en ruso. Por lo tanto, mis modestas habilidades de programación fueron suficientes para realizar mis ideas con Unity3D.

Los planes no cambian el entorno de desarrollo, ya que el motor del juego facilita la resolución de problemas de visualización, lo cual es muy importante en esta etapa.

Quiero disculparme con aquellos que quieren recurrir al código por su negligencia, posible descuido de la sintaxis del lenguaje y posibles errores. Cuando comencé este trabajo, no había demostración de código en los planes. Quería probar algunas de mis hipótesis.

El código refleja una búsqueda creativa. En el proceso de trabajo, me enfrenté a otro problema, el modelo no quería actuar como lo imaginaba. Y durante el día se me ocurrió la idea de cómo solucionar esto. En estos momentos, me puedo inspirar algún tipo de percepción. Al regresar del trabajo, hice correcciones con entusiasmo, ignorando todas las reglas del código, no había tiempo para esto. Y con qué frecuencia sucede esto, estas ideas no arrojaron resultados o no arrojaron el resultado deseado. Así que el trabajo en el proyecto continuó, y gracias por la paciencia de mi esposa, que me permitió realizar este trabajo. Es difícil encontrar tiempo entre la familia, el trabajo, su propia procrastinación y la pereza en el trabajo de rutina de la estandarización del código. Aunque aún tendrá que hacerse algún día.

En mi trabajo, me adhirí a un modelo algo inusual de la neurona. Un modelo neuronal, como una neurona biológica, podría actuar de forma asincrónica a partir del trabajo de otras neuronas. Las señales de las claves del receptor, como las de los receptores de la piel, pueden no estar sincronizadas. Por lo tanto, en los primeros modelos, bajo la influencia del pensamiento estereotípico, seleccioné ciertas fases del estado en la neurona que duran un cierto número de pasos (ciclos) de todo el sistema, y ​​los pasos del sistema se realizaron sincrónicamente en todas las neuronas. Esto no funcionó correctamente y fue terriblemente incómodo. Pero era necesario sincronizar de alguna manera las señales entrantes y salientes, y evaluarlas correctamente.

En cierto momento, surgió la idea de que un usuario de Internet posteriormente apodó el "tanque de drenaje". El modelo de "tanque de drenaje" resultó ser sorprendentemente preciso y aplicable a una neurona biológica, explicaba muy claramente los mecanismos de suma y era más conveniente de implementar. Ahora las neuronas emuladas podrían ser completamente independientes, al igual que los objetos reales.



Este modelo sumador es el modelo neuronal biológico más preciso que conozco. Simular una célula gástrica en detalle requerirá un poder de procesamiento increíblemente grande, pero todo lo que esta célula hace es producir la enzima u hormona apropiada si es necesario. Atribuir increíbles propiedades computacionales a una neurona es muy popular entre la cibernética moderna.

Posteriormente, algunos mecanismos de la teoría del reflejo y la idea de la orientación direccional de los ajustes de potencia de sinapsis salientes se agregaron al modelo de suma. El modelo resultante permitió crear una base teórica, que simplemente explicaba muchos procesos y fenómenos que ocurren en el sistema nervioso. Los mecanismos reflejos, la memoria y la consolidación de la memoria, la autoorganización y la especialización de las neuronas, el trabajo del cerebelo, los mecanismos emocionales y el pensamiento están en una botella.

No aburriré. Enlace al repositorio de GitHub .

Por ejemplo, el código del script que contiene la lógica principal del funcionamiento del elemento neural NeironScript.cs (perdón por mi francés):

Mucho código
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class NeironScript : MonoBehaviour {

	public GameObject prefabNeiron;          // 
	public GameObject prefabSinaps;          // 

	public int IndexNeiron = 0;              // 

	private int _TypeIndexNeiron = 0;        //  

	public int TypeIndexNeiron               //  
	{
		get { return _TypeIndexNeiron; }
		set {
			if (value == 0) 
				{ _TypeIndexNeiron = value;
				  gameObject.GetComponent<SpriteRenderer>().color = new Color32(255, 255, 0, 255);//, 
				}	
			if (value == 1) 
				{ _TypeIndexNeiron = value;
				gameObject.GetComponent<SpriteRenderer>().color = new Color32( 0, 255, 0, 255); //,  //
				}	
			if (value == 2) 
				{ _TypeIndexNeiron = value;
				gameObject.GetComponent<SpriteRenderer>().color = new Color32(0, 255, 255, 255);//,  
				}
			if (value == 3) 
				{ _TypeIndexNeiron = value;
				gameObject.GetComponent<SpriteRenderer>().color = new Color32(255, 255, 255, 255);//,  
				}
			}
	}
	//   0
	public float Adder = 0.0f; 										//

	public float MaxAdder = 30f;									//  

	public float DampferAdder = 1.0f; 								// 
	public float thresholdTop = 1.0f; 								//  
	public float AnswerTime = 0.1f;      							// 
	public float TimeRepose = 0f;       							//  

	public bool IgnoreInput = false; 								//  
	public List<GameObject> hitSinaps = new List<GameObject>();  	// 

	public GameObject Area; 										//

	private bool _ActionN;											//  
	
	public bool ActionN												//  
	{
		get { return _ActionN; }
		set 
		{
			_ActionN = value;
			if (Area != null)
			{
				gameObject.GetComponent<LineRenderer>().enabled = value; //  ..
                bool existAction = Area.GetComponent<AreaScript>().NeironActionList.Contains(gameObject); //existAction = true -       
				if (_ActionN && (!existAction)) Area.GetComponent<AreaScript>().NeironActionList.Add(gameObject); //    
				else Area.GetComponent<AreaScript>().NeironActionList.Remove(gameObject); //    
			}
		}
	}

	//   1 

	public float thresholdDown = -5.0f;			 		//  
	public float timeIgnore = 5.0f;   					//        
	public float bonusThreshold = 0f; 					//   
	public float DempferBonusThreshold = 1.0f; 			//   
	public float TimeEvaluation = 5.0f;					// 
	public int LimitRecurrence = 5; 					// 
	public float thresholdTopUp = 1.0f;					//   

	public bool TimeEvaluationBool = false;				// 
	public int LimitEvaluationInt = 0;					//     

	public float AdaptationTime = 0;                    // 
	public float thresholdAdapt = 1f;                   //  

	//   2

	public float MaxForceSinaps = 100f;
	private Vector3 VectorPattern; 						// 
	public Vector3 VectorTrend; 						// 

	public float Charge = 0.0f; 						//
	public float TimeCharge = 0.01f; 					//   

	private float changeAngle = 0f; 					//  

	public float FocusNeiron = 90f;						// 
	public bool FocusDinamic = true;                    //  
	public float StepFocus = 1f;						//  
	public float MaxFocus = 90f;						//  

	public float Plasticity = 1.0f; 					//
	public bool PlasticityDinamic = true; 				//   
	public float StepPlasticity = 0.01f;				// 
	public float BasicPlasticity = 1.0f;				//  (  )
	public bool NewNeironDinamic = true;				//   

	

	private float angleMin = 0f;

	private bool CorunPlasticRun = false;

	// END VAR

    private Vector3 noveltyVector = Vector3.zero;
    private float noveltyFactor = 0.1f;

	IEnumerator StartSummator (){
		IgnoreInput = true;  //   
		gameObject.GetComponent<SpriteRenderer>().color = new Color32(255, 0, 0, 255); // 
		ActionN = true; //    
		yield return new WaitForSeconds(AnswerTime); // 
		ActionN = false; 
		ExcitationTransfer (); // 
		yield return new WaitForSeconds(TimeRepose);// 
		IgnoreInput = false; //    
		TypeIndexNeiron = _TypeIndexNeiron; //   
	}

	IEnumerator repolarizationTime (){
		IgnoreInput = true; //   
		gameObject.GetComponent<SpriteRenderer>().color = new Color32(0, 0, 255, 255);//  
		yield return new WaitForSeconds(timeIgnore);// 
		IgnoreInput = false;
		TypeIndexNeiron = _TypeIndexNeiron;//  
	}

	IEnumerator StartModule (){
        IgnoreInput = true; //   
		ActionN = true; // ,      
		gameObject.GetComponent<SpriteRenderer>().color = new Color32(255, 0, 0, 255);// 
		yield return new WaitForSeconds(AnswerTime);// 
		ExcitationTransfer ();//    
		ActionN = false;//  
		yield return new WaitForSeconds(TimeRepose);// 
		IgnoreInput = false;//   
		TypeIndexNeiron = _TypeIndexNeiron;// 
		StartCoroutine ("EvaluationTime");//  
		if ((AdaptationTime > 0) && (thresholdTop > thresholdAdapt)) StartCoroutine ("AdaptationVoid");// ,     =0   
        //         
	}

	IEnumerator EvaluationTime(){ 
		TimeEvaluationBool = true;//   
		yield return new WaitForSeconds(TimeEvaluation);
		TimeEvaluationBool = false;//  
	}

	IEnumerator AdaptationVoid(){
		yield return new WaitForSeconds(AdaptationTime);//  
        if (thresholdTop > thresholdAdapt) thresholdTop--;// ,    
		if ((AdaptationTime > 0) && (thresholdTop > thresholdAdapt)) StartCoroutine ("AdaptationVoid");//  
	}

	IEnumerator NegativeRepolarization(){
		IgnoreInput = true; //   
		ActionN = true; //
        for (int i = 0; i < 16; i++)
        {  //  
			Charge = Area.GetComponent<AreaScript>().Spike2[i];
			if (Charge > 0) gameObject.GetComponent<SpriteRenderer>().color = new Color32(255, 0, 0, 255); //
			else gameObject.GetComponent<SpriteRenderer>().color = new Color32(0, 0, 255, 255); //
			yield return new WaitForSeconds(TimeCharge); //  /
		}
		Charge = 0f;// 
		TypeIndexNeiron = _TypeIndexNeiron;// 
		ActionN = false;//
		IgnoreInput = false;//    
	}

	IEnumerator StartAssociative(){
		IgnoreInput = true;//  
		ActionN = true;//
        StartCoroutine("PositiveRepolarization"); //   
		yield return new WaitForSeconds(AnswerTime); 		//  
		Compass ();//  
	}

	IEnumerator StartWhite() {
        IgnoreInput = true;//  
        ActionN = true;//
        StartCoroutine("PositiveRepolarization");//   
		yield return new WaitForSeconds(AnswerTime); 		// 
		ExcitationTransfer ();//    
	}

	IEnumerator PositiveRepolarization(){
		for (int i = 0; i < 16; i++) {
            //  
			Charge = Area.GetComponent<AreaScript>().Spike1[i];
			if (Charge > 0) gameObject.GetComponent<SpriteRenderer>().color = new Color32(255, 0, 0, 255); //
			else gameObject.GetComponent<SpriteRenderer>().color = new Color32(0, 0, 255, 255); //
			yield return new WaitForSeconds(TimeCharge); //  
		}
		Charge = 0f; // 
		TypeIndexNeiron = _TypeIndexNeiron;// 
		ActionN = false;// 
		yield return new WaitForSeconds(TimeRepose);// 
		IgnoreInput = false;// 
		StartCoroutine ("EvaluationTime");// 
		if ((AdaptationTime > 0) && (thresholdTop > thresholdAdapt)) StartCoroutine ("AdaptationVoid");//
	}

	IEnumerator PlasticTimeCoruntine (Vector2 PT){//  
		CorunPlasticRun = true;//   
		float PlasticBuffer = Plasticity;//  
		Plasticity = PT.x;// 
		yield return new WaitForSeconds(PT.y);//  
		Plasticity = PlasticBuffer;//  
		CorunPlasticRun = false;//   
	}

	public void ActiveNeiron (){ //        
		if (!IgnoreInput)
		{
			if (TypeIndexNeiron == 0) StartCoroutine ("StartSummator");//  
			if (TypeIndexNeiron == 1) StartCoroutine ("StartModule");// 
			if (TypeIndexNeiron == 2) StartCoroutine ("StartAssociative");// ,    
			if (TypeIndexNeiron == 3) StartCoroutine ("StartWhite");//  
		}
	}

	private void Compass (){
		if (Area != null){ //    ,        
			VectorPattern = Vector3.zero; //  
            //  
			for (int i = 0; i < Area.GetComponent<AreaScript>().NeironActionList.Count; i++) { //   
				if (gameObject == Area.GetComponent<AreaScript> ().NeironActionList [i]) continue; //    
				Vector3 R = Area.GetComponent<AreaScript> ().NeironActionList [i].transform.position - transform.position;//  ,   
                //       
				VectorPattern += (Area.GetComponent<AreaScript> ().NeironActionList [i].GetComponent<NeironScript> ().Charge * R.normalized);//R.sqrMagnitude; .normalized   //sqrMagnitude;!!!!!!!!!(  )
			}

			if (VectorPattern.sqrMagnitude < 3f) VectorPattern = VectorTrend; //   ,    
			if (VectorPattern.sqrMagnitude == 0) VectorPattern = new Vector3(Random.Range(-1f, 1f), Random.Range(-1f, 1f), Random.Range(-1f, 1f)); 
            //   ( ),    ,    ,    - 

			VectorPattern.Normalize(); //   

            if (noveltyVector == Vector3.zero) noveltyVector = -VectorPattern; //  (   )    -    
			changeAngle = Vector3.Angle(VectorPattern, noveltyVector);//         

			if (Area != null) Area.SendMessage("MessageOriginality", changeAngle/180);//      

			VectorTrend = VectorPattern; // 
            noveltyVector = Vector3.Slerp(noveltyVector, VectorPattern, noveltyFactor);//  
            //      
            //        
            //   noveltyVector = VectorPattern,       (     )
            //       ,       
			gameObject.GetComponent<LineRenderer>().SetPosition(0, transform.position);//   
			gameObject.GetComponent<LineRenderer>().SetPosition(1, transform.position + VectorTrend * 6);

           
			if (PlasticityDinamic) {
				if (changeAngle < 10) Plasticity -= StepPlasticity; else Plasticity += StepPlasticity; // 
				if (Plasticity > 1) Plasticity = 1f;
				if (Plasticity < 0) Plasticity = 0f;
                //         
                //    ,         . 
                //..        ,       
			}

			if (FocusDinamic){
				if (changeAngle < 10) FocusNeiron -= StepFocus; else FocusNeiron = MaxFocus;
				if (FocusNeiron < 0) FocusNeiron = 0;
                //         .
                //        .
                //       .
                //   -     ,      
			}

            //  
			if (NewNeironDinamic){
                if (!Physics.CheckSphere(transform.position + VectorTrend * 5, 3f))
                {   //  -     3,
                    //     5   
                    //   
					if (Area.GetComponent<AreaScript>().Global) NewNeiron(); //    
					else 
					{
						if (Area.GetComponent<Collider>().bounds.Contains(transform.position + VectorTrend * 5)) NewNeiron(); //          
					}
				}

				//   
                Collider[] hitColliders = Physics.OverlapSphere(transform.position + VectorTrend * 5, 3f); //          
				foreach (Collider value in hitColliders) //    
				{
					if (value.tag == "Neiron") //  
					{
						bool EnableSinaps = false; //    
						foreach (GameObject sinapsValue in hitSinaps) //    
						{
							if (sinapsValue.GetComponent<SinapsScript>().NeironTarget == value.gameObject) {
								EnableSinaps = true; //   
								break; //  
							} 	
						}
						
						if (!EnableSinaps) { //   
							GameObject cSinaps = Instantiate(prefabSinaps, transform.position, transform.rotation) as GameObject;//   
							cSinaps.transform.parent = transform;
							cSinaps.GetComponent<SinapsScript>().NeironTarget = value.gameObject;
							cSinaps.GetComponent<SinapsScript>().Force = 0f;
							hitSinaps.Add(cSinaps);

						}

					}
				}
			}

			//        
			angleMin = 180f;
			if (hitSinaps.Count != 0) angleMin = Vector3.Angle(hitSinaps[0].GetComponent<SinapsScript>().NeironTarget.transform.position - transform.position, VectorTrend);
			foreach(GameObject ShershSinaps in hitSinaps)
			{
				float angleShersh = Vector3.Angle(ShershSinaps.GetComponent<SinapsScript>().NeironTarget.transform.position - transform.position, VectorTrend);
				if (angleShersh < angleMin) angleMin = angleShersh;
			}
           
			if (FocusNeiron < angleMin) FocusNeiron = angleMin;
            //      ,       .
            //        , 
            //        .

			//  
			foreach(GameObject SinapsCoeff in hitSinaps){
					if (SinapsCoeff.GetComponent<SinapsScript>().TypeSinaps == 0){
					    float angleSinaps = Vector3.Angle(SinapsCoeff.GetComponent<SinapsScript>().NeironTarget.transform.position - transform.position, VectorTrend);
					    if (angleSinaps <= FocusNeiron) SinapsCoeff.GetComponent<SinapsScript>().Force += MaxForceSinaps * Plasticity;
					    else SinapsCoeff.GetComponent<SinapsScript>().Force -= MaxForceSinaps * Plasticity;
					    SinapsCoeff.GetComponent<SinapsScript>().Force = Mathf.Clamp(SinapsCoeff.GetComponent<SinapsScript>().Force, 0, MaxForceSinaps);
				    }
			}
		}

		ExcitationTransfer ();//    
	}

	private void NewNeiron (){
		GameObject clone = Instantiate(prefabNeiron, transform.position + VectorTrend * 6, transform.rotation) as GameObject;
        /*  :        (   ),
         *      ,        
         *        ,     .
         *       ....
         * */
		if (Area != null) Area.GetComponent<AreaScript>().amount++;//     

		clone.GetComponent<NeironScript>().Plasticity = BasicPlasticity;//  
		clone.GetComponent<NeironScript>().ActionN = false;
		clone.GetComponent<NeironScript>().IgnoreInput = false;
		clone.GetComponent<NeironScript>().Adder = 0f;
		clone.GetComponent<NeironScript>().VectorTrend = Vector3.zero;
		clone.GetComponent<NeironScript>().Area = Area;
		clone.GetComponent<NeironScript>().TimeEvaluationBool = false;
		clone.GetComponent<NeironScript>().LimitEvaluationInt = 0;
		clone.GetComponent<NeironScript>().Charge = 0.0f; 
		clone.GetComponent<NeironScript>().FocusNeiron = MaxFocus;
		clone.GetComponent<NeironScript>().Plasticity =  BasicPlasticity;
		clone.GetComponent<NeironScript>().TypeIndexNeiron = 2;
        clone.GetComponent<NeironScript>().noveltyVector = Vector3.zero;
        clone.GetComponent<NeironScript>().VectorTrend = Vector3.zero;

		clone.GetComponent<LineRenderer>().SetPosition(0, clone.transform.position);
		clone.GetComponent<LineRenderer>().SetPosition(1, clone.transform.position);

		clone.SendMessage("StopNeiron"); //          ,   

		GameObject ManagerObj = GameObject.Find("Manager"); //... , Find   
		ManagerObj.GetComponent<ManagerScript>().EndIndexNeiron++;// 
		clone.GetComponent<NeironScript>().IndexNeiron = ManagerObj.GetComponent<ManagerScript>().EndIndexNeiron;//    
		clone.name = "Neiron" + clone.GetComponent<NeironScript>().IndexNeiron;//     

        foreach (GameObject sd in clone.GetComponent<NeironScript>().hitSinaps) Destroy(sd); //       ,     
		clone.GetComponent<NeironScript>().hitSinaps.Clear(); //   .  ..
	}

	void FixedUpdate(){ //      0.01


		if (!IgnoreInput) //    
		{
			if (TypeIndexNeiron == 0)  //    
			{
				if (Adder > thresholdTop) // 
				{
					StartCoroutine ("StartSummator"); 
				}
			}

			if (TypeIndexNeiron == 1) //  
			{
				if (Adder > thresholdTop + bonusThreshold) // 
				{
					
					if (TimeEvaluationBool) //  ?
					{                       
						LimitEvaluationInt++; // 
						StopCoroutine("EvaluationTime"); //    
						TimeEvaluationBool = false; //  
					}
					else LimitEvaluationInt = 0; //   

					if ((LimitEvaluationInt > LimitRecurrence) && (bonusThreshold == 0)) thresholdTop += thresholdTopUp; //         - 

					StopCoroutine ("AdaptationVoid");  // ,      
					StartCoroutine ("StartModule"); //    
					
				}

				if (Adder < thresholdDown) //    
				{
					if (Area != null) StartCoroutine ("repolarizationTime"); //   ,    
				}
			}

			if (TypeIndexNeiron == 2) // 
			{
				if (Adder > thresholdTop + bonusThreshold) //    :   
				{
					if (TimeEvaluationBool) //     
					{
						LimitEvaluationInt++; //  
						StopCoroutine("EvaluationTime");//  
						TimeEvaluationBool = false;
					}
					else LimitEvaluationInt = 0; //   ,  

					if ((LimitEvaluationInt > LimitRecurrence) && (bonusThreshold == 0)) thresholdTop += thresholdTopUp; //      ,    

					StopCoroutine ("AdaptationVoid");// ,   ( -    )
					StartCoroutine ("StartAssociative"); //    
				}

				if (Adder < thresholdDown) //   
				{
					StartCoroutine ("NegativeRepolarization");  //  ()
				}
			}

			if (TypeIndexNeiron == 3) //  
			{
				if (Adder > thresholdTop + bonusThreshold)//   
				{
					if (TimeEvaluationBool)// ...
					{
						LimitEvaluationInt++;
						StopCoroutine("EvaluationTime");
						TimeEvaluationBool = false;
					}
					else LimitEvaluationInt = 0;

					if ((LimitEvaluationInt > LimitRecurrence) && (bonusThreshold == 0)) thresholdTop += thresholdTopUp;

					StopCoroutine ("AdaptationVoid");
					StartCoroutine ("StartWhite");  
				}

				if (Adder < thresholdDown)
				{
					StartCoroutine ("NegativeRepolarization");  
				}
			}

		}

        if (Mathf.Abs(Adder) <= DampferAdder) Adder = 0f; // 
		if (Adder > DampferAdder) Adder -= DampferAdder;
		if (Adder < -DampferAdder) Adder += DampferAdder;

        if (Mathf.Abs(bonusThreshold) <= DempferBonusThreshold) bonusThreshold = 0f; //  
		if (bonusThreshold > DempferBonusThreshold) bonusThreshold -= DempferBonusThreshold;
		if (bonusThreshold < -DempferBonusThreshold) bonusThreshold += DempferBonusThreshold;
	} 

	private void ExcitationTransfer () // 
	{
		foreach (GameObject value in hitSinaps) //   
		{
			int T = value.GetComponent<SinapsScript>().TypeSinaps; // 
			float F = value.GetComponent<SinapsScript>().Force; // 
			GameObject NT = value.GetComponent<SinapsScript>().NeironTarget;// 
			if (T == 0) NT.SendMessage("AddSummator", F);// 
			if (T == 1) NT.SendMessage("AddTActual", F);
			if (T == 2) NT.SendMessage("ActiveNeiron");
            if (T == 3) NT.SendMessage("AddSummator", F);
			value.GetComponent<SinapsScript>().GoAction = true;//  
		}
	}

	public void AddSummator (float Summ) //      
	{
		Adder += Summ;
		if (Adder > MaxAdder) Adder = MaxAdder;
        if (Adder < - MaxAdder) Adder = -MaxAdder;
	}

	public void AddTActual (float T)//  ,  
	{
		bonusThreshold += T;
		if (bonusThreshold + thresholdTop < 0f) bonusThreshold = - thresholdTop + 0.0001f;
	}

	public void StopNeiron(){//  ,     GameOject.SendMessage("StopNeiron") 
		StopAllCoroutines();
	}

	public void plasticSetTime (Vector2 plasticTime){
        //  , SendMessage     , Vectir2 -    
        //     
		if (!CorunPlasticRun) StartCoroutine("PlasticTimeCoruntine", plasticTime);
        if (TypeIndexNeiron == 2) thresholdTop = thresholdAdapt;
	}
}




La comunicación entre las neuronas se lleva a cabo utilizando un sistema de mensajes, basado en SendMessage, y todos los procesos asociados con los cambios de estado se realizan en las rutinas.



En el diagrama de bloques, la base básica del neuroelemento. SendMessage ("AddSummator", F): sinapsis de acción directa con fuerza F, aumenta la suma del sumador en un número determinado. Cada 0.01 s, la función FixedUpdate () se activa en la cual el modulador del sumador disminuye por el amortiguador / número establecido. Y también hay una comprobación de que se supera el umbral en el sumador, si se supera el umbral, se inicia la coruntina. Durante el período de operación corundina, se activa el modo de ignorar las señales externas, pero el amortiguador para el sumador continúa, así como la oportunidad de reponer la cantidad. SendMessage ("ActiveNeiron"): sinapsis de contacto (efaps), se iniciará la rutina si no se está ejecutando actualmente; de ​​lo contrario, se ignorará la señal.

En base a esta base, se agregaron mecanismos relacionados con el metabolismo celular (adicción y adaptación), así como un sistema de modulación, que se derivó del trabajo de Eric Kandel. Y la idea de transmisión direccional de excitación en aras de la verificación de que comencé este proyecto.

Muchos estaban interesados ​​en el código fuente del proyecto, pero no solo por esta razón publico la fuente. El hecho es que todavía hay mucho trabajo por delante, planea expandir seriamente las capacidades y herramientas, crear un cierto entorno que le permita trabajar convenientemente con una gran variedad de elementos, estructurarlos y organizarlos. No tengo mucha experiencia en programación, pero estoy seguro de que un gran número de personas de la comunidad GeekTimes puede dar recomendaciones sobre la estructura, los métodos y las optimizaciones que mejorarán cualitativamente el proyecto. Planeo no cambiar el entorno de desarrollo, la empírica del proceso de desarrollo es importante para mí, así como la estética del resultado final y el motor de juego de Unity hasta ahora me han ayudado mucho en esto.

Source: https://habr.com/ru/post/es398867/


All Articles