00001 /*************************************************************************** 00002 * Copyright (C) 2005-2011 LpzRobots development team * 00003 * Georg Martius <georg dot martius at web dot de> * 00004 * Frank Guettler <guettler at informatik dot uni-leipzig dot de * 00005 * Frank Hesse <frank at nld dot ds dot mpg dot de> * 00006 * Ralf Der <ralfder at mis dot mpg dot de> * 00007 * * 00008 * This program is free software; you can redistribute it and/or modify * 00009 * it under the terms of the GNU General Public License as published by * 00010 * the Free Software Foundation; either version 2 of the License, or * 00011 * (at your option) any later version. * 00012 * * 00013 * This program is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00016 * GNU General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU General Public License * 00019 * along with this program; if not, write to the * 00020 * Free Software Foundation, Inc., * 00021 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 00022 * * 00023 ***************************************************************************/ 00024 #ifndef __REGULARISATION_H 00025 #define __REGULARISATION_H 00026 00027 #include <cmath> 00028 #include <selforg/controller_misc.h> 00029 00030 double inline sqr(double x) { 00031 return x*x; 00032 } 00033 00034 /// neuron transfer function 00035 double inline g(double z) 00036 { 00037 return tanh(z); 00038 }; 00039 00040 /// first dervative 00041 double inline g_s(double z) 00042 { 00043 double k=tanh(z); 00044 return 1.025 - k*k; 00045 // return 1/((1+0.5 * z*z)*(1+0.5 * z*z)); // softer 00046 //return 1/(1+log(1+z*z)); // even softer 00047 }; 00048 00049 00050 /// first dervative with smoothing for large z 00051 double inline g_derivative(double z) 00052 { 00053 return 1/((1+0.5 * z*z)*(1+0.5 * z*z)); 00054 }; 00055 00056 /// inverse of the first derivative 00057 double inline g_s_inv(double z) 00058 { 00059 double k=tanh(z); 00060 return 1/(1.025 - k*k); 00061 // return 1+z*z; // softer 00062 //return 1+log(1+z*z); // even softer 00063 }; 00064 00065 /** \f[ g'(z+xsi) = 1-(tanh(z+xsi))^2 \f] with additional clipping */ 00066 double inline g_s(double z, double xsi) { 00067 double Z = clip(z, -3.0, 3.0) + clip(xsi, -1.0, 1.0); 00068 double k=tanh(Z); // approximation with Mittelwertsatz 00069 return 1 - k*k; 00070 }; 00071 00072 00073 /** soft version: \f[ g'(z+xsi) = 1/(1+(z+xsi)^2 \f] with additional clipping */ 00074 double inline g_s_soft(double z, double xsi) { 00075 double Z = clip(z, -3.0, 3.0) + clip(xsi, -1.0, 1.0); 00076 return 1/(1 + Z*Z);//TEST 00077 }; 00078 00079 00080 /// an exact formula for g''/g'= -2g(Z), with clipped Z = z+xsi 00081 double inline g_ss_div_s(double z, double xsi) { 00082 // for consistency reasons we use the same clipped z as for g'. 00083 double Z = clip(z, -3.0, 3.0) + clip(xsi, -1.0, 1.0); 00084 // approximation with Mittelwertsatz (z is clipped) 00085 return -2*g(Z); 00086 }; 00087 00088 /// an soft formula for g''/g' = -2Z, with clipped Z = z+xsi 00089 double inline g_ss_div_s_soft(double z, double xsi) { 00090 // for consistency reasons we use the same clipped z as for g'. 00091 double Z = clip(z, -3.0, 3.0) + clip(xsi, -1.0, 1.0); 00092 return -2*Z;//TEST 00093 }; 00094 00095 /** with \f[ g'(z) = 1-(g(z+\xi))^2 \f] we get 00096 \f[\frac{\partial}{\partial z} \frac{1}{g'(Z)} = \frac{g''}{g'^2} \f] 00097 again with clipped Z 00098 */ 00099 double inline derive_g_s_inv_exact_clip(double z, double xsi){ 00100 double Z = clip(z, -3.0, 3.0) + clip(xsi, -1.0, 1.0); 00101 double k=tanh(Z); // approximation with Mittelwertsatz 00102 return -2*k/(1-k*k); 00103 } 00104 00105 /** \f[ g'(z) = 1-(z+\xi)^2 \f] which is the series expansion to the second order 00106 */ 00107 double inline g_s_expand2(double z, double xsi){ 00108 double Z = z + clip(xsi, -fabs(z), fabs(z)); 00109 return 1/(1+sqr(Z)); 00110 } 00111 00112 /** \f[ \frac{1}{g'(z)} \approx 1+(z+\xi)^2 \f] with geometric series approximation 00113 */ 00114 double inline g_s_inv_expand2(double z, double xsi){ 00115 double Z = z + clip(xsi, -fabs(z)/2.0, fabs(z)/2.0); 00116 return 1+sqr(Z); 00117 } 00118 00119 /** \f[ \frac{g''(z)}{g'(z)} \approx 2(z+\xi)(1+(z+\xi)^2) \f] with geometric series approximation 00120 */ 00121 double inline g_ss_div_s_expand2(double z, double xsi){ 00122 double Z = z + clip(xsi, -fabs(z)/2.0, fabs(z)/2.0); 00123 // double Z = z + clip(xsi, -fabs(z), fabs(z)); 00124 return -2*tanh(Z); 00125 } 00126 00127 00128 /// squashing function (-0.1 to 0.1), to protect against to large weight updates 00129 double inline squash(double z) 00130 { 00131 return clip(z, -0.1, 0.1); 00132 //return 0.1 * tanh(10.0 * z); 00133 }; 00134 00135 /// squashing function with adjustable clipping size, to protect against too large weight updates 00136 double inline squash(void* d, double z) { 00137 double size = *((double*)d); 00138 return clip(z, -size, size); 00139 }; 00140 00141 00142 00143 #endif 00144