00001 /*!@file Learn/test-FuzzyART.C */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00005 // by the University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: John Shen <shenjohn@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Learn/test-FuzzyART.C $ 00035 // $Id: test-FuzzyART.C 13373 2010-05-09 04:28:40Z lior $ 00036 // 00037 00038 #include "Component/ModelComponent.H" 00039 #include "Component/ModelManager.H" 00040 #include "GUI/DebugWin.H" 00041 #include "Image/ColorMap.H" 00042 #include "Image/DrawOps.H" 00043 #include "Image/Image.H" 00044 #include "Learn/FuzzyART.H" 00045 #include "Util/MathFunctions.H" 00046 #include "Util/StringConversions.H" 00047 #include "Util/StringUtil.H" 00048 #include "nub/ref.h" 00049 #include <string> 00050 #include <vector> 00051 #include <fstream> 00052 #include <sstream> 00053 struct NormalDataCluster // gives normally distributed data 00054 { 00055 std::vector<double> mu, sigma; 00056 00057 PixRGB<byte> diagColor; 00058 00059 std::vector<double> generateData() { 00060 std::vector<double> ret; 00061 for(uint i = 0; i < mu.size(); i++) 00062 ret.push_back(mu[i]+randomDoubleFromNormal(sigma[i])); 00063 00064 return ret; 00065 } 00066 }; 00067 00068 //returns a vector with values uniformly distributed between the two 00069 std::vector<double> randomVectorIn(const std::vector<double> min, const std::vector<double> max) 00070 { 00071 ASSERT(min.size() == max.size()); 00072 std::vector<double> ret; 00073 for(uint i = 0; i < min.size(); i++) 00074 ret.push_back(min[i] + randomDouble()*(max[i]-min[i])); 00075 00076 return ret; 00077 } 00078 00079 void defaultTest(nub::soft_ref<FuzzyART> FuzzyLearner); 00080 00081 std::string toString(const std::vector<double>& c); 00082 00083 PixRGB<byte> randColor(); 00084 00085 int submain(const int argc, char** argv) 00086 { 00087 MYLOGVERB = LOG_INFO; 00088 00089 //initRandomNumbers(); 00090 ModelManager mgr("Test Fuzzy ART"); 00091 nub::soft_ref<FuzzyART> FuzzyARTModule(new FuzzyART(mgr)); 00092 mgr.addSubComponent(FuzzyARTModule); 00093 if (mgr.parseCommandLine( 00094 (const int)argc, (const char**)argv, "<input file> <output file>", 0,2) == false) 00095 return 1; 00096 00097 mgr.start(); 00098 00099 if(mgr.numExtraArgs() == 0) { 00100 defaultTest(FuzzyARTModule); 00101 } 00102 else { 00103 // input file has one pattern per line, scaled from 0 to 1, space separated 00104 // const uint NFeatures = FuzzyARTModule->getMaxCategories(); 00105 const uint NDims = FuzzyARTModule->getInputSize(); 00106 00107 std::string fn_in = mgr.getExtraArg(0); 00108 std::string fn_out = mgr.getExtraArg(1); 00109 00110 std::ifstream fin(fn_in.c_str()); 00111 if (!fin.is_open()) PLFATAL("Cannot open '%s'", fn_in.c_str()); 00112 00113 std::ofstream fout(fn_out.c_str()); 00114 if (!fout.is_open()) PLFATAL("Cannot open '%s'", fn_out.c_str()); 00115 00116 std::string line; int linenum = -1; 00117 00118 while(getline(fin, line)) { 00119 ++linenum; 00120 00121 std::stringstream ss(line); 00122 00123 std::vector<double> input_vec; 00124 for(uint i = 0; i < NDims; i++) { 00125 double foo; 00126 ss >> foo; 00127 input_vec.push_back(foo); 00128 } 00129 uint result; 00130 result = FuzzyARTModule->learnInput(input_vec); 00131 // LINFO("%d",FuzzyARTModule->numUnitsCommitted()); 00132 fout << result << "\n"; 00133 LINFO("input %02d to unit %02d", linenum, result); 00134 } 00135 00136 fin.close(); 00137 fout.close(); 00138 } 00139 mgr.stop(); 00140 00141 return 0; 00142 } 00143 00144 extern "C" int main(const int argc, char** argv) 00145 { 00146 try 00147 { 00148 return submain(argc, argv); 00149 } 00150 catch (...) 00151 { 00152 REPORT_CURRENT_EXCEPTION; 00153 } 00154 00155 return 1; 00156 } 00157 00158 // ###################################################################### 00159 // A default test, using normally distributed clusters and displaying 2D 00160 // clustering results 00161 void defaultTest(nub::soft_ref<FuzzyART> FuzzyLearner) 00162 { 00163 const uint NFeatures = FuzzyLearner->getMaxCategories(); 00164 const uint NDims = FuzzyLearner->getInputSize(); 00165 00166 const Dims dim(600,600); 00167 const PixRGB<byte> white(255,255,255); 00168 Image<PixRGB<byte> > grnd_truth(dim, ZEROS), 00169 test_result(dim,ZEROS); 00170 grnd_truth+=white; 00171 test_result+=white; 00172 const ColorMap cm = ColorMap::JET(NFeatures); 00173 00174 // setup: initialize data clusters 00175 std::vector<NormalDataCluster> dataClusters; 00176 for(uint i = 0; i < NFeatures; i++) { 00177 NormalDataCluster d; 00178 d.mu = randomVectorIn(std::vector<double>(NDims, 0.2), std::vector<double>(NDims, 0.8)); 00179 d.sigma = randomVectorIn(std::vector<double>(NDims, 0.01), std::vector<double>(NDims, 0.05)); 00180 d.diagColor = cm[i]; 00181 dataClusters.push_back(d); 00182 00183 // draw an ellipse for each cluster 00184 Point2D<int> p(d.mu[0]*dim.w(),d.mu[1]*dim.h()); 00185 00186 int rx = d.sigma[0]*dim.w(); 00187 int ry = d.sigma[1]*dim.h(); 00188 drawEllipse(grnd_truth, p, rx, ry, PixRGB<byte>(d.diagColor*0.8)); 00189 drawCross(grnd_truth, p, d.diagColor); 00190 } 00191 00192 00193 // sample data clusters, one at a time 00194 uint cluster; 00195 for(uint i = 0; i < NFeatures; i++) { 00196 LINFO("cluster #%d: mu (%s) sigma (%s)",i,toString(dataClusters[i].mu).c_str(), 00197 toString(dataClusters[i].sigma).c_str()); 00198 for(uint j = 0; j < 10; j++) { 00199 std::vector<double> sample = dataClusters[i].generateData(); 00200 Point2D<int> p(sample[0]*dim.w(),sample[1]*dim.h()); 00201 drawDisk(grnd_truth,p,2,dataClusters[i].diagColor); 00202 00203 cluster = FuzzyLearner->learnInput(sample); 00204 00205 if(cluster != uint(-1)) 00206 drawDisk(test_result,p,2,cm[cluster]); 00207 else 00208 drawCross(test_result, p, PixRGB<byte>(0,0,0)); 00209 00210 // LINFO("generate pt (%s) into cluster %u", toString(sample).c_str(),cluster); 00211 00212 00213 } 00214 } 00215 Image< PixRGB<byte> > disp = concatX(grnd_truth, test_result); 00216 drawLine(disp, Point2D<int>(dim.w()-1,0), Point2D<int>(dim.w()-1,dim.h()-1), 00217 PixRGB<byte>(0,0,255),1); 00218 LINFO("left: ground truth, right: ART clusters. press q to close window."); 00219 SHOWIMG(disp); 00220 } 00221 00222 // ###################################################################### 00223 // Utility functions 00224 std::string toString(const std::vector<double>& c) 00225 { 00226 std::string ret = ""; 00227 for(uint i = 0; i < c.size(); i++) 00228 ret += convertToString(c[i]) + ","; 00229 00230 ret.erase(ret.end()-1); 00231 return ret; 00232 } 00233 00234 // ###################################################################### 00235 PixRGB<byte> randColor() 00236 { 00237 return PixRGB<byte>(randomUpToIncluding(255), 00238 randomUpToIncluding(255), 00239 randomUpToIncluding(255)); 00240 } 00241