VisualCortexSurprise.C

Go to the documentation of this file.
00001 /*!@file Neuro/VisualCortexSurprise.C a VisualCortex with SingleChannelSurprise
00002   channels */
00003 
00004 // //////////////////////////////////////////////////////////////////// //
00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003   //
00006 // by the University of Southern California (USC) and the iLab at USC.  //
00007 // See http://iLab.usc.edu for information about this project.          //
00008 // //////////////////////////////////////////////////////////////////// //
00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00011 // in Visual Environments, and Applications'' by Christof Koch and      //
00012 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00013 // pending; application number 09/912,225 filed July 23, 2001; see      //
00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00015 // //////////////////////////////////////////////////////////////////// //
00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00017 //                                                                      //
00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00019 // redistribute it and/or modify it under the terms of the GNU General  //
00020 // Public License as published by the Free Software Foundation; either  //
00021 // version 2 of the License, or (at your option) any later version.     //
00022 //                                                                      //
00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00026 // PURPOSE.  See the GNU General Public License for more details.       //
00027 //                                                                      //
00028 // You should have received a copy of the GNU General Public License    //
00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00031 // Boston, MA 02111-1307 USA.                                           //
00032 // //////////////////////////////////////////////////////////////////// //
00033 //
00034 // Primary maintainer for this file: Laurent Itti <itti@usc.edu>
00035 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Neuro/VisualCortexSurprise.C $
00036 // $Id: VisualCortexSurprise.C 11584 2009-08-12 05:24:46Z itti $
00037 //
00038 
00039 #include "Neuro/VisualCortexSurprise.H"
00040 
00041 #include "Channels/ChannelOpts.H"
00042 #include "Channels/ComplexChannel.H"
00043 #include "Channels/SingleChannel.H"
00044 #include "Channels/SubmapAlgorithm.H"
00045 #include "Component/ModelOptionDef.H"
00046 #include "Component/OptionManager.H"
00047 #include "Image/MathOps.H"
00048 #include "Surprise/SingleChannelSurprise.H"
00049 #include "Surprise/SurpriseOpts.H"
00050 
00051 // Used by: VisualCortexSurprise
00052 const ModelOptionDef OPT_VCXnormSurp =
00053   { MODOPT_ARG(int), "VCXnormSurp", &MOC_SURPRISE, OPTEXP_CORE,
00054     "Apply competitive spatial interactions to VisualCortex output "
00055     "when --maxnorm-type is Surprise. This will slightly sparsify the "
00056     "final surprise map output by the VisualCortex. Specify the number "
00057     "of FancyWeak iterations or 0 for no interactions.",
00058     "vcx-normsurp", '\0', "<int>", "2" };
00059 
00060 // Used by: VisualCortexSurprise
00061 const ModelOptionDef OPT_VCXSurpriseThresh =
00062   { MODOPT_ARG(float), "VCXSurpriseThresh", &MOC_SURPRISE, OPTEXP_CORE,
00063     "Threshold for nonlinearity applied to Visual Cortex surprise output "
00064     "(will be ignored if --surprise-exp=0.0)",
00065     "surprise-thresh", '\0', "<float>", "0.25" };
00066 
00067 // Used by: VisualCortexSurprise
00068 const ModelOptionDef OPT_VCXSurpriseSemisat =
00069   { MODOPT_ARG(float), "VCXSurpriseSemisat", &MOC_SURPRISE, OPTEXP_CORE,
00070     "Semisaturation constant for nonlinearity applied to Visual Cortex "
00071     "surprise output (will be ignored if --surprise-exp=0.0)",
00072     "surprise-semisat", '\0', "<float>", "0.35" };
00073 
00074 // Used by: VisualCortexSurprise
00075 const ModelOptionDef OPT_VCXSurpriseExp =
00076   { MODOPT_ARG(float), "VCXSurpriseExp", &MOC_SURPRISE, OPTEXP_CORE,
00077     "Exponent for nonlinearity applied to Visual Cortex surprise output, "
00078     "or 0.0 to not apply any nonlinearity.",
00079     "surprise-exp", '\0', "<float>", "4" };
00080 
00081 
00082 // ######################################################################
00083 VisualCortexSurprise::VisualCortexSurprise(OptionManager& mgr,
00084                                            const std::string& descrName,
00085                                            const std::string& tagName) :
00086   RawVisualCortex(mgr, descrName, tagName),
00087   itsStype(&OPT_VisualCortexSurpriseType, this),
00088   itsNormSurp(&OPT_VCXnormSurp, this),
00089   itsSurpriseThresh(&OPT_VCXSurpriseThresh, this),
00090   itsSurpriseSemisat(&OPT_VCXSurpriseSemisat, this),
00091   itsSurpriseExp(&OPT_VCXSurpriseExp, this)
00092 {
00093   VisualCortexSurprise::registerSurpriseTypes(mgr);
00094 
00095   // make all of the SingleChannel objects change their
00096   // SubmapAlgorithm type:
00097   mgr.setOptionValString(&OPT_SubmapAlgoType, "Surprise" + itsStype.getVal());
00098 }
00099 
00100 // ######################################################################
00101 VisualCortexSurprise::~VisualCortexSurprise()
00102 {  }
00103 
00104 // ######################################################################
00105 void VisualCortexSurprise::registerSurpriseTypes(OptionManager& mgr)
00106 {
00107   // register the various surprise types with the SubmapAlgorithm
00108   // factory, so that we can set OPT_SubmapAlgoType to trigger
00109   // SingleChannel to get its new SubmapAlgorithm from the factory:
00110   ComponentFactory<SubmapAlgorithm>& f = SubmapAlgorithm::getFactory();
00111   if (!f.is_valid_key("SurpriseGaussian"))
00112     f.registerType<SingleChannelSurprise<SurpriseModelSG> >("SurpriseGaussian", mgr);
00113   if (!f.is_valid_key("SurprisePoisson"))
00114     f.registerType<SingleChannelSurprise<SurpriseModelSP> >("SurprisePoisson", mgr);
00115   if (!f.is_valid_key("SurprisePoisson1"))
00116     f.registerType<SingleChannelSurprise<SurpriseModelSP1> >("SurprisePoisson1", mgr);
00117   if (!f.is_valid_key("SurprisePoissonConst"))
00118     f.registerType<SingleChannelSurprise<SurpriseModelSPC> >("SurprisePoissonConst", mgr);
00119   if (!f.is_valid_key("SurprisePoissonFloat"))
00120     f.registerType<SingleChannelSurprise<SurpriseModelSPF> >("SurprisePoissonFloat", mgr);
00121   if (!f.is_valid_key("SurpriseChiSquare"))
00122     f.registerType<SingleChannelSurprise<SurpriseModelCS> >("SurpriseChiSquare", mgr);
00123   if (!f.is_valid_key("SurpriseJointGG"))
00124     f.registerType<SingleChannelSurprise<SurpriseModelGG> >("SurpriseJointGG", mgr);
00125   if (!f.is_valid_key("SurpriseNathan"))
00126     f.registerType<SingleChannelSurprise<SurpriseModelPM> >("SurpriseNathan", mgr);
00127   if (!f.is_valid_key("SurpriseOutlier"))
00128     f.registerType<SingleChannelSurprise<SurpriseModelOD> >("SurpriseOutlier", mgr);
00129   if (!f.is_valid_key("SurpriseMultivariant"))
00130     f.registerType<SingleChannelSurprise<SurpriseModelPM> >("SurpriseMultivariant", mgr);
00131 }
00132 
00133 // ######################################################################
00134 void VisualCortexSurprise::paramChanged(ModelParamBase* const param,
00135                                         const bool valueChanged,
00136                                         ParamClient::ChangeStatus* status)
00137 {
00138   RawVisualCortex::paramChanged(param, valueChanged, status);
00139 
00140   // was that a change of surprise type?
00141   if (param == &itsStype)
00142     {
00143       LINFO("Switching to surprise models of type %s", itsStype.getVal().c_str());
00144 
00145       // make all of the SingleChannel objects change their
00146       // SubmapAlgorithm type:
00147       getManager().setOptionValString(&OPT_SubmapAlgoType, "Surprise" + itsStype.getVal());
00148     }
00149 }
00150 
00151 // ######################################################################
00152 Image<float> VisualCortexSurprise::postProcessOutputMap(const Image<float>& outmap)
00153 {
00154   if (itsNormType.getVal() != VCXNORM_SURPRISE)
00155     LFATAL("You must use --maxnorm-type=Surprise with VisualCortexSurprise");
00156 
00157   Image<float> result = outmap;
00158 
00159   if (itsUseMax.getVal() == false)
00160     {
00161       // get the sum of all subchan output maps and divide it by the
00162       // number of subchans that have non-zero weights, so that surprise
00163       // averages rather than sums over subchans:
00164       uint num_nzw = 0; for (uint i = 0; i < numChans(); ++i) if (getSubchanTotalWeight(i) != 0.0) ++num_nzw;
00165       if (num_nzw > 1)
00166         {
00167           LDEBUG("Averaging surprise outputs across %u top channels.", numChans());
00168           result *= 1.0 / numChans();
00169         }
00170     }
00171 
00172   // get rid of background firing activity due to internal relaxation:
00173   result -= itsSurpriseThresh.getVal();
00174   inplaceRectify(result);
00175 
00176   // Pass the final surprise through a sigmoid, if exp is non-zero:
00177   if (itsSurpriseExp.getVal() != 0.0)
00178     inplaceSigmoid(result, itsSurpriseExp.getVal(), itsSurpriseExp.getVal(),
00179                    powf(itsSurpriseSemisat.getVal(), itsSurpriseExp.getVal()));
00180 
00181   // Optional spatial competition may be applied to sparsify the output:
00182   if (itsNormSurp.getVal())
00183     {
00184       result = maxNormalize(result, 0.0f, 0.0f, VCXNORM_FANCYWEAK, itsNormSurp.getVal());
00185       LDEBUG("%s(0.0 .. 0.0) x %d", maxNormTypeName(VCXNORM_FANCYWEAK), itsNormSurp.getVal());
00186     }
00187 
00188   return result;
00189 }
00190 
00191 // ######################################################################
00192 /* So things look consistent in everyone's emacs... */
00193 /* Local Variables: */
00194 /* indent-tabs-mode: nil */
00195 /* End: */
Generated on Sun May 8 08:05:26 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3