Índice analítico[Ocultar][Mostrar]
O cerebro é comparable ás redes neuronais. Esta é a analoxía que normalmente se usa para axudar a alguén novo no tema a comprender as ideas detrás da aprendizaxe automática e das redes neuronais artificiais.
Debido a que hai varias capas de cálculos matemáticos e estatísticos entre bastidores, definir estas redes como unha función matemática é un método máis avanzado.
Isto é para as persoas que realmente están interesadas na aprendizaxe automática e queren ver como se escribe o código de rede neuronal de Python.
Neste artigo, demostraremos como construír unha rede neuronal profunda (DNN) totalmente conectada desde cero. Pitão 3.
Unha visión xeral da estrutura de ficheiros para o noso código de rede neuronal Python
Crearanse tres ficheiros aquí. O primeiro é o ficheiro nn.py sinxelo, que se comentará en "Configuración de funcións auxiliares" e "Construción da rede neuronal desde cero".
Tamén teremos un ficheiro chamado mnist loader.py para cargar os datos de proba, como se describe en "Cargando datos MNIST".
Finalmente, teremos un ficheiro chamado test.py que se lanzará no terminal para probar a nosa rede neuronal.
Este ficheiro descríbese en detalle en "Execución de probas".
instalación
A biblioteca NumPy Python debe descargarse para seguir este tutorial. Podes facelo usando o seguinte comando no terminal:
Importando módulos e configurando a función Helper
As dúas únicas bibliotecas que necesitamos son aleatorias e NumPy, que importaremos de inmediato. Para os pesos iniciais da nosa rede neuronal, barallarémolos usando a biblioteca aleatoria.
Para acelerar os nosos cálculos, usaremos NumPy ou np (por convención, moitas veces é importado como np). As nosas dúas funcións auxiliares realizaranse despois das nosas importacións. Dúas funcións sigmoides: unha e sigmoides primo.
A regresión loxística clasificará os datos mediante a función sigmoide, mentres que a retropropagación calculará o delta ou gradiente mediante a función prima sigmoide.
Creando clase de rede
Construír unha rede neuronal totalmente ligada é o único foco desta sección. A clase de rede abarcará todas as funcións que veñen despois. A función Object() { [código nativo] } crearase inicialmente na nosa clase de rede.
A función Object() { [código nativo] } require un argumento, tamaños. A variable tamaños é unha colección de valores numéricos que representa o número de nodos de entrada presentes en cada capa da nosa rede neuronal.
Inicializamos catro propiedades no noso método __init__. As variables de entrada, tamaños, úsanse para establecer a lista de tamaños de capa e o número de capas, num capas, respectivamente.
O primeiro paso é asignar aleatoriamente os prexuízos iniciais da nosa rede a cada capa que segue á capa de entrada.
Finalmente, cada enlace entre as capas de entrada e saída ten os seus pesos xerados aleatoriamente. Np.Random.Randn() dá unha mostra aleatoria extraída da distribución normal para o contexto.
Función Feed Forward
Nunha rede neuronal, a información envíase a través da función de avance. Esta función requirirá un argumento, a, que indica o vector de activación actual.
Esta función estima as activacións en cada capa iterando todos os sesgos e pesos da rede. A resposta dada é a predición, que son as activacións da última capa.
Descenso de gradiente de mini-lote
O cabalo de batalla da nosa clase de Rede é o Descenso de Gradientes. Nesta versión, usamos o descenso do gradiente de mini-lote (estocástico), unha variación modificada do descenso do gradiente.
Isto indica que se utilizará un pequeno lote de puntos de datos para actualizar o noso modelo. A este método pásanse catro argumentos obrigatorios e un opcional. As catro variables necesarias son o conxunto de datos de adestramento, o número de épocas, o tamaño dos mini-lotes e a taxa de aprendizaxe (eta).
Os datos das probas están dispoñibles previa solicitude. Forneceremos datos de proba cando avaliemos esta rede. O número de mostras nesta función establécese inicialmente na lonxitude da lista unha vez que os datos de adestramento se transformaron nun tipo de lista.
Tamén aplicamos o mesmo proceso para probar os datos que se dan. Isto débese a que, en lugar de devolvernos como listas, son realmente listas. Cando carguemos as mostras de datos MNIST máis tarde, aprenderemos máis sobre isto.
Se podemos asegurarnos de que proporcionamos ambos tipos de datos como listas, entón este tipo de emisión non é necesariamente esencial.
Unha vez que temos os datos, repasamos en bucle as épocas de adestramento. Un período de adestramento é só unha rolda de adestramento en redes neuronais. Primeiro barallamos os datos en cada época para garantir a aleatoriedade antes de facer unha lista de mini-lotes.
A función de actualización do mini-lote, que se comenta a continuación, chamarase para cada mini-lote. Tamén se devolverá a precisión da proba se os datos da proba están dispoñibles.
Función auxiliar derivada de custos
Desenvolvemos unha función auxiliar chamada derivada de custos antes de crear realmente o código de retropropagación. Se cometemos un erro na nosa capa de saída, a función de derivada de custos amosarao.
Require dúas entradas: a matriz de activacións de saída e as coordenadas y dos valores de saída previstos.
Función de retropropagación
O noso vector de activación actual, a activación, así como calquera outro vector de activación, activación e vector z, zs, debe terse en conta. Primeiro actívase unha capa chamada capa de entrada.
Repasaremos cada sesgo e peso despois de colocalos. Cada bucle implica calcular o vector z como produto escalar dos pesos e da activación, engadilo á lista de zs, recalcular a activación e engadir a activación actualizada á lista de activacións.
Por último, as matemáticas. O delta, que é igual ao erro da capa anterior multiplicado polo primo sigmoide do último elemento dos vectores zs, calcúlase antes de comezar o noso paso atrás.
A última capa de nabla b está configurada para ser o delta, e a capa final de nabla w está configurada para ser o produto puntual do delta e a penúltima capa de activacións (transposta para que poidamos facer as matemáticas) .
Procedemos como antes, comezando pola segunda capa e rematando coa última, e repetimos o proceso despois de completar estas últimas capas. As nablas son entón devoltos como unha tupla.
Actualizando descenso de gradiente de mini-lote
O noso método SGD (descenso de gradiente estocástico) de antes incorpora a actualización de mini-lote. Dado que se utiliza en SGD pero tamén require backprop, discutín onde poñer esta función.
Finalmente, optei por publicalo aquí. Comeza xerando 0 vectores das nablas dos sesgos e dos pesos, tal e como fixo a nosa función backprop.
Require o mini-lote e a taxa de aprendizaxe eta como as súas dúas entradas. No mini-lote, entón usamos a función backprop para obter o delta de cada matriz nabla para cada entrada, x, e saída, y. A continuación, as listas de nabla actualízanse con estes deltas.
Finalmente, utilizamos a taxa de aprendizaxe e as nablas para actualizar os pesos e prexuízos da rede. Cada valor actualízase ao valor máis recente, menos a taxa de aprendizaxe, multiplicado polo tamaño do minilote e, a continuación, engádese ao valor nabla.
Avaliar a función
A función de avaliar é a última que necesitamos escribir. Os datos de proba son a única entrada para esta función. Nesta función, só comparamos as saídas da rede co resultado previsto, y. Ao alimentar a entrada, x, determínanse as saídas da rede.
Código completo
Cando combinamos todo o código, así aparece.
Proba da rede neuronal
Cargando datos MNIST
o Datos do MNIST está en formato .pkl.gz, que abriremos usando GZIP e cargaremos con pickle. Escribamos un método rápido para cargar estes datos como unha tupla de tamaño tres, dividida en datos de adestramento, validación e proba.
Para facilitar a xestión dos nosos datos, escribiremos outra función para codificar o y nunha matriz de 10 elementos. A matriz será todos 0 excepto un 1 que coincida co díxito correcto da imaxe.
Usaremos os datos de carga básicos e un método de codificación en quente para cargar os nosos datos nun formato lexible. Escribirase outra función que converterá os nosos valores x nunha lista de tamaño 784, que coincida cos 784 píxeles da imaxe, e os nosos valores y na súa única forma vectorial codificada en quente.
Despois combinaremos os valores x e y de forma que un índice coincida co outro. Isto aplícase aos conxuntos de datos de adestramento, validación e proba. Despois devolvemos os datos modificados.
Probas de execución
Crearemos un novo ficheiro chamado "cargador mnist" que importará tanto a rede neuronal que establecemos anteriormente (nn simple) como o cargador de conxunto de datos MNIST antes de comezar a probar.
Neste ficheiro, todo o que temos que facer é importar os datos, construír unha rede cun tamaño de capa de entrada de 784 e un tamaño de capa de saída de 10, executar a función SGD da rede nos datos de adestramento e, a continuación, probalo usando os datos de proba.
Teña en conta que para a nosa lista de capas de entrada, non importa cales son os números entre 784 e 10. Podemos cambiar as outras capas como queiramos; só os tamaños de entrada e saída son fixos.
Non son necesarias tres capas; podemos usar catro, cinco ou incluso só dous. Divírtete experimentando con el.
Conclusión
Aquí, usando Python 3, creamos unha rede neuronal desde cero. Xunto coas matemáticas de alto nivel, tamén falamos dos aspectos específicos da implementación.
Comezamos implementando funcións auxiliares. Para que as neuronas funcionen, as funcións primas sigmoides e sigmoides son cruciais. Despois poñemos en práctica a función feedforward, que é o proceso fundamental para alimentar os datos á rede neuronal.
A continuación, creamos a función de descenso de gradiente en Python, o motor que impulsa a nosa rede neuronal. Para localizar os "mínimos locais" e optimizar os seus pesos e prexuízos, a nosa rede neuronal utiliza o descenso de gradientes. Creamos a función de retropropagación usando descenso en gradiente.
Ao ofrecer actualizacións cando as saídas non coinciden coas etiquetas adecuadas, esta función permite que a rede neuronal "aprenda".
Finalmente, poñemos o noso novo Python rede neural para a proba usando o conxunto de datos MNIST. Todo funcionou sen problemas.
Feliz Codificación!
Deixe unha resposta