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 #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
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
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
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
00104
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
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
00160
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
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
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
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
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
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