Exemplo n.º 1
0
        /// <summary>
        /// Lee la descripción del modelo RNC contenida dentro de un archivo .txt (arquitectura y pesos) (Aún no totalmente automatizado, ya que se deben considerar como parámetros algunos campos que deberían estar en el archivo)
        /// </summary>
        /// <param name="FilePath">Ruta absoluta del archivo (con el nombre y extensión)</param>
        /// <param name="imgSizeIn">Tamaño de las imágenes en la que el modelo fue entrenado</param>
        /// <param name="imgDimenIn">Dimensión de las imágenes en la que el modelo fue entrenado</param>
        /// <param name="totalClases">Número de clases para las que el modelo fue entrenado</param>
        /// <param name="CNN">La sección convolutiva del modelo leído</param>
        /// <param name="NN">La sección neuronal del modelo leído</param>
        /// <param name="kValues">Vector con los valores de pesos convolutivos del modelo leído</param>
        /// <param name="nValues">Vector con los valores de pesos neuronales del modelo leído</param>
        public static void ReadConvolutionalNeuralNetworkModel(string FilePath, int imgSizeIn, int imgDimenIn, int totalClases, out ConvolutionNetwork CNN, out NeuralNetwork NN, out double[] kValues, out double[] nValues)
        {
            var F = File.OpenRead(FilePath);

            // Read file using StreamReader. Reads file line by line
            using (StreamReader file = new StreamReader(F))
            {
                string           ln;
                List <ConvLayer> convLayers   = new List <ConvLayer>();
                List <double>    kernelValues = new List <double>();
                List <int>       neuralLayers = new List <int>();
                List <double>    neuralValues = new List <double>();
                while ((ln = file.ReadLine()) != null)
                {
                    if (ln.Equals(CONVOLUTION))
                    {
                        //Es la sección convolutiva
                        while (ln != null && !ln.Equals(FULLY))
                        {
                            if (ln.StartsWith($"//Capa convolucional"))
                            {
                                //Es el inicio de una capa convolutiva
                                //Obtener los valores
                                ln = file.ReadLine();
                                string[] valsConv = ln.Split(';');
                                int      totalK   = Convert.ToInt32(valsConv[0]);
                                int      sizeK    = Convert.ToInt32(valsConv[1]);
                                int      strideK  = Convert.ToInt32(valsConv[2]);
                                int      paddingK = Convert.ToInt32(valsConv[3]);
                                int      sizeP    = Convert.ToInt32(valsConv[4]);
                                int      strideP  = Convert.ToInt32(valsConv[5]);
                                //Crear la capa
                                convLayers.Add(new ConvLayer(totalK, sizeK, strideK, paddingK, sizeP, strideP));
                                while ((ln = file.ReadLine()) != null && !ln.StartsWith($"//Capa convolucional") && !ln.Equals(FULLY))
                                {
                                    //Armar una lista con los valores obtenidos
                                    if (!ln.StartsWith(@"//") && ln.Contains(','))
                                    {
                                        string[] vals = ln.Split(',');
                                        for (int ixv = 0; ixv < vals.Length; ixv++)
                                        {
                                            double v = Convert.ToDouble(vals[ixv]);
                                            kernelValues.Add(v);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                ln = file.ReadLine();
                            }
                        }
                    }
                    if (ln.Equals(FULLY))
                    {
                        ln = file.ReadLine();
                        if (ln.StartsWith(';'))
                        {
                            ln = Regex.Replace(ln, @"^;", "");
                        }
                        string[] valsNeural = ln.Split(';');
                        for (int ixN = 0; ixN < valsNeural.Length; ixN++)
                        {
                            //Almacenar el número de neuronas por capa
                            neuralLayers.Add(Convert.ToInt32(valsNeural[ixN]));
                        }
                        //Cada línea a partir de la siguiente que se lea son los valores aprendidos de los pesos por cada una de las capas
                        while ((ln = file.ReadLine()) != null)
                        {
                            if (!ln.StartsWith(@"//"))
                            {
                                ln = ln.Substring(ln.IndexOf('_') + 1);
                                string[] valsn = ln.Split(';');
                                for (int ixvn = 0; ixvn < valsn.Length; ixvn++)
                                {
                                    neuralValues.Add(Convert.ToDouble(valsn[ixvn]));
                                }
                            }
                        }
                    }
                }
                file.Close();
                ConvLayer[] l = convLayers.ToArray();
                CNN = new ConvolutionNetwork();
                int iso, ido;
                int totalKernelValues = CNN.Build(l, imgSizeIn, imgDimenIn, out iso, out ido);
                NN = new NeuralNetwork();
                int[] NNLayers = neuralLayers.ToArray(); //{ (iso * iso * ido), 100, 70, totalClases };
                NeuralNetwork.ErrorMethod errorMethod = NeuralNetwork.ErrorMethod.MeanSquaredError;
                int totalWeigthsValues = NN.Build(NNLayers, PropagationRule.Lineal, ActivationFunction.Hiperbolic, OutputFunction.Lineal,
                                                  PropagationRule.Lineal, ActivationFunction.Hiperbolic, OutputFunction.Lineal, errorMethod);
                kValues = kernelValues.ToArray();
                nValues = neuralValues.ToArray();
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Escribe un modelo RNC en un archivo .txt (arquitectura y pesos) con un formato particular (Aún no totalmente automatizado, pues faltan de incluir ciertos parámetros dentro de la estructura del archivo)
        /// </summary>
        /// <param name="CNNModel">Sección convolutiva del modelo</param>
        /// <param name="NNModel">Sección neuronal del modelo</param>
        /// <param name="FilePath">Ruta de la carpeta donde se almacenará el modelo</param>
        /// <param name="Name">Nombre del archivo (sin extensión)</param>
        /// <param name="Observations">Texto que se incorporará al inicio del archivo a modo de comentario</param>
        public static void WriteConvolutionalNeuralNetworkModel(ConvolutionNetwork CNNModel, NeuralNetwork NNModel, string FilePath, string Name, string Observations)
        {
            //FALTA QUE GUARDE EL TAMAÑO Y DIMENSIÓN EN LA QUE FUE ENTRENADA, ADEMÁS DEL NÚMERO DE CLASES QUE RECONOCE (ACTUALMENTE DEBE SER ESPECIFICADO AL LEER)
            //Escribir en un archivo txt la arquitectura del modelo, al igual que los pesos utilizados
            string fp = Path.Combine(FilePath, Name);
            //Si existe previamente un archivo como Modelo_A.txt, colocarlo en Modelo_A(1).txt
            int fileCount = -1;

            do
            {
                fileCount++;
            }while (File.Exists(fp + (fileCount > 0 ? "(" + fileCount.ToString() + ").txt" : ".txt")));
            var F = File.Create(fp + (fileCount > 0 ? "(" + (fileCount).ToString() + ").txt" : ".txt"));

            using (var W = new StreamWriter(F))
            {
                W.WriteLine("//" + Observations);
                //Escribir la arquitectura Convolucional (Número de Capas - Número de Kernels, Tamaño de Kernels, Stride, Padding, Tamaño Pooling, Stride Pooling)
                ConvLayer[] convLayers = CNNModel.GetLayers();
                //Por cada una de las capas convolucionales
                W.WriteLine(CONVOLUTION);
                for (int ixC = 0; ixC < convLayers.Length; ixC++)
                {
                    W.WriteLine($@"//Capa convolucional {ixC}");
                    W.WriteLine($"{convLayers[ixC].GetTotalKernels()};{convLayers[ixC].GetKernelSize()};{convLayers[ixC].GetKernelStride()};{convLayers[ixC].GetPadding()};{convLayers[ixC].GetPoolingSize()};{convLayers[ixC].GetPoolingStride()}");
                    //Escribir los valores de kernels - [Número de Kernel][Dimensión][Fila][Columna]
                    double[][][][] kernelValues = convLayers[ixC].GetKernelValues();
                    //Por cada uno de los Kernels
                    for (int ixK = 0; ixK < kernelValues.Length; ixK++)
                    {
                        W.WriteLine($@"//Kernel {ixK}");
                        W.WriteLine(KERNEL);
                        //Por cada una de las dimensiones
                        for (int ixD = 0; ixD < kernelValues[ixK].Length; ixD++)
                        {
                            W.WriteLine($@"//Dimension {ixD}");
                            string vals = "";
                            //Por cada una de las filas
                            for (int ixRow = 0; ixRow < kernelValues[ixK][ixD].Length; ixRow++)
                            {
                                //Por cada una de las columnas
                                for (int ixCol = 0; ixCol < kernelValues[ixK][ixD][ixRow].Length; ixCol++)
                                {
                                    //Escribir valor por valor
                                    vals += $"{kernelValues[ixK][ixD][ixRow][ixCol]},";
                                }
                            }
                            if (vals.Length > 0)
                            {
                                vals = vals.Remove(vals.Length - 1);
                            }
                            W.WriteLine(vals);
                        }
                    }
                }
                //Escribir la arquitectura Neuronal (Número de Capas, Cantidad de Neuronas por capa, Función de propagación, función de activación, función de salida, método de error)
                W.WriteLine(FULLY);
                string   archNN = ";";
                string[] values = new string[NNModel.NetLayers.Length];
                //Por cada una de las capas
                for (int ixL = 0; ixL < NNModel.NetLayers.Length; ixL++)
                {
                    archNN += NNModel.NetLayers[ixL].Neurons.Length + ";";
                    //if (ixL == 0)
                    //    values[ixL] = $"{NNModel.NetLayers[ixL].WeightedConnections}";
                    //else
                    if (ixL > 0)
                    {
                        values[ixL] = $"{NNModel.NetLayers[ixL].WeightedConnections}_";
                        //Añadir los valores de pesos
                        //Por cada una de las neuronas de la capa
                        for (int ixN = 0; ixN < NNModel.NetLayers[ixL].Neurons.Length; ixN++)
                        {
                            //Por cada una de sus entradas, obtener el peso que tiene actualmente
                            for (int ixIn = 0; ixIn < NNModel.NetLayers[ixL].Neurons[ixN].Inputs.Length; ixIn++)
                            {
                                //Y escribirlo
                                values[ixL] += NNModel.NetLayers[ixL].Neurons[ixN].Inputs[ixIn].Weight + ";";
                            }
                        }
                    }
                }
                archNN = archNN.Remove(archNN.Length - 1);
                W.WriteLine(archNN);
                W.WriteLine($@"//LA CAPA 0 (LA DE ENTRADA) NO SE INCLUYE, POR LO QUE LOS SIGUIENTES VALORES SON DE LA CAPA 1 EN ADELANTE");
                for (int ixV = 1; ixV < values.Length; ixV++)
                {
                    W.WriteLine(values[ixV].Remove(values[ixV].Length - 1));
                }
            }
        }