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

gnn_logistic.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *  @file gnn_logistic.c
00003  *  @brief Logistic Sigmoid transfer function.
00004  *
00005  *  @date   : 10-08-03 01:09
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 
00027 /**
00028  * @defgroup gnn_logistic_doc gnn_logistic : Logistic Sigmoid Activation Function.
00029  * @ingroup gnn_atomic_doc
00030  *
00031  * The \ref gnn_logistic datatype implements a node that computes the function:
00032  * \f[ y_i = a \frac{1}{1 + \exp(-bx)} \f]
00033  * where \f$i = 1,\ldots,n\f$.
00034  *
00035  * This function is a member of the more general class of sigmoid functions,
00036  * which have the property to "squash" its inputs to a very restricted output
00037  * interval.
00038  *
00039  * The Logistic Sigmoid is assymmetric and its outputs lie between \f$[0,a]\f$.
00040  * It has been said that it leads to slower convergence in training than the
00041  * Hyperbolic Tangent.
00042  */
00043 
00044 
00045 
00046 /******************************************/
00047 /* Include Files                          */
00048 /******************************************/
00049 
00050 #include "gnn_logistic.h"
00051 #include <math.h>
00052 
00053 
00054 
00055 /******************************************/
00056 /* Macros and Definitions                 */
00057 /******************************************/
00058 
00059 #define GNN_LOGISTIC_A(node) (((gnn_logistic *)(node))->a)
00060 #define GNN_LOGISTIC_B(node) (((gnn_logistic *)(node))->b)
00061 
00062 
00063 
00064 /******************************************/
00065 /* Static Declaration                     */
00066 /******************************************/
00067 
00068 typedef struct _gnn_logistic
00069 {
00070     gnn_node node;
00071     double a;
00072     double b;
00073 } gnn_logistic;
00074 
00075 static int
00076 gnn_logistic_f (gnn_node *node,
00077                 const gsl_vector *x,
00078                 const gsl_vector *w,
00079                 gsl_vector *y);
00080 
00081 static int
00082 gnn_logistic_dx (gnn_node *node,
00083                  const gsl_vector *x,
00084                  const gsl_vector *w,
00085                  const gsl_vector *dy,
00086                  gsl_vector *dx);
00087 
00088 
00089 
00090 /******************************************/
00091 /* Static Implementation                  */
00092 /******************************************/
00093 
00094 /**
00095  * @brief Computes the output.
00096  * @ingroup gnn_logistic_doc
00097  *
00098  * This functions evaluates the logistic sigmoid function.
00099  *
00100  * @param node  A pointer to a \ref gnn_logistic node.
00101  * @param x The input vector \f$x\f$.
00102  * @param w The parameter vector \f$w\f$ (which is empty in this case).
00103  * @param y The output buffer vector \f$y\f$.
00104  * @return Returns 0 on success.
00105  */
00106 static int
00107 gnn_logistic_f (gnn_node *node,
00108                 const gsl_vector *x,
00109                 const gsl_vector *w,
00110                 gsl_vector *y)
00111 {
00112     size_t i;
00113     size_t size;
00114     double a;
00115     double b;
00116 
00117     /* get the size */
00118     size = gnn_node_input_get_size (node);
00119 
00120     /* get the parameters */
00121     a = GNN_LOGISTIC_A (node);
00122     b = GNN_LOGISTIC_B (node);
00123 
00124     /* evaluate */
00125     for (i=0; i<size; ++i)
00126     {
00127         double xi;
00128         double yi;
00129 
00130         xi = gsl_vector_get (x, i);
00131         yi = a * 1 / (1 + exp (- b * xi));
00132         gsl_vector_set (y, i, yi);
00133     }
00134 
00135     return 0;
00136 }
00137 
00138 /**
00139  * @brief Computes \f$ \frac{\partial E}{\partial X} \f$.
00140  * @ingroup gnn_logistic_doc
00141  *
00142  * This functions computes the gradient of the logistic sigmoid function,
00143  * given dedy (\f$ \frac{\partial E}{\partial Y} \f$). The function is,
00144  * \f[ \frac{\partial E}{\partial x_i}
00145  *     = ab \frac{ x_i e^{-bx_i} }{ \left ( 1 + e^{-bx_i} \right )^2 }
00146  *       \frac{\partial E}{\partial y_i}
00147  *     = b y_i \left ( 1 - \frac{y_i}{a} \right )
00148  *       \frac{\partial E}{\partial y_i}
00149  * \f]
00150  *
00151  * @param node  A pointer to a \ref gnn_logistic node.
00152  * @param x  The input vector \f$x\f$.
00153  * @param w  The parameter vector \f$w\f$ (which is empty in this case).
00154  * @param dy The vector \f$\frac{\partial E}{\partial y}\f$.
00155  * @param dx The output buffer vector \f$\frac{\partial E}{\partial x}\f$.
00156  * @return Returns 0 on success.
00157  */
00158 static int
00159 gnn_logistic_dx (gnn_node *node,
00160                  const gsl_vector *x,
00161                  const gsl_vector *w,
00162                  const gsl_vector *dy,
00163                  gsl_vector *dx)
00164 {
00165     size_t i;
00166     size_t size;
00167     double a;
00168     double b;
00169 
00170     /* get the size */
00171     size = gnn_node_input_get_size (node);
00172 
00173     /* get the parameters */
00174     a = GNN_LOGISTIC_A (node);
00175     b = GNN_LOGISTIC_B (node);
00176 
00177     /* evaluate */
00178     for (i=0; i<size; ++i)
00179     {
00180         double xi;
00181         double yi;
00182         double dxi;
00183         double dyi;
00184 
00185         xi  = gsl_vector_get (x, i);
00186         yi  = a * 1 / (1 + exp (- b * xi));
00187         dyi = gsl_vector_get (dy, i);
00188         dxi = b * yi * (1.0 - yi / a) * dyi;
00189 
00190         gsl_vector_set (dx, i, dxi);
00191     }
00192 
00193     return 0;
00194 }
00195 
00196 
00197 /******************************************/
00198 /* Public Interface                       */
00199 /******************************************/
00200 
00201 /**
00202  * @brief Creates a Logistic Sigmoid activation function node.
00203  * @ingroup gnn_logistic_doc
00204  *
00205  * This function creates a node of the \ref gnn_logistic type. This node
00206  * computes
00207  * \f[ y_i = a \frac{ 1 }{ 1 + e^{-b x_i} } \f]
00208  * where \f$i = 1, \ldots, n\f$, \f$a\f$ and \f$b\f$ constants.
00209  *
00210  * @param input_size The input size \f$n\f$.
00211  * @param a The \f$a\f$ factor.
00212  * @param b The \f$b\f$ factor.
00213  * @return A pointer to a new \ref gnn_logistic node.
00214  */
00215 gnn_node *
00216 gnn_logistic_new (int input_size, double a, double b)
00217 {
00218     int status;
00219     gnn_node *node;
00220 
00221     /* check if sizes are positive */
00222     if (input_size < 1)
00223     {
00224         GSL_ERROR_VAL ("input size should be stricly positive",
00225                        GSL_EINVAL, NULL);
00226     }
00227 
00228     /* allocate the node */
00229     node = (gnn_node *) malloc (sizeof (gnn_logistic));
00230     if (node == NULL)
00231     {
00232         GSL_ERROR_VAL ("could not allocate memory for gnn_logistic",
00233                        GSL_ENOMEM, NULL);
00234     }
00235     
00236     /* Initialize the node */
00237     status = gnn_node_init (node,
00238                             "gnn_logistic",
00239                             gnn_logistic_f,
00240                             gnn_logistic_dx,
00241                             NULL,
00242                             NULL);
00243     if (status)
00244     {
00245         GSL_ERROR_VAL ("could not initialize gnn_logistic node",
00246                        GSL_EFAILED, NULL);
00247     }
00248     
00249     status = gnn_node_set_sizes (node, input_size, input_size, 0);
00250     if (status)
00251     {
00252         GSL_ERROR_VAL ("could not set sizes for gnn_logistic node",
00253                        GSL_EFAILED, NULL);
00254     }
00255     /* set the constants */
00256     GNN_LOGISTIC_A (node) = a;
00257     GNN_LOGISTIC_B (node) = b;
00258 
00259     return node;
00260 }
00261 
00262 /**
00263  * @brief Creates a standard Logistic Sigmoid function node.
00264  * @ingroup gnn_logistic_doc
00265  *
00266  * This function creates a node of the \ref gnn_logistic type:
00267  * \f[ y_i = \frac { 1 } { 1 + e^{-x_i}} \f]
00268  * where \f$i = 1, \ldots, n\f$.
00269  *
00270  * @param input_size The input size \f$n\f$.
00271  * @return A pointer to a new \ref gnn_logistic node.
00272  */
00273 gnn_node *
00274 gnn_logistic_standard_new (int input_size)
00275 {
00276     return gnn_logistic_new (input_size, 1.0, 1.0);
00277 }
00278 
00279 /**
00280  * @brief Returns the amplitude constant \f$a\f$.
00281  * @ingroup gnn_logistic_doc
00282  *
00283  * @param node  A pointer to a \ref gnn_logistic node.
00284  * @return The amplitude \f$a\f$ of the sigmoid.
00285  */
00286 double
00287 gnn_logistic_get_a (gnn_node *node)
00288 {
00289     return GNN_LOGISTIC_A (node);
00290 }
00291 
00292 /**
00293  * @brief Sets the amplitude constant \f$a\f$.
00294  * @ingroup gnn_logistic_doc
00295  *
00296  * @param node  A pointer to a \ref gnn_logistic node.
00297  * @param a     The amplitude factor.
00298  */
00299 void
00300 gnn_logistic_set_a (gnn_node *node, double a)
00301 {
00302     GNN_LOGISTIC_A (node) = a;
00303 }
00304 
00305 /**
00306  * @brief Gets the streching factor \f$b\f$.
00307  * @ingroup gnn_logistic_doc
00308  *
00309  * @param node  A pointer to a \ref gnn_logistic node.
00310  * @return The streching factor \f$b\f$.
00311  */
00312 double
00313 gnn_logistic_get_b (gnn_node *node)
00314 {
00315     return GNN_LOGISTIC_B (node);
00316 }
00317 
00318 /**
00319  * @brief Sets the streching factor \f$b\f$.
00320  * @ingroup gnn_logistic_doc
00321  *
00322  * @param node  A pointer to a \ref gnn_logistic node.
00323  * @param b     The new streching factor \f$b\f$.
00324  */
00325 void
00326 gnn_logistic_set_b (gnn_node *node, double b)
00327 {
00328     GNN_LOGISTIC_B (node) = b;
00329 }
00330 
00331 
00332 
00333 

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