Prefacio
En el aprendizaje automático, las redes neuronales convolucionales son redes neuronales artificiales de avance profundas que se han aplicado con éxito al reconocimiento de imágenes. En la actualidad, muchos reconocimientos de números de matrícula, reconocimiento facial, etc. usan redes neuronales convolucionales. Se puede decir que las redes neuronales convolucionales han logrado un gran éxito en el reconocimiento de imágenes. Existen muchos marcos de aprendizaje profundo de código abierto, como Caffe, TensorFlow, Torch, etc. Estos marcos de aprendizaje profundo incluyen la implementación de redes neuronales convolucionales completas. Entonces, ¿por qué todavía tenemos que escribir redes neuronales convolucionales nosotros mismos? Es mejor usar estos marcos de aprendizaje profundo de código abierto directamente, que son rápidos y fáciles de tratar, tienen un buen rendimiento y pocos errores. Sí, si solo usa redes neuronales convolucionales para hacer algunas aplicaciones y no les importa su principio de trabajo, entonces no tiene que trabajar duro para escribir redes neuronales convolucionales. Pero si desea dominar completamente el principio de funcionamiento de las redes neuronales convolucionales, los antiguos dijeron: lo que obtiene en el papel siempre es superficial y debe practicar la conciencia en este momento. Por lo tanto, es muy necesario que implementa la red neuronal convolucional usted mismo para profundizar su comprensión de ella.
¿Qué es Cupcnn?
Cupcnn es una red neuronal convolucional escrita en Java. Además del trabajo, me di cuenta para profundizar mi comprensión de las redes neuronales convolucionales. Es bastante simple y funciona bien, lo que hace que sea muy adecuado para los principiantes a los que se refieren. Su código fuente se puede descargar desde GitHub: Cupcnn
No tiene que preocuparse por las limitaciones de su protocolo o algo así. Puede usarlo para hacer cualquier cosa y modificarlo arbitrariamente. Si puede ayudarte, ¡espero que pueda darte una estrella! ! !
^-^^-^^-^^-^
Ideas de diseño
Espero que sea una red neuronal que sea lo suficientemente simple como para ayudar a los principiantes a aprender. Así que no implementé esas cosas de aceleración concurrente, lo que garantiza la naturaleza introductoria del código. Al diseñar, dividí la red neuronal convolucional en cuatro módulos: red (pérdida de blob de capa activa), que se puede ver desde el nombre del paquete. La capa, la pérdida y el activo tienen una clase base, y la programación de toda la red neuronal está orientada hacia la clase base. La red es el centro que integra estos cuatro módulos, coordenadas y despacha recursos. Cada capa tendrá una instancia de la red, para que se puedan obtener fácilmente varios datos a través de la red, como obtener la salida de cada capa, diff, etc.
El diagrama de bloques de diseño es el siguiente:
Guardar parámetros es muy simple para Java. La implementación de la interfaz serializable puede implementar rápidamente la serialización y la deserialización de los parámetros. Cupcnn solo implementa la interfaz serializable para blob y blobparams en el directorio de datos, y todos los parámetros son implementados por estos dos.
Rendimiento actual
Red neuronal totalmente conectada
Actualmente, en el conjunto de datos MNIST, una red neuronal totalmente conectada (conexión completa (100) + conexión completa (30) + conexión completa (10) + Softmax) está entrenada con 30 ePOE, con una tasa de precisión de 96.76
Red neuronal convolucional
Red neuronal convolucional (6 características) + agrupación máxima + convolución (6 características) + conexión completa (512) + conexión completa (30) + conexión completa (10) + softmax), cuando la tasa de aprendizaje es 0.2, 30 EPOE están entrenados, la tasa de precisión es 97.79. Creo que después de un ajuste adicional de los parámetros, la tasa de precisión puede ser más alta bajo capacitación suficiente.
La instantánea de entrenamiento de la red neuronal convolucional es la siguiente:
comenzar el tren
EPOE: 0 Lossvalue: 2.3019369891560455 LR: 0.2 La precisión es 0.13
EPOE: 0 Lossvalue: 2.0722489482105195 LR: 0.2 La precisión es 0.44
EPOE: 0 Lossvalue: 1.2423286194012682 LR: 0.2 La precisión es 0.72
EPOE: 0 Lossvalue: 0.7860529560675255 LR: 0.2 La precisión es 0.79
EPOE: 0 FIELSVALUE: 0.6272194196176664 LR: 0.2 La precisión es 0.87
EPOE: 0 Lossvalue: 0.5240051326725808 LR: 0.2 La precisión es 0.84
EPOE: 0 FIELSVALUE: 0.27637563581928026 LR: 0.2 La precisión es 0.95
EPOE: 0 PIELSVALUE: 0.35585388987055083 LR: 0.2 La precisión es 0.92
EPOE: 0 Pierde Value: 0.441971528417802 LR: 0.2 La precisión es 0.92
EPOE: 0 Pierde Value: 0.25637710325999674 LR: 0.2 La precisión es 0.95
EPOE: 0 Lossvalue: 0.39872273532502 LR: 0.2 La precisión es 0.9
EPOE: 1 Value de pérdida: 0.264085484522027 LR: 0.1600000000000000000033 La precisión es 0.91
EPOE: 1 Value de pérdida: 0.22754066024803088 LR: 0.16000000000000000000003 La precisión es 0.96
EPOE: 1 Value de pérdida: 0.30256420975577103 LR: 0.1600000000000000000033 La precisión es 0.96
EPOE: 1 Value de pérdida: 0.18149648622985948 LR: 0.1600000000000000000003 La precisión es 0.99
EPOE: 1 Value de pérdida: 0.177239938748327 LR: 0.16000000000000000000003 La precisión es 0.96
EPOE: 1 Value de pérdida: 0.15041993009777443 LR: 0.16000000000000000000003 La precisión es 0.98
EPOE: 1 Value de pérdida: 0.10759545752665524 LR: 0.160000000000000000000003 La precisión es 1.0
El uso de Cupcnn
En la actualidad, Cupcnn implementa pruebas en el conjunto de datos MNIST. Bajo SRC/Test, MnistTest es la entrada a la función principal, y la red neuronal específica está construida en la clase MnistNetwork. En la clase MNISTNETWORK, BuildConvNetwork y BuildFCnetwork implementan respectivamente la construcción de redes neuronales convolucionales y la construcción de redes neuronales totalmente conectadas. Gracias a las buenas propiedades multiplataforma de Java, después de descargar el código fuente de Cupcnn, use Eclipse para abrir el proyecto y luego ejecutarlo directamente, debería poder comenzar a entrenar y probar en el conjunto de datos MNIST.
Construyendo una red neuronal
public void buildnetwork () {// Primero cree el objeto de red neuronal y establezca la red de parámetros = new Network (); Network.SetBatch (100); Network.SetLoss (New LoglikehoodLoss ()); //network.setloss(New CrossEnentROpyLoss ()); optimizador = nuevo SGDoptimizer (0.2); Network.SetOptimizer (Optimizer); // buildfcnetwork (); buildConvNetwork (); network.prepare (); } La función setBatch () establece cuántas imágenes hay en un lote.
setloss () Establece la función de pérdida para usar. Cupcnn implementa la función de pérdida de entropía cruzada y la función de pérdida de veracilización log.
SetOptimizer () debe usarse para establecer el optimizador. Cupcnn solo implementa el optimizador SGD. Si implementa un mejor optimizador y está dispuesto a enviarlo a Cupcnn, me gustaría darle la bienvenida profundamente.
Construir una red neuronal totalmente conectada
Private void buildfcnetwork () {// Agregar capa de red a la capa inputLayer de red1 = new InputLayer (Network, New BlobParams (network.getBatch (), 1,28,28)); Network.Addlayer (Layer1); FullConnectionLayer Layer2 = new FullConnectionLayer (Network, New BlobParams (network.getBatch (), 784,1,1)); Layer2.SetActivationFunc (New RELUACTIVATIONFUNC ()); Network.Addlayer (Layer2); FullConnectionLayer Layer3 = new FullConnectionLayer (Network, New BlobParams (Network.GetBatch (), 100,1,1)); capa3.SetActivationFunc (nueva reanactivaciónfunc ()); Network.Addlayer (Layer3); FullConnectionLayer Layer4 = new FullConnectionLayer (Network, New BlobParams (network.getBatch (), 30,1,1)); Layer4.SetActivationFunc (New SigModActivationFunc ()); Network.Addlayer (Layer4); FullConnectionLayer Layer5 = new FullConnectionLayer (Network, New BlobParams (Network.GetBatch (), 10,1,1)); capa5.SetActivationFunc (nueva reanactivaciónfunc ()); Network.Addlayer (Layer5); Softmaxlayer sflayer = new SoftMaxLayer (red, new BlobParams (network.getBatch (), 10,1,1)); Network.Addlayer (Sflayer); }Como se muestra en el código anterior, cada capa necesita una red, que es una instancia de la red. La red es el administrador global y el despachador de recursos. Con la referencia de la red, podemos obtener fácilmente los datos de salida, los errores de salida, etc. de cada capa. Además, cada capa necesita un parámetro que especifique el tamaño del bloque de datos de salida de la capa actual, lo que le dice a una determinada capa cuántos datos necesita emitir. Por ejemplo, la última capa de una red neuronal es Softmaxlayer, cuyo número debe ser emitido. Este número está representado por un vector de longitud 10, como el número 7, por lo que SoftMaxLayer debería generar el valor del octavo elemento para ser 1 y el valor de otros elementos para ser 0. La capa de convolución y la capa de agrupación requieren más parámetros porque ambos tienen un núcleo. Para la capa de convolución, se llama un núcleo de convolución. El paso de cada dirección de la capa de convolución es 1, que todavía está margen de mejora. Para la capa de agrupación, además de pasar los parámetros del núcleo de agrupación, también debe pasar a los escalones horizontales y verticales, lo cual es necesario.
Entrenamiento y prueba
Después de construir una red neuronal, debe llamar al método network.prepare (), que creará bloques de datos de salida y bloques de datos de error en función de los parámetros de datos de cada capa. Por lo tanto, la llamada a este método es necesaria.
Public void Train (List <DigitImage> imglist, int epoes) {System.out.println ("Begin Train"); int batch = network.getBatch (); doble loclalr = optimizador.getlr (); para (int e = 0; e <epoes; e ++) {colección.shuffle (imglist); for (int i = 0; i <imglist.size ()-lotes; i+= lote) {list <Lub> inputandLabel = buildBlObByImageList (imglist, i, lote, 1,28,28); Double LossValue = network.train (inputandLabel.get (0), inputandLabel.get (1)); if (i> batch && i/batch%50 == 0) {system.out.print ("epoe:"+e+"LossValue:"+LossValue+""+"lr:"+optimiz.getlr ()+""); testInner (inputandLabel.get (0), inputandLabel.get (1)); }} if (loclalr> 0.001) {loclalr*= 0.8; Optimizer.setLr (loclalr); }}} Public void test (list <digitImage> imglist) {system.out.println ("comenzar prueba"); int batch = network.getBatch (); int correctCount = 0; int i = 0; para (i = 0; i <imglist.size ()-lotes; i+= lote) {List <Lob> inputandLabel = buildBlObByImageList (imglist, i, lote, 1,28,28); Blob outple = network.predict (inputandLabel.get (0)); int [] calOutLabels = getBatchOutputLabel (output.getData ()); int [] realLabels = getBatchOutputLabel (inputandLabel.get (1) .getData ()); for (int kk = 0; kk <calOutLabels.length; kk ++) {if (calOutLabels [kk] == reaslabels [kk]) {correcto ++; }}} doble precisión = correctCount/(1.0*i+lote); System.out.println ("La precisión de la prueba es"+precisión+"correctCount"+correctCount); }Como se mencionó anteriormente, puede entrenar llamando al tren de la red, y puede probar llamando al método de predicción de la red.
Guardar y cargar parámetros
public void saveModel (nombre de cadena) {network.savemodel (nombre); } public void loadModel (nombre de cadena) {network = new Network (); Network.LoadModel (nombre); network.prepare (); }Llamar al savemodel y loadmodel de la red puede guardar y cargar parámetros respectivamente. Solo necesita pasar un nombre de archivo. Cuando creamos una red neuronal a través de parámetros guardados, primero necesitamos una nueva red, luego llamar al Modelo de carga de esta red para cargar los parámetros guardados y luego no olvidar llamar al método de preparación para crear bloques de datos de salida y bloques de datos de error para cada capa.
Estado de finalización actual y planes futuros
Actualmente, las capas implementadas incluyen: conexión completa, convolución, capa de agrupación máxima, capa de agrupación promedio y capa Softmax. Las funciones de activación implementadas son: Sigmod, Tanh, Relu.
Las funciones de pérdida implementadas son: entropía cruzada, probabilidad log. La optimización implementada es: SGD. Los parámetros ya pueden guardar y cargar. A continuación, se agregará la capa de deserción y se agregarán los ejemplos en CIFAR-10.
Además, escribiré algunos artículos para revisar mis pensamientos y preguntas durante el proceso de escritura de Cupcnn para que los principiantes sean referentes. Por favor, tome un desvío. Los interesados pueden continuar prestando atención. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.