74 while (src.
end() != i)
83 auto out = std::make_shared<M>(len, tag_dh.size());
86 uint64_t current_timepoint = 0;
87 while (src.
end() != it)
89 while(!(*it).is_word() && src.
end() != it)
98 for (
size_t feat_idx = 0; feat_idx < tag_dh.size(); ++feat_idx)
100 const std::string& feat_val = fe.feat_value(*it, feat_idx);
101 StringDict::key_t idx = dynamic_pointer_cast<StringDict>(tag_dh[feat_idx])->get_idx(feat_val);
102 out->set(current_timepoint, feat_idx, idx);
106 if (current_timepoint == std::numeric_limits<uint64_t>::max())
108 throw std::overflow_error(
"Too much words in the dataset.");
142 feat_extractor, 0,
"");
145 BiRnnClassifierForNer model(
nullptr);
149 model = BiRnnClassifierForNer();
160 dh.erase(dh.begin());
165 vector<CoNLLUToTorchMatrix::feature_descr_t> feat_descr;
167 std::shared_ptr<FastTextVectorizerToTorchMatrix> p_embd;
172 p_embd = std::make_shared<FastTextVectorizerToTorchMatrix>(params.
m_embeddings_fn);
173 assert(
nullptr != p_embd.get());
174 feat_descr.push_back({ CoNLLUToTorchMatrix::str_feature,
"form", p_embd });
176 catch (
const exception& e)
178 cerr << e.what() << endl;
183 cerr <<
"Something wrong happened while loading \""
189 shared_ptr<DirectDict<TorchMatrix<float>>> p_eos;
194 throw std::invalid_argument(
"Can't use EOS as both input and output");
197 p_eos = std::make_shared<DirectDict<TorchMatrix<float>>>(2);
198 assert(
nullptr != p_embd);
199 feat_descr.push_back({ CoNLLUToTorchMatrix::int_feature,
"eos", p_eos });
202 vector<CoNLLUToTorchMatrix::embeddable_feature_descr_t> embd_feat_descr;
205 embd_feat_descr.push_back({
206 CoNLLUToTorchMatrix::str_feature,
208 int(model->get_embd_descr()[0].m_dim),
209 model->get_dicts()[0]
214 assert(dh[0]->size() > 1);
215 embd_feat_descr.push_back({
216 CoNLLUToTorchMatrix::str_feature,
223 assert(feat_descr.size() > 0 || embd_feat_descr.size() > 0);
227 CoNLLUToTorchMatrix::vectorization_t train_input
229 CoNLLUToTorchMatrix::vectorization_t dev_input
232 shared_ptr<TorchMatrix<int64_t>> train_gold
237 shared_ptr<TorchMatrix<int64_t>> dev_gold
242 if (train_input.first && train_input.second && train_input.first->size() != train_input.second->size())
244 std::cerr <<
"ERROR: train set length missmatch: "
245 << train_input.first->
size()
246 <<
" " << train_input.second->size() << std::endl;
247 throw runtime_error(
"Train set length missmatch");
250 if ((train_input.first && train_input.first->size() != train_gold->size())
251 || (train_input.second && train_input.second->size() != train_gold->size()))
253 std::cerr <<
"ERROR: train set length (input != gold): "
254 << (train_input.first ? train_input.first->size() : train_input.second->size())
255 <<
" " << train_gold->size() << std::endl;
256 throw runtime_error(
"Train set length missmatch (input != gold)");
261 vector<embd_descr_t> embd_descr = vectorizer.get_embd_descr();
262 embd_descr.emplace_back(
"raw", train_input.second->get_tensor().size(1), 0);
264 model = BiRnnClassifierForNer(std::move(dh),
267 feat_extractor.
feats(),
277 train_input.first->to(device);
278 train_input.second->to(device);
279 train_gold->to(device);
281 dev_input.first->to(device);
282 dev_input.second->to(device);
283 dev_gold->to(device);
291 shared_ptr<torch::optim::Optimizer> optimizer;
293 if (opt_name ==
"adam")
295 optimizer = make_shared<torch::optim::Adam>(model->parameters(),
298 .betas({params.m_beta_one, params.m_beta_two}));
300 else if (opt_name ==
"sgd")
302 optimizer = make_shared<torch::optim::SGD>(model->parameters(),
308 throw runtime_error(
"Unknown optimizer: " + opt_name);
312 feat_extractor.
feats(),
313 *(train_input.first.get()), *(train_input.second.get()), *(train_gold.get()),
314 *(dev_input.first.get()), *(dev_input.second.get()), *(dev_gold.get()),
315 *optimizer, min_perf, device);
317 std::cerr <<
"train_tag: Optimizer " << opt_name <<
" stopped at " << min_perf << std::endl;