Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

ActiveLearnEngine.h

Go to the documentation of this file.
00001 #ifndef ActiveLearnEngine_h
00002 #define ActiveLearnEngine_h
00003 
00004 #include "Basis/ILog.h"
00005 #include "Core/Trec/ThreadSet.h"
00006 #include "Core/Table/SimilarityTableSet.h"
00007 #include "Util/Database.h"
00008 
00009 #include "Basis/Timer.h"
00010 
00011 namespace Impala {
00012 
00013 namespace Samples {
00014 
00015 //using namespace Visualization::GUI;
00016 //using namespace Core::Trec;
00017 
00018 typedef Core::Table::TableTem<Core::Column::ColumnTem<Int32>, Core::Column::ColumnTem<double> > ShotWithWeight;
00019 
00020 class ActiveLearnEngine
00021 {
00022 public:
00023     typedef Core::Trec::Thread                          Thread;
00024     typedef Core::Trec::ThreadSet                       ThreadSet;
00025     typedef Core::Trec::ShotResult                      ShotResult;
00026     typedef std::list<ShotResult>                       ShotResultList;
00027 
00028     ActiveLearnEngine(ThreadSet *set, Thread *positiveAnnotations,
00029                       Thread *negativeAnnotations)
00030     {
00031         mThreadSet = set;
00032         mPositive = positiveAnnotations;
00033         mNegative = negativeAnnotations;
00034         mAnnotations = new Core::Table::AnnotationTable();
00035         mTimer = new Timer();
00036         mTimer->Start();
00037         srand( time(NULL) );
00038         mInfoSent = false;
00039         mActiveID = "start";
00040         mAutoNegatives = true;
00041         mAutoNegativesNumber = 50;
00042         mErrCount = 0;
00043 
00044         mALDatabase = new Util::Database("activelearning");
00045         mALDatabase->SetOverride(true);
00046     }
00047 
00048     void
00049     PrepareNewID()
00050     {
00051         mActiveID = "al" + mTimer->SplitTimeStr();
00052         mInfoSent = false;
00053     }
00054 
00055     std::string
00056     GetID()
00057     {
00058         return mActiveID;
00059     }
00060 
00061     bool
00062     RequestSubmitted()
00063     {
00064         return mInfoSent;
00065     }
00066 
00067     int
00068     GetErrCount()
00069     {
00070         return mErrCount;
00071     }
00072 
00073     void
00074     PrepRequest()
00075     {
00076         if (mInfoSent)
00077             return;
00078 
00079         PrepareNewID();
00080 
00081         ILOG_DEBUG("SubmitRequest(), ID for submit = " << GetID());
00082 
00083         mAnnotations->SetEmpty();
00084 
00085     }
00086 
00087     void
00088     AddAnnotations()
00089     {
00090         for (int i=0; i<mPositive->GetLength(); i++)
00091         {
00092             int shot = mPositive->GetShot(i);
00093             int keyframe = mThreadSet->GetKeyframes()->GetShotRKF(shot);
00094             Quid fquid = mThreadSet->GetKeyframes()->GetQuidFrame(keyframe);
00095 //            ILOG_DEBUG("positive: " << QuidObj(fquid));
00096             mAnnotations->AddPositive(fquid);
00097         }
00098 
00099         for (int i=0; i<mNegative->GetLength(); i++)
00100         {
00101             int shot = mNegative->GetShot(i);
00102             int keyframe = mThreadSet->GetKeyframes()->GetShotRKF(shot);
00103             Quid fquid = mThreadSet->GetKeyframes()->GetQuidFrame(keyframe);
00104 //            ILOG_DEBUG("negative: " << QuidObj(fquid));
00105             mAnnotations->AddNegative(fquid);
00106         }
00107         ILOG_DEBUG("Added annotations, table now with " << mAnnotations->GetNrPositive() << " positive shots and " << mAnnotations->GetNrNegative() << " negative shots.");
00108     }
00109 
00110     void
00111     AddPositive(Quid q)
00112     {
00113 //        ILOG_DEBUG("added positive " << QuidObj(q));
00114         mAnnotations->AddPositive(q);
00115     }
00116 
00117     void
00118     AddNegative(Quid q)
00119     {
00120 //        ILOG_DEBUG("added negative " << QuidObj(q));
00121         mAnnotations->AddNegative(q);
00122     }
00123 
00124     void
00125     AddRandomNegatives(int number)
00126     {
00127         ILOG_DEBUG("adding " << number << " random examples as negative...");
00128         for (int i=0; i<number; i++)
00129         {
00130             double rnd = ( (1.0 * rand()) / RAND_MAX);
00131             int randomkeyframe = rnd * (mThreadSet->GetKeyframes()->GetNrKeyframes()-1);
00132             Quid randomkeyquid = mThreadSet->GetKeyframes()->GetQuidFrame(randomkeyframe);
00133             AddNegative(randomkeyquid);
00134         }
00135     }
00136 
00137     void
00138     SubmitRequest()
00139     {
00140         if (mInfoSent)
00141             return;
00142 
00143         if (mAnnotations->GetNrPositive() == 0)
00144         {
00145             ILOG_WARN("No positive examples, ALE request not submitted.");
00146             return;
00147         }
00148 
00149         if (mAnnotations->GetNrNegative() == 0)
00150         {
00151             if (mAutoNegatives) {
00152                 ILOG_INFO("No negative examples given, selecting random subset...");
00153                 AddRandomNegatives(mAutoNegativesNumber);
00154             } else {
00155                 ILOG_WARN("No negative examples and random selection disabled, ALE request not submitted.");
00156                 return;
00157             }
00158         }
00159 
00160         ILOG_DEBUG("Using table with " << mAnnotations->GetNrPositive() << " positive shots and " << mAnnotations->GetNrNegative() << " negative shots.");
00161 
00162         String dir = "Annotations/" + QuidClassToString(QUID_CLASS_FRAME) + "/" + "conceptsActiveLearn.txt";        
00163         String filename = mALDatabase->GetFilePath(dir, GetID() + ".tab", true, false);
00164 
00165         ILOG_DEBUG("Writing to " << filename << "...");
00166 
00167         Core::Table::Write(mAnnotations, filename, mALDatabase, true);
00168 
00169         ILOG_DEBUG("Signalling active learning engine...");
00170         
00171         String startlearnfile = mALDatabase->GetFilePath(dir, "startlearner.txt", true, false);
00172 
00173         Util::IOBuffer *slf = mALDatabase->GetIOBuffer(
00174                                 startlearnfile, false, false, "tmp");
00175         if (!slf)
00176         {
00177             ILOG_WARN("No startlearnfile, ALE request not submitted.");
00178             return;
00179         }
00180         slf->IOBuffer::Puts(GetID());
00181         delete slf;
00182 
00183         ILOG_DEBUG("Signal sent.");
00184         mInfoSent = true;
00185     }
00186 
00187     bool
00188     HasResults()
00189     {
00190         ILOG_DEBUG("Locating results...");
00191 
00192         String dir =
00193             "SimilarityIndex/conceptsActiveLearn.txt/activelearn/activelearn";
00194 
00195         String path = mALDatabase->GetFilePath(dir, "names.txt", false, false);
00196         Core::Table::SimilarityTableSet *conceptSet = 
00197             Core::Table::SimilarityTableSet::MakeFromFile(path, mALDatabase);
00198 
00199         Core::Table::SimilarityTableSet::RankTableType* rank = conceptSet->GetRankTable(GetID());
00200 
00201         //ShotResultList out;
00202 
00203         if (!rank)
00204         {
00205             ILOG_DEBUG("ID " << GetID() << " not (yet) found.");
00206             delete conceptSet;
00207             return false;
00208         }
00209         delete conceptSet;
00210         ILOG_DEBUG("ID " << GetID() << " found!");
00211         return true;
00212     }
00213 
00214     ShotResultList
00215     RetrieveResults()
00216     {
00217         ILOG_DEBUG("Retrieving results...");
00218 
00219         String dir =
00220             "SimilarityIndex/conceptsActiveLearn.txt/activelearn/activelearn";
00221 
00222         String path = mALDatabase->GetFilePath(dir, "names.txt", false, false);
00223 
00224         Core::Table::SimilarityTableSet *conceptSet = 
00225             Core::Table::SimilarityTableSet::MakeFromFile(path, mALDatabase);
00226 
00227         Core::Table::SimilarityTableSet::RankTableType* rank = conceptSet->GetRankTable(GetID());
00228 
00229         ShotResultList out;
00230 
00231         if (!rank)
00232         {
00233             ILOG_DEBUG("Could not find ID, no data present. :'(");
00234             delete conceptSet;
00235             return out;
00236         }
00237 
00238         mInfoSent = false;
00239 
00240         int results = 5000;
00241 
00242         ILOG_DEBUG("Concept loaded, converting to list...");
00243         // find the Thread using the "concept" name
00244 
00245         std::map<int,bool> noduplicates;
00246         int rrank = 1;
00247         mErrCount = 0;
00248         int dropcount = 0;
00249         for (int i=0; i<results; i++)
00250         {
00251 
00252             Quid q = rank->Get1(i);
00253             if (QuidSet(q) == 23) {
00254                 dropcount++; 
00255                 // ILOG_DEBUG("silent drop of result " << i <<": from topic set.");
00256                 mErrCount++;
00257                 continue;
00258             }
00259             /*
00260             if (QuidSet(q) != 11 && QuidSet(q) != 12) {
00261                 ILOG_ERROR("data not from trec2008devel or test set, dropping results.");
00262                 // added to limit effects of race condition
00263                 // which happens when the server is still writing results and the
00264                 // user already is loading the file. A better approach would be to
00265                 // rewrite this entire file to use network comms instead of thumper
00266                 // based comms instead.
00267                 mErrCount++;
00268                 mInfoSent = true;
00269                 delete conceptSet;
00270                 return out;
00271             }
00272             */
00273 
00274             int keyframe = mThreadSet->GetKeyframes()->GetFrameId(q);
00275 
00276             if (keyframe < 0) {
00277                 ILOG_WARN("erroneous result " << QuidObj(q) << " for this set, dropping.");
00278                 mErrCount++;
00279                 continue;
00280             }
00281 
00282             int shot = mThreadSet->GetKeyframes()->GetShotId(keyframe);
00283 
00284             if (shot > -1 && noduplicates.find(shot) == noduplicates.end())
00285             {
00286                 ShotResult r;
00287                 r.shotid = shot;
00288                 r.rank = rrank++;
00289                 r.score = conceptSet->GetSimTable(GetID())->Get1(conceptSet->FindQuid(q));
00290 //                if (rrank < 10)
00291 //                    ILOG_DEBUG("RECV: " << r.rank << ": " << r.shotid << " (" << r.score << ")");
00292                 noduplicates[shot] = true;
00293                 out.push_back(r);
00294             }
00295         }
00296        
00297         if (dropcount > 0)
00298             ILOG_DEBUG("there were " << dropcount << " silent drops from results");
00299         if (mErrCount > 0)
00300             ILOG_DEBUG("there were " << mErrCount << " errors while receiving results");
00301 
00302         delete conceptSet;
00303 
00304         return out;     
00305     }
00306 
00307     bool
00308     Ready()
00309     {
00310         // return true iff input is correct, and engine is ready to learn new results.
00311 
00312         return true;
00313     }
00314 
00315 private:
00316 
00317 
00318     ThreadSet *mThreadSet;
00319     Thread *mPositive, *mNegative;
00320     std::string mActiveID;
00321     Core::Table::AnnotationTable *mAnnotations;
00322     Util::Database *mALDatabase;
00323     bool mInfoSent;
00324 
00325     bool mAutoNegatives;
00326     int mAutoNegativesNumber;
00327     int mErrCount;
00328 
00329     Timer* mTimer;
00330     ILOG_VAR_DEC;
00331 
00332 };
00333 ILOG_VAR_INIT(ActiveLearnEngine, Core.Trec);
00334 
00335 
00336 }
00337 
00338 }
00339 
00340 
00341 #endif

Generated on Fri Mar 19 09:31:25 2010 for ImpalaSrc by  doxygen 1.5.1