Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

gnn_cross_entropy.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *  @file gnn_cross_entropy.c
00003  *  @brief Cross Entropy Error Criterion.
00004  *
00005  *  @date   : 25-08-03 23:20
00006  *  @author : Pedro Ortega C. <peortega@dcc.uchile.cl>
00007  *  Copyright  2003  Pedro Ortega C.
00008  ****************************************************************************/
00009 /*
00010  *  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  You should have received a copy of the GNU General Public License
00021  *  along with this program; if not, write to the Free Software
00022  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00023  */
00024 
00025 /**
00026  * @brief Cross Entropy Error function.
00027  * @defgroup gnn_cross_entropy_doc gnn_cross_entropy : Cross-Entropy Error Criterion.
00028  * @ingroup gnn_criterion_doc
00029  *
00030  * This datatype implements the Cross-Entropy criterion, given by
00031  * \f[ E(y,t) =
00032        - \sum_i^m \left (
00033                   t_i \ln y_i + (1 - t_i) \ln (1 - y_i)
00034                   \right )
00035    \f]
00036  * As it can be easily seen, the cross entropy cost function depends on the
00037  * relative error (instead of the absolute error like in MSE), thus giving
00038  * to small and large errors te same weight.
00039  *
00040  * The cross entropy criterion fits well in classification problems, where
00041  * the output encodes the class using binary values; that is, where
00042  * \f$y_c = 1\f$ and \f$y_i = 0\f$ for all \f$i \neq c\f$ if the input
00043  * \f$x\f$ corresponds to the \f$c\f$-th class.
00044  *
00045  */
00046 
00047 
00048 
00049 /******************************************/
00050 /* Include Files                          */
00051 /******************************************/
00052 
00053 #include <math.h>
00054 #include "gnn_cross_entropy.h"
00055 
00056 
00057 
00058 /******************************************/
00059 /* Static Declaration                     */
00060 /******************************************/
00061 
00062 typedef gnn_criterion gnn_cross_entropy;
00063 
00064 double
00065 gnn_cross_entropy_e (gnn_criterion *crit,
00066                      const gsl_vector *y,
00067                      const gsl_vector *t);
00068 
00069 int
00070 gnn_cross_entropy_dy (gnn_criterion *crit,
00071                       const gsl_vector *y,
00072                       const gsl_vector *t,
00073                       gsl_vector * dy);
00074 
00075 
00076 
00077 /******************************************/
00078 /* Static Implementation                  */
00079 /******************************************/
00080 
00081 /**
00082  * @brief The evaluation function.
00083  * @ingroup gnn_cross_entropy_doc
00084  *
00085  * This function corresponds to the evaluation of the cross entropy criterion.
00086  *
00087  * @param  crit A pointer to a \ref gnn_cross_entropy criterion.
00088  * @param  y    A pointer to an estimation vector \f$y\f$.
00089  * @param  t    A pointer to the desired target vector \f$t\f$.
00090  * @return A real number corresponding to the value of the criterion.
00091  */
00092 double
00093 gnn_cross_entropy_e (gnn_criterion *crit,
00094                      const gsl_vector *y,
00095                      const gsl_vector *t)
00096 {
00097     int i;
00098     double E;
00099 
00100     assert (crit != NULL);
00101     assert (y != NULL);
00102     assert (t != NULL);
00103 
00104     /* check sizes */
00105     if (y->size != t->size)
00106         GSL_ERROR_VAL ("vector sizes should be the same", GSL_EINVAL, 0.0);
00107 
00108     /* compute error */
00109     E = 0.0;
00110     for (i=0; i<y->size; ++i)
00111     {
00112         double yi;
00113         double ti;
00114         double ei;
00115 
00116         yi = gsl_vector_get (y, i);
00117         ti = gsl_vector_get (t, i);
00118 
00119         ei  = (yi < GNN_CROSS_ENTROPY_EPS)?
00120                 ti * log (GNN_CROSS_ENTROPY_EPS)
00121               : ti * log (yi);
00122               
00123         ei += (1.0 - yi < GNN_CROSS_ENTROPY_EPS)?
00124                 (1.0 - ti) * log (1.0 - GNN_CROSS_ENTROPY_EPS)
00125               : (1.0 - ti) * log (1.0 - yi);
00126 
00127         E -= ei;
00128     }
00129 
00130     return E;
00131 }
00132 
00133 /**
00134  * @brief The gradient evaluation function.
00135  * @ingroup gnn_cross_entropy_doc
00136  *
00137  * This function implements the \ref gnn_cross_entropy criterion's gradient
00138  * evaluation function given by
00139  *
00140  * \f[ \frac{\partial E}{\partial y_i} =
00141        - \frac{y_i - t_i}{y_i (1 - y_i)} \f]
00142  *
00143  * @param  crit A pointer to a \ref gnn_cross_entropy criterion.
00144  * @param  y    A pointer to an estimation vector \f$y\f$.
00145  * @param  t    A pointer to the desired target vector \f$t\f$.
00146  * @param  dy   A pointer to a buffer vector where the result should be placed.
00147  * @return Returns 0 if succeeded.
00148  */
00149 int
00150 gnn_cross_entropy_dy (gnn_criterion *crit,
00151                       const gsl_vector *y,
00152                       const gsl_vector *t,
00153                       gsl_vector * dy)
00154 {
00155     int i;
00156 
00157     assert (crit != NULL);
00158     assert (y != NULL);
00159     assert (t != NULL);
00160     assert (dy != NULL);
00161 
00162     /* check sizes */
00163     if (y->size != t->size || y->size != dy->size)
00164         GSL_ERROR ("vector sizes should be the same", GSL_EINVAL);
00165 
00166     /* compute dy */
00167     for (i=0; i<y->size; ++i)
00168     {
00169         double yi;
00170         double ti;
00171         double dyi;
00172 
00173         yi  = gsl_vector_get (y, i);
00174         ti  = gsl_vector_get (t, i);
00175         dyi = gsl_vector_get (dy, i);
00176 
00177         yi  = (yi > 1.0 - GNN_CROSS_ENTROPY_EPS)?
00178                  (1.0 - GNN_CROSS_ENTROPY_EPS)
00179                : yi;
00180         yi  = (yi < GNN_CROSS_ENTROPY_EPS)?
00181                  GNN_CROSS_ENTROPY_EPS
00182                : yi;
00183 
00184         dyi += (yi - ti) / (yi * (1.0 - yi));
00185 
00186         gsl_vector_set (dy, i, dyi);
00187     }
00188 
00189     return 0;
00190 }
00191 
00192 
00193 /******************************************/
00194 /* Public Interface                       */
00195 /******************************************/
00196 
00197 /**
00198  * @brief Creates a new \ref gnn_cross_entropy criterion.
00199  * @ingroup gnn_cross_entropy_doc
00200  *
00201  * This function creates a new \ref gnn_cross_entropy criterion of the given
00202  * size.
00203  *
00204  * @param  size    The size of the estimation and the target vector \f$y\f$
00205  *                 and \f$t\f$.
00206  * @return Returns a pointer to a new \ref gnn_cross_entropy or NULL if failed.
00207  */
00208 gnn_criterion *
00209 gnn_cross_entropy_new (size_t size)
00210 {
00211     int status;
00212     gnn_criterion *crit;
00213 
00214     /* check size */
00215     if (size < 1)
00216         GSL_ERROR_VAL ("size should be strictly positive", GSL_EINVAL, NULL);
00217 
00218     /* alloc memory */
00219     crit = (gnn_criterion *) malloc (sizeof (*crit));
00220     if (crit == NULL)
00221         GSL_ERROR_VAL ("couldn't alloc memory for gnn_cross_entropy",
00222                        GSL_ENOMEM, NULL);
00223 
00224     /* initialize */
00225     status = gnn_criterion_init  (crit,
00226                                   "gnn_cross_entropy",
00227                                   size,
00228                                   gnn_cross_entropy_e,
00229                                   gnn_cross_entropy_dy,
00230                                   NULL);
00231     if (status)
00232     {
00233         gnn_criterion_destroy (crit);
00234         GSL_ERROR_VAL ("couldn't initialize gnn_cross_entropy",
00235                        GSL_EFAILED, NULL);
00236     }
00237 
00238     return crit;
00239 }
00240 
00241 
00242 

Generated on Sun Jun 13 20:50:11 2004 for libgnn Gradient Retropropagation Machine Library by doxygen1.2.18