#TSNB_redes_neuronales – nas.py I

Introducción de las RnA’s

Primero antes de nada mi agradecimiento a José Luis (@_ciudadano72) por dejarme navegar en esta incesante aventura, y poder aprender de un gran maestro. Para ello documentaré como base de estudio propio y aprendizaje, y poder compartir y quede plasmado mi estudio para aquellas personas que lo puedan necesitar. Por ello estudiaré el código fuente y el flujo de ejecución del programa mediante esquemas y explicaciones sencillas, pudiendo abarcar el estudio creando un esquema mental del funcionamiento para el desarrollo de aplicaciones útiles en los diferentes campos de la informática.

“El objetivo final de esta investigación es el desarrollo de un modelo teórico-práctico en el ámbito de la estructuración Neuronal y su conexionismo para la implementación de aplicaciones prácticas relacionadas con la Inteligencia Artificial (I.A)”

La Web principal del Research, podreis encontrar información además de mi estudio, actualizaciones que irá publicando Jose Luis, https://computacionneuronal.com/

Las Redes Neuronales artificiales que se exponen en esta investigación son a bajo nivel, parten de una neurona artificial real y se establece posteriormente dentro del segmento computacional actual, el binario [0,1]. Veremos que el punto medio de estos dos valores dentro del método constructor  de la clase (INIT) es  __learning , con un valor medio de 0.5, constante. Se establecen saltos lineales entre [0….1], una progresión, es decir, cuanto más esté ajustándose la red para obtener el resultado deseado (el patrón), indica que la red está aprendiendo el patrón deseado a su salida, -por ejemplo tenemos una entradas variables en el tiempo, y queremos  ir detectando o determinando un patrón o patrones específicos para su tratamiento-.

Empezaremos el estudio con la neurona básica real (coma flotante) denominada Nas (naspy), veremos que cuanto más se va ajustando la misma para obtener el patrón deseado a su salida, el diferencial de aprendizaje va disminuyendo porque se va acercando a la resolución del patrón. Por ejemplo; para resolver un patrón de una imagen, una RnA nunca llegará al 100% de efectividad o resolución final, quizás en un 80% o algo similar, pero le será suficiente para poder determinar o “deducir” que se trata de la imagen en cuestión con un alto grado de probabilidad, gracias a su gran tolerancia al error.

Las estructuras neuronales creadas o conformadas a través de RnA’s son estructuras compuestas por unidades independientes discretas (neuronas) u otras estructuras (otras RnA’s), de gran paralelismo y con un alto grado de conectividad y con una topología estructurada en diferentes capas. Amplían el espectro de resolución de problemas, principalmente con todos aquellos relacionados con tareas complejas y representan, un “instrumento” de computación muy potente si se compara con la programación simbólica actual. El aprendizaje (ajuste para la obtención del patrón deseado) puede ser automatizado o supervisado.

La neurona básica Nas (naspy) de dos entradas definidas por las etiquetas den1 y den2 establecen dos entradas binarias a su unidad y cuatro posibles combinaciones de salidas en función de sus entradas con valores 0 y 1 . El grupo de combinaciones posibles a sus entradas es sencillo; 00,01,10,11. El lenguaje empleado en esta investigación es Python bajo la licencia GPLv3 (GNU), un lenguaje muy accesible para la implementación de esta tecnología al ser un lenguaje muy potente en lo que a programación orientada a objetos se refiere (POO). Los objetos básicos que se crearán (instanciarán por código) en las implementaciones (aplicaciones –casos) partirán como base de una pieza de código denominada -clase- , y serán las neuronas que emplearemos a lo largo de la investigación.

La topología Neuronal (RnA’s) es de naturaleza paralela en un alto porcentaje con excepción de redes específicas especializadas (mixtas). Se emplea una técnica electrónica denominada Netlist para la interconexión entre las diferentes neuronas o estructuras neuronales realizadas a través de las funciones que las implementan, técnica electrónica. https://en.wikipedia.org/wiki/Netlist

En este primer caso1.py, veremos cómo se genera la memoria (RamDisk), que es única e inequívoca por neurona. Para la ejecución (sinapsis) una vez la neurona ha sido entrenada (aprendizaje del modo de funcionamiento) es una combinación de las entradas proporcionadas a la misma y el aprendizaje establecido en el RamDisk obteniendo la salida deseada (axón) para la obtención del patrón deseado .

El “símil” computacional de la parte química donde reside el aprendizaje en las neuronas reales son los pesos (RamDisk) en las neuronas artificiales en su combinación con las entradas el cual, varía en tanto las entradas a la neurona cambian. El proceso es el siguiente:

  • En primer lugar para cada combinación de las entradas y en función del patrón (cuatro combinaciones) deseado, la neurona se va autoajustando hasta que uno de los valores de incremento entre el intervalo [0…1] haga que la condición se cumpla y así sucesivamente, y para cada valor deseado obtenido a la salida en función de la entrada, el peso correspondiente en coma flotantee se almacena en el RamDisk. El __learning.
  • Una vez la neurona ha aprendido el patrón de salida (pattern) para cada combinación de entradas y almacenado en el RamDisk, -pesos-, en la implementación (aplicación) se ejecutarán la combinación de entradas neuronales, -dendritas-, de una forma secuencial; 00,01,10,11 o arbitraria; 11,01,00,11, para satisfacer el patrón deseado, y ¿como lo hace? , matcheando la combinación de entradas con su peso correspondiente almacenado en el RamDisk, obteniendo la salida deseada para cada combinación y en su conjunto.., el patrón deseado (pattern).

Para hacer una similitud de lo que significa “ajuste” neuronal para la determinación del patrón en función de la combinación de entradas lo podemos comparar como un “dial” que va barriendo progresivamente un intervalo, en nuestro caso entre [0….1], en coma flotante, -pequeños intervalos-, hasta que uno de esos intervalos o incrementos hace que se satisfaga la condición de salida para una combinación de entradas dada.

Una neurona sola (unidad de cómputo) sólo aprende el patrón deseado (su modo de funcionamiento), pero cuando la conectas con las demás en profusión en paralelo en diferentes capas, se tiene que reprogramar todo para obtener el patrón deseado, eso es una RnA, y como se consigue eso, a través de realimentaciones ajustando la red de igual forma que lo hacemos en una neurona específica, eso si, el nivel de cálculo es más complejo porque la interacción paralela de cada unidad exige tener en cuenta el “todo” en los cálculos necesarios para obtener el patrón deseado a su salida.

A nivel individual, por unidad de cómputo (neurona) el siguiente ejemplo os ayudará a comprender mejor todo este proceso:

Imaginaros que queréis encontrar un canal de “radio” determinado, -ese canal de radio es la posición del incremento (puntero) que hace que la salida deseada se obtenga en función de la combinación de entradas dada-, para ello vamos sintonizando manualmente (aprendizaje supervisado) mediante un dial el rango de frecuencias de izquierda a derecha [0…..1] hasta que de repente el díal encuentra la frecuencia que hace que empecemos a escuchar la emisora deseada, ese valor.., es el peso que se almacenará en el RamDisk y que se asociará inequívocamente a la combinación de entradas dada. Posteriormente la combinación de entradas cambia, el díal se “resetea” a cero (izquierda) y el proceso se repite, y así sucesivamente para todas las demás combinaciones de entrada, todo ello teniendo encuenta en cada aprendizaje (ajuste) el patrón individual por combinación de entradas deseado (el modo de funcionamiento). Una vez finaliza el proceso de aprendizaje, la neurona ya estará lista para ejecutar (sinapsis) el patrón para el cual ha sido entrenada. Imaginaros por un momento que ese díal que movéis de una forma manual a mano dándole vueltas a la rueda hacia la derecha (aprendizaje supervisado) lo realizáis de una forma automática, dándole a un botón, eso es el aprendizaje automatizado.

Todo ese proceso de aprendizaje lo realiza de una forma secuencial (entre funciones y condicionales) en base a realimentaciones la neurona y de una forma más compleja en una Red neuronal para establecer lo anteriormente comentado tal y como podéis ver en el esquema que os muestro a continuación, específico para la neurona básica Nas (naspy) pero sirve como base para que podáis entender todo el proceso en este caso y las demás implementaciones (casos de uso) que veréis a lo largo de toda la investigación (Research).

Como podéis observar en la imagen que os muestro a continuación , en la primera línea “[‘neuron_0′, ’00’,……”, los valores en coma flotante corresponden a los generados por la función de activación.  Si el valor en coma flotante es negativo < 0 su equivalencia binaria es el 0 (salida) e inversamente, cuando el valor en coma flotante es > 0, su salida binaria es 1. Recordad que si establecéis el __learning de aprendizaje (modo de funcionamiento neuronal, el patrón de salida deseado para la combinación de las entradas que en el caso de esta neurona básica es de dos bits es decir, cuatro posibles combinaciones) , la neurona se vuelve a ajustar haciendo el barrido en coma flotante para obtener la salida deseada (_out) y el proceso se repite para obtener el patrón deseado.

Automatizar el aprendizaje de una neurona como unidad de cómputo independiente y una RnA en su conjunto para que se ajuste dinámicamente y en función de las entradas a un patrón determinado, variando su modo de funcionamiento computacional in situ tiene un alcance de desarrollo muy amplio, básicamente modificamos el funcionamiento de una unidad de cómputo (neurona) la forma de comportarse de una forma dinámica, lo que de una forma se consigue de una forma artificial mediante la programación simbólica, lo hacemos de una forma estructural a base de realimentaciones, se genera “inteligencia”, adaptación al medio (entradas), el campo de aplicación es inmenso y abre infinitas posibilidades de desarrollo en el cómputo actual. En realidad la electrónica y el software que conocemos son de naturaleza conexionista (neuronal) lo que hacemos con la Inteligencia Artificial (I.A) es cambiar el prisma, la forma de generar más inteligencia, de dar valor.

Dinamizar el modo de funcionamiento en tiempo de ejecución a través de los pesos del código de ejecución abre un amplio abanico de posibilidades de computación; se podría aplicar a la seguridad para la detección de Malware, electrónica de red para solución de problemas en  los protocolos de comunicación y otros similares, identificación facial de personas, etc.-.

Cuando veamos la bias2_4, empezaremos ver la estructuración usando la nas.py(neurona). Bias significa polarización, es decir, la estamos energizando al hacer la instanciación de la neurona. Es un concepto de la electrónica.

Caso1.py

Empezare mostrando el código fuente del caso1.py y los módulos que importa, la lib_nas.py y la nas.py.

Este script llamado caso1.py, básicamente importa dos módulos y hace una llamada a la función, instanciando un objeto “n0” llamando a la clase neuron de nas.py. Mientras sea verdad ejecutará una serie de instrucciones donde podremos interactuar con nuestro objeto. Esta es la estructura principal del objeto “n0”:

Veremos con detalle este esquema y la “app” caso1.py. Es interesante que os muestre el código fuente de la lib_nas.py y la nas.py que veremos cuando proceda, más adelante en profundidad. Nas.py:

Lib_nas.py:

Y este sería todo el código fuente donde vamos a trabajar en el caso1.py del Research. Si no entendéis el código no os asustéis terminareis entendiéndolo una vez finalizada su lectura en esta documentación. Y para aquellos que ya entendéis el código y sabéis perfectamente el funcionamiento y su flujo de ejecución, podéis saltaros esta explicación. El objetivo es el entendimiento para poder pasar al caso2.py.

Llamada a la función _init_net() e instanciación de la neurona “n0”

A partir de aquí, es importante tener claro el flujo de ejecución del programa, ya que es la base para poder entender el funcionamiento del caso1.py, y por consecuente de la lib_nas.py y la nas.py.

Primero realizamos una llamada a la función “def _init_net_():” con _init_net(). La llamada se hace sin pasarle ningún argumento. Dentro de la función instanciamos, de la misma forma que vimos antes, el objeto “n0” llamando a la clase “neuron” de nas.py pasándole como argumento el id_, en este caso 0. Establecemos un contador a 0 también.

La llamada a la clase “neuron”, define la clase que se instanciara “n0” creándose la neurona en memoria cambiando el flujo de ejecución del programa. Así de ese modo se inicializa el constructor “__init__”, creando la neurona con unos atributos. Estos atributos son:

  • Learning de 0.5, que es el factor de aprendizaje, el valor medio.
  • El identificador de la neurona que se le pasa como parámetro, y lo convertimos al tipo de dato integer.
  • La referencia de clase, básicamente se declara un objeto mediante su atributo mágico __class__ y el nombre de la clase concatenando un guión bajo y el identificador. De esa forma creamos “neuron_0” en tipo de datos string.
  • Memory, es el resultado de la concatenación de una cadena de caracteres y el objeto (atributo) que declaramos anteriormente. Básicamente es el nombre del fichero que genera el RamDisk. En definitiva lo que crea es esto “rnl_sinap_ia_neuron_0”.

El RamDisk se genera para el almacenamiento de pesos, un fichero(file) por neurona creada (como vimos en el esquema arriba). Es el equivalente químico que realiza la sinapsis en las neuronas biológicas, donde reside el aprendizaje.

Antes de seguir, cabe destacar que cuando se instancia un objeto de tipo “self.__neurona = nas.neuron(0)”, “self” hace referencia (apunta ==puntero) al inicio del bloque de datos en memoria. Básicamente este objeto tiene una dirección de memoria. Por tanto, es interesante ver en profundidad el flujo de ejecución del programa para saber en todo momento en que parte del programa nos encontramos y las diferentes llamadas que se realizan.

Como trabajamos con funciones, en este ejemplo “sumatoria = self.funcionActivacion”, el objeto se recupera a través de la declaración de una variable, recogiendo el valor (retorno) para poder trabajar con ella.

Entonces “self.funcionActivacion”, llama a la función “def funciónActivacion”, apuntando(self) el inicio del bloque de datos de esa función recogiéndose en la variable “sumatoria”. En Python todo es un objeto.

Seguimos con la ejecución del programa analizándola. Mientras sea verdad, ejecutará todas las instrucciones de la “app” conforme a lo que nosotros queramos interactuar con la lib_nas.py y la nas.py. En el caso1.py le vamos a pasar por teclado el balanceador neuronal de función – 6 modos. Es decir un valor de 0 a 5.

Por tanto, almacena de forma oculta (oculta nos referimos a __) en la variable “__learning_logic” un valor de tipo integer. En el primer caso vamos a ver como es lógico el 0, que corresponde a una operación AND.

Aprendizaje antes de pasar las entradas

Una vez introducido el valor por teclado y dado Enter, hace una llamada a la lib_nas.py pasándole al método “_memory” el valor.

Quedaría de la siguiente forma: “lib_nas._layer_1_1_(n0,0,lib_nas._memory_(0))”

Es decir, le pasa al método (función)“_memory_” el valor 0. Como puedes observar la función “def _memory_()” esta compuesto por:

Es decir, “id_mode” recoge el valor introducido por teclado.

La variable o “referencia de objeto” (objectReference = valor), __learn crea un diccionario accediendo a las funciones “def s0():…def sn():”, almacenando las operaciones en él. Una vez creado accedemos al diccionario pasándole en integer el valor recogido por teclado “__learn[0]()” , devolviendo el resultado de la función “_memory_” con un return.

Por tanto quedaría así: “lib_nas._layer_1_1_(n0,0,lib_nas._learn_)”.

Al método _layer_1_1_ de la lib_nas, le pasamos como parámetros el objeto “n0”, la identificación de la neurona y el return de la función _memory_. Dentro de este método, tenemos una función neuron_0, y la declaración de la variable __rst_sign.

Si seguimos el flujo de ejecución del programa, la función “neuron_0” es donde reside la sinapsis y aprendizaje. El __rst_sign es para establecer, como si fuese un __init__

Partimos de la base siempre de “n0” como primer argumento y se la pasamos a la función “neuron_0” haciendo uso del método rst.sign_(). Este método se encuentra en la nas.py, por tanto vuelve a cambiar el flujo de ejecución.

Esta función lo que hace es comprobar si existe __memory_ y resetea, que si bien recordamos es el fichero RamDisk = “rnl_sinap_ia_neuron_0”.

Seguidamente va a ejecutar 4 instrucciones que llaman al método ibn_ en la nas.py.

Como argumentos la “n0”, va a tener 3. La primera dentrita, segunda y el valor de retorno “_learn_” en integer accediendo a la primera posición de la lista.

Recordamos que tanto la neurona “n0”, el _idnas y _learn_, son los argumentos de la función principal _layer_1_1_().

Por tanto al existir 4 instrucciones, quiere decir que se va a ejecutar 4 veces la función de arranque sináptico o aprendizaje en función del patrón.

Bien, ahora veremos en profundidad la sinapsis en las 4 instrucciones.

Def ibn_(0,0,0)

La función ibn_ nos la encontramos en nas.py:

Esta es la función de arranque sináptico o aprendizaje en función de patrón. Este método, tiene una serie de atributos, como las entradas y el patrón sináptico (axón_ptron). El axón_ptron lo usamos como selector. Le pasamos como primer argumento 0, segundo 0 y tercero 0. Por tanto el patrón sináptico es distinto a 11, y llama a la función self.sinap(). Este condicional es para controlar el modo de aprendizaje y el funcionamiento normal a través de la estructura de la librería lib_nas(_memory_), usada para decirle a la neurona el tipo de aprendizaje (valor de retorno _learn_) de salida deseado. Así de esa forma controlamos si la neurona hay que programarla para que aprenda (sinap) o tiene que recuperar los valores en memoria (RamDisk) una vez esta programada para obtener la salida deseada.

Llamamos a la función ibn_ a través de la estructura _memory_ el valor es distinto a (11), porque envía la secuencia de aprendizaje. Si os fijais tiene un valor por defecto (11). Cuando llamamos a la sinapsis de una formal normal, es decir, con únicamente los valores x0 y x1 (den_0, den_1) de entrada.

En el flujo de ejecución entra en el if, ya que es distinto a 11 el tercer argumento (0,0,0).

La función sinap(), se encuentra en la nas.py, y vamos a ir viendo en detalle la función sináptica de aprendizaje.

Guardamos los pesos y el _mem_ en una lista vacia. Seguidamente mediante un bucle for establecemos 2 pesos aleatoriamente en coma flotante entre [0,1]

Seguidamente guardamos las entradas en una lista. Recordamos lo que hace “self”, y básicamente hace una llamada global (__init__) para poder almacenar las entradas en forma de lista. Declaramos dos variables, salida y corrector.

Siguiendo el flujo de ejecución del programa, se establece una variable sumatoria llamando a una función o método de la clase neurona en la nas.py, cutos argumentos son dos listas.

La variable sumatoria recoge el valor de retorno de la función (self.funcionActivacion). Llamamos a la función de activación que esta dentro del objeto self. Si observamos dentro de la clase neurona y queremos llamar de una función a otra función hay que hacer uso de self. El primer parámetro de todas las funciones es self. La clase no es un objeto, es una estructura. Cuando se instancia un objeto se crea un bloque de datos en memoria con un puntero apuntando (self) el inicio del bloque de datos. Dentro de __init__, los self son globales y se pueden usar dentro de toda la clase.

La función de activación es de tipo escalon simétrica, es lineal y separable. Es donde la neurona aprende. Recibe dos listas (arrays). Inicializamos la variable sumatoria = 0. Todo en Python es un objeto. Si no se declara (inicializa), puede devolver None.

El bucle for, lo que hace es enumerar las entradas(rango de 2), por tanto sumatoria recibe estos datos: entradas[0]*pesos[0] + entradas[1]*pesos[1]. Se suma el primer valor por el primer peso, y luego el segundo valor por el segundo peso. Sumatoria es igual a cero, ya que multiplicar cero por el valor aleatorio de pesos es cero. Entra en el “if sumatoria == 0”, y sumatoria se ajusta en un nuevo bucle con un return que es el valor de retorno de la función de activación.

Seguimos el flujo de ejecución y como sumatoria es mayor que cero, se modifican las variables “salida” y “corrector” con nuevos valores.

Si la función cmp que compara dos objetos en este caso la salida y self.__axon_ptron_out, es distinto a cero, entra en la estructura de control. Como salida es mayor a self.__axon_ptron_out, el valor de retorno de la función es estrictamente positivo. En el bucle para cada valor de los pesos, y con la condición que el self.__axon_ptron_out es igual a cero, se ajustan los pesos y se ejecuta la instrucción goto.backend, volviendo a la función de activación.

Vuelve a ejecutar la función de activación, devolviendo un valor de retorno sumatoria menor o igual a cero, por tanto entra en la estructura de control elif, estableciendo una salida = 0 y corrector = 2.0. En la función cmp, al comparar los dos objetos como los dos son igual a cero, retorna ese valor y no cumple el if, pasa al else una vez ajustados los pesos y se almacena (escribe) en el RamDisk y la neurona ya esta lista.

Por tanto, abre el fichero (RamDisk):

  • _bin_: Realiza la suma binaria de (0,0) y lo pasa a strings
  • append(self.__ref_class): ‘neuron_0’
  • append(_bin_[2] + _bin_[5]): ‘00’
  • append(pesos[0]): -0.3645393429943511,
  • append(pesos[1]): -0.8638519293684906
  • append(sumatoria): -0.3645393429943511,

Escribe y lo cierra.

Def ibn_(0,1,0)

Realizaría el mismo flujo de ejecución del programa

Def ibn_(1,0,0)

Realizaría el mismo flujo de ejecución del programa

Def ibn_(1,1,1)

En este caso al ser la sumatoria mayor que cero, y la salida y el self.__axon_ptron_out iguales (1 == 1) el valor de return de la función cmp da cero. La función cmp(x,y), si x==y, devuelve cero la función. Por tanto entra directamente al else. Solo pasa una vez por la función activación.

Una vez tenemos el RamDisk, ya se terminó de ejecutar la sentencia del caso1.py:

“lib_nas._layer_1_1_(n0,0,lib_nas._memory_(0))”. Ahora establecemos una variable, para leer del RamDisk e iterar.

Se imprime en pantalla el fichero RamDisk (_mem_), que representa los diferentes pesos en función del patrón de aprendizaje.

En resumen, la neurona recibe a través de la función (ibn_) las entradas (posibilidades) y el patrón de aprendizaje – la salida deseada para el tipo de entrada — , lo hace a través de la estructura que se puede localizar en la librería dinámica lib_nas.py, llamada _memory_ y llama a la función sinap para ajustar y aprender en bucles de realimentación hasta obtener el patrón deseado para la combinación de entradas. Una vez ajustado los pesos y almacenados en un RamDisk, la neurona ya esta lista.

Ejecución con aprendizaje, “learning”

Ahora mediante entrada por el teclado, le pasaremos unos valores a la entrada, mediante un bucle for en un rango de 4. Son todas las posibilidades (00,01,10,11).

A modo de ejemplo en la ejecución, veremos cuando se le pasan 0 y 0 en detalle, y así ver como realiza la operación AND exitosamente. Recordamos que el _logic elegido fue 0, que coincide con el AND.

Seguidamente usamos el objeto “n0” llamando al método ibn_ pasándole como argumentos las dos entradas introducidas por teclado.

Esto como resultado tiene llamar de nuevo a la función ibn_ de la nas.py.

Bien, ahora veréis la diferencia justo antes de crear el RamDisk. La diferencia es que no le pasamos el tercer parámetro que correspondia al “_learn_”. Es decir, antes le pasábamos el valor de retorno de la función _memory_.

Pero ya no es necesario ya que ahora una vez ya ajusto los pesos y almacenados en un RamDisk, únicamente solo tiene que llamar a la función (_memory_back_sinap). Y como self.__axon_ptron_out tiene un valor por defecto, entra en el else:

Seguidamente vamos a ver la función memory_back_sinap. En esta función se lee el aprendizaje del RamDisk, donde reside el “learning”. Ejecuta la salida en función de las entradas y el learning que está en el RamDisk.

El proceso antes del memory_back_sinap, se le pasa las entradas desde aquí:

Y aprende el patrón. Luego con las entradas, accede a la reglamentación (al RamDisk), para ejecutar el “learning”. Estas entradas las recibe gracias al selector (self.__axon_ptron_out). Por tanto gracias a esta función (memory_back_sinap) recupera el “learning” y obtiene la tercera entrada, para ejecutar la sinopsis y obtener el patrón deseado.

El _mem_, accede a los string de las entradas: ‘00’. Abrimos el RamDisk, estableciendo una variable. W_ibn, recoge de rnl_map_sinap, y este a su vez es un descriptor de archivo. Lee de self.__memory_ el RamDisk, que es individual por neurona.

En combinación con el _mem_ and w_ibn, verifica si es ‘00’ comparando en el RamDisk para recuperar el “learning” para ese par de entradas(teclado). El _mem_ es la segunda posición del RamDisk comparándolas en w_ibn, siendo la línea donde obtiene los pesos del “learning”. W_ibn en forma de iteración lee del RamDisk de izquierda a derecha. El contenido del RamDisk es texto. Coge una línea y ajusta correspondiendo a ‘00’.

En este bucle, se mete en una lista (pesos) y ensambla la sinapsis, la ejecuta para ejecutar la sinopsis, pero ya una vez aprendido.

Es decir, necesita cargar los pesos del aprendizaje que es donde reside el “learning”. Resumen:

  • Learning sinapsis (una vez creado el RamDisk). Para aprender. Las entradas residen en la función neuron_0. En la lib_nas.
  • Ejecución con aprendizaje (memory_back_sinap). Ejecución con “learning”. Se le pasa dos entradas por teclado.

El proceso es automático, una vez se pasa las entradas se produce todo internamente para obtener el patrón o la salida deseada(_out_) una vez ajustada en flotante. Por tanto si cumple el if(_mem_ and w_ibn), obtiene el “learning”(los pesos) para ajustar el aprendizaje llamando otra vez la función de activación y obtener el patrón, resultado _out_

Al final con esto conseguimos la salida deseada que es la operación correspondiente al AND. 0,0 –> 0

En síntesis, para que quede claro, la función _memory_back_sinap() es una función normal sináptica una vez la neurona ha aprendido la secuencia y ajustado pesos, por eso a llamar la sinapsis solo pasamos las entradas por teclado (den_0, den_1), y por defecto el selector (axón_ptron_out) = = 11, ya esta lista para resolver y obtener la salida _out_

Todo lo descrito en esta entrada es la explicación de una neurona de 2 bits, con dos entradas; y el uso de una app para ver su funcionamiento. También será la primera entrada de muchas de mi estudio del Research sobre RnA’s

Un saludo, n4ivenom

 

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Los datos introducidos se guardarán en nuestra base de datos como parte del comentario publicado, como se indica en la política de privacidad.