SHOGUN  4.1.0
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 宏定义  
GaussianARDKernel.cpp
浏览该文件的文档.
1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * Written (W) 2015 Wu Lin
8  * Written (W) 2012 Jacob Walker
9  *
10  * Adapted from WeightedDegreeRBFKernel.cpp
11  */
12 
15 
16 #ifdef HAVE_LINALG_LIB
18 #endif
19 
20 using namespace shogun;
21 
23 {
24  init();
25 }
26 
28 {
29 }
30 
31 void CGaussianARDKernel::init()
32 {
33 
34 #ifdef HAVE_LINALG_LIB
35  m_sq_lhs=SGVector<float64_t>();
36  m_sq_rhs=SGVector<float64_t>();
37  SG_ADD(&m_sq_lhs, "sq_lhs", "squared left-hand side", MS_NOT_AVAILABLE);
38  SG_ADD(&m_sq_rhs, "sq_rhs", "squared right-hand side", MS_NOT_AVAILABLE);
39 #endif
40 }
41 
42 float64_t CGaussianARDKernel::distance(int32_t idx_a, int32_t idx_b)
43 {
44  float64_t result=0.0;
45 #ifdef HAVE_LINALG_LIB
46  REQUIRE(lhs, "Left features (lhs) not set!\n")
47  REQUIRE(rhs, "Right features (rhs) not set!\n")
48 
49  if (lhs==rhs && idx_a==idx_b)
50  return result;
51 
52  if (m_ARD_type==KT_SCALAR)
53  {
54  result=(m_sq_lhs[idx_a]+m_sq_rhs[idx_b]-2.0*CDotKernel::compute(idx_a,idx_b));
55  result*=CMath::exp(2.0*m_log_weights[0]);
56  }
57  else
58  {
61  avec=linalg::add(avec, bvec, 1.0, -1.0);
62  result=compute_helper(avec, avec);
63  }
64 #endif /* HAVE_LINALG_LIB */
65  return result/2.0;
66 }
67 
68 #ifdef HAVE_LINALG_LIB
70  : CExponentialARDKernel(size)
71 {
72  init();
73 }
74 
76  CDotFeatures* r, int32_t size)
77  : CExponentialARDKernel(size)
78 {
79  init();
80 }
81 
82 bool CGaussianARDKernel::init(CFeatures* l, CFeatures* r)
83 {
84  bool status=CExponentialARDKernel::init(l,r);
85 
86  if (m_ARD_type==KT_SCALAR)
87  precompute_squared();
88 
89  return status;
90 }
91 
92 SGVector<float64_t> CGaussianARDKernel::precompute_squared_helper(CDotFeatures* df)
93 {
94  REQUIRE(df, "Features not set\n")
95  int32_t num_vec=df->get_num_vectors();
96  SGVector<float64_t> sq(num_vec);
97  for (int32_t i=0; i<num_vec; i++)
98  sq[i]=df->dot(i,df, i);
99  return sq;
100 }
101 
102 void CGaussianARDKernel::precompute_squared()
103 {
104  if (!lhs || !rhs)
105  return;
106  SG_SPRINT("called\n");
107  m_sq_lhs=precompute_squared_helper((CDotFeatures*) lhs);
108 
109  if (lhs==rhs)
110  m_sq_rhs=m_sq_lhs;
111  else
112  m_sq_rhs=precompute_squared_helper((CDotFeatures*) rhs);
113 }
114 
115 
117 {
118  if (kernel->get_kernel_type()!=K_GAUSSIANARD)
119  {
120  SG_SERROR("Provided kernel is not of type CGaussianARDKernel!\n");
121  }
122 
123  /* since an additional reference is returned */
124  SG_REF(kernel);
125  return (CGaussianARDKernel*)kernel;
126 }
127 
128 float64_t CGaussianARDKernel::compute_helper(SGVector<float64_t> avec, SGVector<float64_t>bvec)
129 {
130  SGMatrix<float64_t> left;
131  SGMatrix<float64_t> left_transpose;
132  float64_t scalar_weight=1.0;
133  if (m_ARD_type==KT_SCALAR)
134  {
135  left=SGMatrix<float64_t>(avec.vector,1,avec.vlen,false);
136  scalar_weight=CMath::exp(m_log_weights[0]);
137  }
138  else if(m_ARD_type==KT_FULL || m_ARD_type==KT_DIAG)
139  {
140  left_transpose=get_weighted_vector(avec);
141  left=SGMatrix<float64_t>(left_transpose.matrix,1,left_transpose.num_rows,false);
142  }
143  else
144  SG_ERROR("Unsupported ARD type\n");
145  SGMatrix<float64_t> right=compute_right_product(bvec, scalar_weight);
146  SGMatrix<float64_t> res=linalg::matrix_product(left, right);
147  return res[0]*scalar_weight;
148 }
149 
150 float64_t CGaussianARDKernel::compute_gradient_helper(SGVector<float64_t> avec,
152 {
153  float64_t result=0.0;
154 
155  if(m_ARD_type==KT_DIAG)
156  result=2.0*avec[index]*bvec[index]*CMath::exp(2.0*m_log_weights[index]);
157  else
158  {
160 
161  if (m_ARD_type==KT_SCALAR)
162  {
163  SGMatrix<float64_t> left(avec.vector,1,avec.vlen,false);
164  SGMatrix<float64_t> right(bvec.vector,bvec.vlen,1,false);
165  res=linalg::matrix_product(left, right);
166  result=2.0*res[0]*CMath::exp(2.0*m_log_weights[0]);
167  }
168  else if(m_ARD_type==KT_FULL)
169  {
170  int32_t row_index=0;
171  int32_t col_index=index;
172  int32_t offset=m_weights_rows;
173  int32_t total_offset=0;
174  while(col_index>=offset && offset>0)
175  {
176  col_index-=offset;
177  total_offset+=offset;
178  offset--;
179  row_index++;
180  }
181  col_index+=row_index;
182 
183  SGVector<float64_t> row_vec=SGVector<float64_t>(m_log_weights.vector+total_offset,m_weights_rows-row_index,false);
184  row_vec[0]=CMath::exp(row_vec[0]);
185 
186  SGMatrix<float64_t> row_vec_r(row_vec.vector,row_vec.vlen,1,false);
187  SGMatrix<float64_t> left(avec.vector+row_index,1,avec.vlen-row_index,false);
188 
189  res=linalg::matrix_product(left, row_vec_r);
190  result=res[0]*bvec[col_index];
191 
192  SGMatrix<float64_t> row_vec_l(row_vec.vector,1,row_vec.vlen,false);
193  SGMatrix<float64_t> right(bvec.vector+row_index,bvec.vlen-row_index,1,false);
194 
195  res=linalg::matrix_product(row_vec_l, right);
196  result+=res[0]*avec[col_index];
197 
198  if(row_index==col_index)
199  result*=row_vec[0];
200  row_vec[0]=CMath::log(row_vec[0]);
201  }
202  else
203  {
204  SG_ERROR("Unsupported ARD type\n");
205  }
206 
207  }
208  return result*scale;
209 }
210 
211 
213  const TParameter* param, index_t index)
214 {
215  REQUIRE(param, "Param not set\n");
216  REQUIRE(lhs , "Left features not set!\n");
217  REQUIRE(rhs, "Right features not set!\n");
218 
219  if (lhs==rhs)
220  {
221  if (!strcmp(param->m_name, "log_weights"))
222  {
223  SGVector<float64_t> derivative(num_lhs);
224  derivative.zero();
225  return derivative;
226  }
227  }
228  else
229  {
230  int32_t length=CMath::min(num_lhs, num_rhs);
231  SGVector<float64_t> derivative(length);
232  check_weight_gradient_index(index);
233  for (index_t j=0; j<length; j++)
234  {
235  if (!strcmp(param->m_name, "log_weights") )
236  {
237  if (m_ARD_type==KT_SCALAR)
238  {
239  float64_t dist=distance(j,j);
240  derivative[j]=CMath::exp(-dist)*(-dist*2.0);
241  }
242  else
243  {
246  derivative[j]=get_parameter_gradient_helper(param,index,j,j,avec,bvec);
247  }
248 
249  }
250  }
251  return derivative;
252  }
253 
254  SG_ERROR("Can't compute derivative wrt %s parameter\n", param->m_name);
255  return SGVector<float64_t>();
256 }
257 
258 
259 float64_t CGaussianARDKernel::get_parameter_gradient_helper(
260  const TParameter* param, index_t index, int32_t idx_a,
261  int32_t idx_b, SGVector<float64_t> avec, SGVector<float64_t> bvec)
262 {
263  REQUIRE(param, "Param not set\n");
264 
265  if (!strcmp(param->m_name, "log_weights"))
266  {
267  bvec=linalg::add(avec, bvec, 1.0, -1.0);
268  float64_t scale=-kernel(idx_a,idx_b)/2.0;
269  return compute_gradient_helper(bvec, bvec, scale, index);
270  }
271  else
272  {
273  SG_ERROR("Can't compute derivative wrt %s parameter\n", param->m_name);
274  return 0.0;
275  }
276 }
277 
279  const TParameter* param, index_t index)
280 {
281  REQUIRE(param, "Param not set\n");
282  REQUIRE(lhs , "Left features not set!\n");
283  REQUIRE(rhs, "Right features not set!\n");
284 
285  if (!strcmp(param->m_name, "log_weights"))
286  {
287  SGMatrix<float64_t> derivative(num_lhs, num_rhs);
288  check_weight_gradient_index(index);
289  for (index_t j=0; j<num_lhs; j++)
290  {
292  for (index_t k=0; k<num_rhs; k++)
293  {
294  if (m_ARD_type==KT_SCALAR)
295  {
296  float64_t dist=distance(j,k);
297  derivative(j,k)=CMath::exp(-dist)*(-dist*2.0);
298  }
299  else
300  {
302  derivative(j,k)=get_parameter_gradient_helper(param,index,j,k,avec,bvec);
303  }
304  }
305  }
306  return derivative;
307  }
308  else
309  {
310  SG_ERROR("Can't compute derivative wrt %s parameter\n", param->m_name);
311  return SGMatrix<float64_t>();
312  }
313 }
314 #endif /* HAVE_LINALG_LIB */
SGVector< float64_t > m_log_weights
int32_t index_t
Definition: common.h:62
int32_t num_rhs
number of feature vectors on right hand side
Definition: Kernel.h:1069
Vector::Scalar dot(Vector a, Vector b)
Definition: Redux.h:56
virtual float64_t distance(int32_t idx_a, int32_t idx_b)
parameter struct
#define SG_ERROR(...)
Definition: SGIO.h:129
#define REQUIRE(x,...)
Definition: SGIO.h:206
float64_t kernel(int32_t idx_a, int32_t idx_b)
Definition: Kernel.h:206
virtual float64_t compute(int32_t idx_a, int32_t idx_b)
Definition: DotKernel.h:134
Features that support dot products among other operations.
Definition: DotFeatures.h:44
#define SG_REF(x)
Definition: SGObject.h:51
index_t num_rows
Definition: SGMatrix.h:376
Gaussian Kernel with Automatic Relevance Detection computed on CDotFeatures.
index_t vlen
Definition: SGVector.h:494
#define SG_SPRINT(...)
Definition: SGIO.h:180
void add(Matrix A, Matrix B, Matrix C, typename Matrix::Scalar alpha=1.0, typename Matrix::Scalar beta=1.0)
Definition: Core.h:65
double float64_t
Definition: common.h:50
virtual SGVector< float64_t > get_feature_vector(int32_t idx, CFeatures *hs)
int32_t num_lhs
number of feature vectors on left hand side
Definition: Kernel.h:1067
CFeatures * rhs
feature vectors to occur on right hand side
Definition: Kernel.h:1061
static CKernel * obtain_from_generic(CSGObject *kernel)
Definition: Kernel.cpp:896
all of classes and functions are contained in the shogun namespace
Definition: class_list.h:18
virtual EKernelType get_kernel_type()=0
CFeatures * lhs
feature vectors to occur on left hand side
Definition: Kernel.h:1059
The class Features is the base class of all feature objects.
Definition: Features.h:68
static T min(T a, T b)
Definition: Math.h:157
#define SG_SERROR(...)
Definition: SGIO.h:179
void scale(Matrix A, Matrix B, typename Matrix::Scalar alpha)
Definition: Core.h:93
static float64_t exp(float64_t x)
Definition: Math.h:621
virtual SGMatrix< float64_t > get_parameter_gradient(const TParameter *param, index_t index=-1)
Definition: Kernel.h:850
static float64_t log(float64_t v)
Definition: Math.h:922
The Kernel base class.
Definition: Kernel.h:158
#define SG_ADD(...)
Definition: SGObject.h:81
Exponential Kernel with Automatic Relevance Detection computed on CDotFeatures.
virtual SGVector< float64_t > get_parameter_gradient_diagonal(const TParameter *param, index_t index=-1)
Definition: Kernel.h:864

SHOGUN 机器学习工具包 - 项目文档