| 7 | namespace FM { |
| 8 | |
| 9 | class FMWorker { |
| 10 | public: |
| 11 | virtual void init() { |
| 12 | REGISTER_CHILD_CUSTOMER(name() + "_w", w_, name()); |
| 13 | REGISTER_CHILD_CUSTOMER(name() + "_v", V_, name()); |
| 14 | k_ = 1; |
| 15 | } |
| 16 | virtual bool readMinibatch(StreamReader<Real>& reader, Minibatch* data) { |
| 17 | // read a minibatch |
| 18 | MatrixPtrList<Real> ins; |
| 19 | bool ret = reader.readMatrices(1000, &ins); |
| 20 | CHECK_EQ(ins.size(), 2); |
| 21 | // LL << ins[0]->debugString() << "\n" << ins[1]->debugString(); |
| 22 | data->label = ins[0]; |
| 23 | |
| 24 | // find all unique features, |
| 25 | SArray<Key> uniq_key; |
| 26 | SArray<uint8> key_cnt; |
| 27 | data->localizer = LocalizerPtr<Key, Real>(new Localizer<Key, Real>()); |
| 28 | data->localizer->countUniqIndex(ins[1], &uniq_key, &key_cnt); |
| 29 | |
| 30 | // pull the features and weights from servers with tails filtered |
| 31 | MessagePtr msg(new Message(kServerGroup)); |
| 32 | msg->task.set_key_channel(batch_id_); |
| 33 | msg->setKey(uniq_key); |
| 34 | msg->addValue(key_cnt); |
| 35 | msg->addFilter(FilterConfig::KEY_CACHING); |
| 36 | auto tail = w_->set(msg)->mutable_tail_filter(); |
| 37 | tail->set_insert_count(true); |
| 38 | tail->set_query_key(10); |
| 39 | tail->set_query_value(true); |
| 40 | data->pull_time = w_->pull(msg); |
| 41 | |
| 42 | data->batch_id = batch_id_ ++; |
| 43 | return ret; |
| 44 | } |
| 45 | virtual void computeGradient(Minibatch& data) { |
| 46 | // release some memory |
| 47 | int id = data.batch_id; |
| 48 | if (pre_batch_id_ >= 0) { |
| 49 | w_->clear(pre_batch_id_); |
| 50 | pre_batch_id_ = id; |
| 51 | } |
| 52 | // waiting the model working set |
| 53 | w_->waitOutMsg(kServerGroup, data.pull_time); |
| 54 | |
| 55 | // localize the feature matrix |
| 56 | auto X = data.localizer->remapIndex(w_->key(id)); |
| 57 | SArray<Real> y = data.label->value(); |
| 58 | CHECK_EQ(X->rows(), y.size()); |
| 59 | |
| 60 | SArray<Real> w = w_->value(id); |
| 61 | SArray<Real> py(y.size()); |
| 62 | py.arr() = *X * w.arr(); |
| 63 | |
| 64 | // progress |
| 65 | Real objv = log( 1 + exp( - y.arr() * py.arr() )).sum(); |
| 66 | Real auc = Evaluation<Real>::auc(y, py); |
nothing calls this directly
no outgoing calls
no test coverage detected