forked from VowpalWabbit/vowpal_wabbit
-
Notifications
You must be signed in to change notification settings - Fork 3
/
gd.h
91 lines (76 loc) · 3.43 KB
/
gd.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
Copyright (c) by respective owners including Yahoo!, Microsoft, and
individual contributors. All rights reserved. Released under a BSD
license as described in the file LICENSE.
*/
#pragma once
#ifdef __FreeBSD__
#include <sys/socket.h>
#endif
#include "parse_regressor.h"
#include "constant.h"
#include "interactions.h"
namespace GD{
LEARNER::base_learner* setup(vw& all);
struct gd;
float finalize_prediction(shared_data* sd, float ret);
void print_audit_features(vw&, example& ec);
void save_load_regressor(vw& all, io_buf& model_file, bool read, bool text);
void save_load_online_state(vw& all, io_buf& model_file, bool read, bool text, GD::gd *g = nullptr);
struct multipredict_info { size_t count; size_t step; polyprediction* pred; regressor* reg; /* & for l1: */ float gravity; };
inline void vec_add_multipredict(multipredict_info& mp, const float fx, uint32_t fi) {
if ((-1e-10 < fx) && (fx < 1e-10)) return;
weight*w = mp.reg->weight_vector;
size_t mask = mp.reg->weight_mask;
polyprediction* p = mp.pred;
fi &= mask;
uint32_t top = fi + (mp.count-1) * mp.step;
if (top <= mask) {
weight* last = w + top;
w += fi;
for (; w <= last; w += mp.step, ++p)
p->scalar += fx * *w;
} else // TODO: this could be faster by unrolling into two loops
for (size_t c=0; c<mp.count; ++c, fi += mp.step, ++p) {
fi &= mask;
p->scalar += fx * w[fi];
}
}
// iterate through one namespace (or its part), callback function T(some_data_R, feature_value_x, feature_weight)
template <class R, void (*T)(R&, const float, float&)>
inline void foreach_feature(weight* weight_vector, size_t weight_mask, feature* begin, feature* end, R& dat, uint32_t offset=0, float mult=1.)
{
for (feature* f = begin; f != end; ++f)
T(dat, mult*f->x, weight_vector[(f->weight_index + offset) & weight_mask]);
}
// iterate through one namespace (or its part), callback function T(some_data_R, feature_value_x, feature_index)
template <class R, void (*T)(R&, float, uint32_t)>
void foreach_feature(weight* /*weight_vector*/, size_t /*weight_mask*/, feature* begin, feature* end, R&dat, uint32_t offset=0, float mult=1.)
{
for (feature* f = begin; f != end; ++f)
T(dat, mult*f->x, f->weight_index + offset);
}
// iterate through all namespaces and quadratic&cubic features, callback function T(some_data_R, feature_value_x, S)
// where S is EITHER float& feature_weight OR uint32_t feature_index
template <class R, class S, void (*T)(R&, float, S)>
inline void foreach_feature(vw& all, example& ec, R& dat)
{
uint32_t offset = ec.ft_offset;
for (unsigned char* i = ec.indices.begin; i != ec.indices.end; i++)
foreach_feature<R,T>(all.reg.weight_vector, all.reg.weight_mask, ec.atomics[*i].begin, ec.atomics[*i].end, dat, offset);
INTERACTIONS::generate_interactions<R,S,T>(all, ec, dat);
}
// iterate through all namespaces and quadratic&cubic features, callback function T(some_data_R, feature_value_x, feature_weight)
template <class R, void (*T)(R&, float, float&)>
inline void foreach_feature(vw& all, example& ec, R& dat)
{
foreach_feature<R,float&,T>(all, ec, dat);
}
inline void vec_add(float& p, const float fx, float& fw) { p += fw * fx; }
inline float inline_predict(vw& all, example& ec)
{
float temp = ec.l.simple.initial;
foreach_feature<float, vec_add>(all, ec, temp);
return temp;
}
}