00001 // This is mul/clsfy/clsfy_rbf_svm.h 00002 // Copyright: (C) 2000 British Telecommunications plc. 00003 #ifndef clsfy_rbf_svm_h_ 00004 #define clsfy_rbf_svm_h_ 00005 //: 00006 // \file 00007 // \brief Describe a RBF Support Vector Machine 00008 // \author Ian Scott 00009 // \date Jan 2001 00010 // \verbatim 00011 // Modifications 00012 // 31 May 2001 IMS Converted to VXL 00013 // 31 May 2001 IMS Merged with Finder/IS_OrderedSVM 00014 // \endverbatim 00015 00016 #include <clsfy/clsfy_classifier_base.h> 00017 #include <vcl_cmath.h> 00018 #include <vcl_iosfwd.h> 00019 00020 //: A Support Vector Machine Binary Classifier. 00021 class clsfy_rbf_svm : public clsfy_classifier_base 00022 { 00023 protected: 00024 //: the starting upper bound. 00025 // If the function sum exceeds this value, the decision will definitely be 1. 00026 double upper_target_; 00027 //: the starting lower bound. 00028 // If the function sum falls below this value, the decision will definitely be 0. 00029 double lower_target_; 00030 00031 //: The support vectors. 00032 vcl_vector<vnl_vector<double> > supports_; 00033 00034 //: The Lagrangian multipliers 00035 // The values have been pre-multiplied by the +/-1.0 depending on the support target. 00036 vcl_vector<double> lagrangians_; 00037 00038 //: The offset bias. 00039 double bias_; 00040 00041 //: -1/(2 * sigma*sigma), where sigma = RBF kernel width 00042 double gamma_; 00043 00044 public: 00045 00046 //: Dflt constructor 00047 clsfy_rbf_svm(); 00048 00049 //: Destructor 00050 virtual ~clsfy_rbf_svm(); 00051 00052 //: Classify the input vector 00053 // returns 0 to indicate out of (or negative) class and one to indicate in class (or positive.) 00054 virtual unsigned classify(const vnl_vector<double> &input) const; 00055 00056 //: Return the probability the input being in each class. 00057 // output(i) i<<nClasses, contains the probability that the input 00058 // is in class i; 00059 // This are not strict probability values, since SVMs do not give Bayesian 00060 // outputs. However their properties fit the requirements of a probability. 00061 virtual void class_probabilities(vcl_vector<double> &outputs, 00062 const vnl_vector<double> &input) const; 00063 00064 //: Log likelihood of being in class (binary classifiers only) 00065 // class probability = vcl_exp(logL) / (1+vcl_exp(logL) 00066 virtual double log_l(const vnl_vector<double> &input) const; 00067 00068 //: Set the internal values defining the classifier. 00069 // \param supportVectors 00070 // \param lagrangianAlphas 00071 // \param labels These should be 0 or 1. 00072 // \param RBFWidth 00073 // \param bias 00074 virtual void set( const vcl_vector<vnl_vector<double> > & supportVectors, 00075 const vcl_vector<double> & lagrangianAlphas, 00076 const vcl_vector<unsigned> &labels, 00077 double RBFWidth, double bias); 00078 00079 //: The 1st standard deviation width of the RBF kernel. 00080 // Really this could be better named as the RBF radius. 00081 double rbf_width() const { return 1/vcl_sqrt(-2.0*gamma_);} 00082 00083 //: The number of support vectors. 00084 unsigned n_support_vectors() const { return supports_.size();} 00085 00086 //: The kernel function 00087 // Uses the SVM's current value of RBFWidth. 00088 double kernel(const vnl_vector<double> &v1, const vnl_vector<double> &v2) const; 00089 00090 //: The SVM function bias. 00091 double bias() const {return bias_;} 00092 00093 //: The Lagrange multipliers. 00094 // The values corresponding to negative training vectors are pre-multiplied by -1. 00095 // The array ordering corresponds to supportVectors() 00096 const vcl_vector<double> & lagrangians() const {return lagrangians_;} 00097 00098 //: The support vectors. 00099 // The array ordering corresponds to lagrangians() 00100 const vcl_vector<vnl_vector<double> > & support_vectors() const {return supports_;} 00101 00102 00103 //: The number of possible output classes. 00104 virtual unsigned n_classes() const {return 1;} 00105 00106 //: The dimensionality of input vectors. 00107 virtual unsigned n_dims() const {return supports_[0].size();} 00108 00109 //: Return the class's IO version number 00110 short version_no() const; 00111 00112 //: Name of the class 00113 virtual vcl_string is_a() const ; 00114 00115 //: Name of the class 00116 virtual bool is_class(vcl_string const& s) const; 00117 00118 //: Create a copy on the heap and return base class pointer 00119 virtual clsfy_classifier_base* clone() const; 00120 00121 //: Print class to os 00122 virtual void print_summary(vcl_ostream& os) const; 00123 00124 //: Save class to binary file stream 00125 virtual void b_write(vsl_b_ostream& bfs) const; 00126 00127 //: Load class from binary file stream 00128 virtual void b_read(vsl_b_istream& bfs); 00129 00130 protected: 00131 //: Set the private target member values to the correct value. 00132 void calculate_targets(); 00133 00134 //: Calculate the contribution of a single support vector to the classifier; 00135 // This local version is used so that the number of calls can be tested. 00136 double localEuclideanDistanceSq(const vnl_vector<double> &a, const vnl_vector<double> &b) const 00137 { 00138 #ifdef CLSFY_RBF_SVM_GLOBAL_COUNT_USE_OF_EUCLIDEAN_DISTANCE_SQ 00139 extern CLSFY_RBF_SVM_GLOBAL_COUNT_USE_OF_EUCLIDEAN_DISTANCE_SQ; 00140 CLSFY_RBF_SVM_GLOBAL_COUNT_USE_OF_EUCLIDEAN_DISTANCE_SQ ++; 00141 #endif 00142 return vnl_vector_ssd(a, b); 00143 } 00144 }; 00145 00146 #endif // clsfy_rbf_svm_h_