Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <shogun/classifier/svm/OnlineLibLinear.h>
00014 #include <shogun/features/streaming/StreamingDenseFeatures.h>
00015 #include <shogun/lib/Time.h>
00016
00017 using namespace shogun;
00018
00019 COnlineLibLinear::COnlineLibLinear()
00020 : COnlineLinearMachine()
00021 {
00022 init();
00023 }
00024
00025 COnlineLibLinear::COnlineLibLinear(float64_t C_reg)
00026 {
00027 init();
00028 C1=C_reg;
00029 C2=C_reg;
00030 use_bias=true;
00031 }
00032
00033 COnlineLibLinear::COnlineLibLinear(
00034 float64_t C_reg, CStreamingDotFeatures* traindat)
00035 {
00036 init();
00037 C1=C_reg;
00038 C2=C_reg;
00039 use_bias=true;
00040
00041 set_features(traindat);
00042 }
00043
00044 COnlineLibLinear::COnlineLibLinear(COnlineLibLinear *mch)
00045 {
00046 init();
00047 C1 = mch->C1;
00048 C2 = mch->C2;
00049 use_bias = mch->use_bias;
00050
00051 set_features(mch->features);
00052
00053 w_dim = mch->w_dim;
00054 if (w_dim > 0)
00055 {
00056 w = SG_MALLOC(float32_t, w_dim);
00057 memcpy(w, mch->w, w_dim*sizeof(float32_t));
00058 }
00059 else
00060 {
00061 w = NULL;
00062 }
00063 bias = mch->bias;
00064 }
00065
00066
00067 void COnlineLibLinear::init()
00068 {
00069 C1=1;
00070 C2=1;
00071 use_bias=false;
00072
00073 m_parameters->add(&C1, "C1", "C Cost constant 1.");
00074 m_parameters->add(&C2, "C2", "C Cost constant 2.");
00075 m_parameters->add(&use_bias, "use_bias", "Indicates if bias is used.");
00076 }
00077
00078 COnlineLibLinear::~COnlineLibLinear()
00079 {
00080 }
00081
00082 void COnlineLibLinear::start_train()
00083 {
00084 Cp = C1;
00085 Cn = C2;
00086 PGmax_old = CMath::INFTY;
00087 PGmin_old = -CMath::INFTY;
00088 PGmax_new = -CMath::INFTY;
00089 PGmin_new = CMath::INFTY;
00090
00091 diag[0]=0;diag[1]=0;diag[2]=0;
00092 upper_bound[0]=Cn;upper_bound[1]=0;upper_bound[2]=Cp;
00093
00094 bias = 0;
00095
00096 PGmax_new = -CMath::INFTY;
00097 PGmin_new = CMath::INFTY;
00098
00099 v = 0;
00100 nSV = 0;
00101 }
00102
00103 void COnlineLibLinear::stop_train()
00104 {
00105 float64_t gap = PGmax_new - PGmin_new;
00106
00107 SG_DONE();
00108 SG_INFO("Optimization finished.\n");
00109
00110
00111 for (int32_t i=0; i<w_dim; i++)
00112 v += w[i]*w[i];
00113 v += bias*bias;
00114
00115 SG_INFO("Objective value = %lf\n", v/2);
00116 SG_INFO("nSV = %d\n", nSV);
00117 SG_INFO("gap = %g\n", gap);
00118 }
00119
00120 void COnlineLibLinear::train_one(SGVector<float32_t> ex, float64_t label)
00121 {
00122 alpha_current = 0;
00123 if (label > 0)
00124 y_current = +1;
00125 else
00126 y_current = -1;
00127
00128 QD = diag[y_current + 1];
00129
00130 QD += SGVector<float32_t>::dot(ex.vector, ex.vector, ex.vlen);
00131
00132 if (ex.vlen > w_dim)
00133 {
00134 w = SG_REALLOC(float32_t, w, ex.vlen);
00135 memset(&w[w_dim], 0, (ex.vlen - w_dim)*sizeof(float32_t));
00136 w_dim = ex.vlen;
00137 }
00138
00139 G = SGVector<float32_t>::dot(ex.vector, w, w_dim);
00140 if (use_bias)
00141 G += bias;
00142 G = G*y_current - 1;
00143
00144
00145 C = upper_bound[y_current + 1];
00146 G += alpha_current*diag[y_current + 1];
00147
00148 PG = 0;
00149 if (alpha_current == 0)
00150 {
00151 if (G > PGmax_old)
00152 {
00153 return;
00154 }
00155 else if (G < 0)
00156 PG = G;
00157 }
00158 else if (alpha_current == C)
00159 {
00160 if (G < PGmin_old)
00161 {
00162 return;
00163 }
00164 else if (G > 0)
00165 PG = G;
00166 }
00167 else
00168 PG = G;
00169
00170 PGmax_new = CMath::max(PGmax_new, PG);
00171 PGmin_new = CMath::min(PGmin_new, PG);
00172
00173 if (fabs(PG) > 1.0e-12)
00174 {
00175 float64_t alpha_old = alpha_current;
00176 alpha_current = CMath::min(CMath::max(alpha_current - G/QD, 0.0), C);
00177 d = (alpha_current - alpha_old) * y_current;
00178
00179 for (int32_t i=0; i < w_dim; ++i)
00180 w[i] += d*ex[i];
00181
00182
00183 if (use_bias)
00184 bias += d;
00185 }
00186
00187 v += alpha_current*(alpha_current*diag[y_current + 1] - 2);
00188 if (alpha_current > 0)
00189 nSV++;
00190 }
00191
00192 void COnlineLibLinear::train_example(CStreamingDotFeatures *feature, float64_t label)
00193 {
00194 CStreamingDenseFeatures<float32_t> *feat =
00195 dynamic_cast<CStreamingDenseFeatures<float32_t> *>(feature);
00196 if (feat == NULL)
00197 SG_ERROR("Expected streaming dense feature <float32_t>\n");
00198
00199 train_one(feat->get_vector(), label);
00200 }
00201