00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
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
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
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
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
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
00096
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
00108
00109
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
00141 if (param == &itsStype)
00142 {
00143 LINFO("Switching to surprise models of type %s", itsStype.getVal().c_str());
00144
00145
00146
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
00162
00163
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
00173 result -= itsSurpriseThresh.getVal();
00174 inplaceRectify(result);
00175
00176
00177 if (itsSurpriseExp.getVal() != 0.0)
00178 inplaceSigmoid(result, itsSurpriseExp.getVal(), itsSurpriseExp.getVal(),
00179 powf(itsSurpriseSemisat.getVal(), itsSurpriseExp.getVal()));
00180
00181
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
00193
00194
00195