Examples contains all the training examples that SDCA uses for a mini-batch.
| 233 | |
| 234 | // Examples contains all the training examples that SDCA uses for a mini-batch. |
| 235 | Status Examples::SampleAdaptiveProbabilities( |
| 236 | const int num_loss_partitions, const Regularizations& regularization, |
| 237 | const ModelWeights& model_weights, |
| 238 | const TTypes<float>::Matrix example_state_data, |
| 239 | const std::unique_ptr<DualLossUpdater>& loss_updater, |
| 240 | const int num_weight_vectors) { |
| 241 | if (num_weight_vectors != 1) { |
| 242 | return errors::InvalidArgument( |
| 243 | "Adaptive SDCA only works with binary SDCA, " |
| 244 | "where num_weight_vectors should be 1."); |
| 245 | } |
| 246 | // Compute the probabilities |
| 247 | for (int example_id = 0; example_id < num_examples(); ++example_id) { |
| 248 | const Example& example = examples_[example_id]; |
| 249 | const double example_weight = example.example_weight(); |
| 250 | float label = example.example_label(); |
| 251 | const Status conversion_status = loss_updater->ConvertLabel(&label); |
| 252 | const ExampleStatistics example_statistics = |
| 253 | example.ComputeWxAndWeightedExampleNorm(num_loss_partitions, |
| 254 | model_weights, regularization, |
| 255 | num_weight_vectors); |
| 256 | const double kappa = example_state_data(example_id, 0) + |
| 257 | loss_updater->PrimalLossDerivative( |
| 258 | example_statistics.wx[0], label, 1.0); |
| 259 | probabilities_[example_id] = example_weight * |
| 260 | sqrt(examples_[example_id].squared_norm_ + |
| 261 | regularization.symmetric_l2() * |
| 262 | loss_updater->SmoothnessConstant()) * |
| 263 | std::abs(kappa); |
| 264 | } |
| 265 | |
| 266 | // Sample the index |
| 267 | random::DistributionSampler sampler(probabilities_); |
| 268 | GuardedPhiloxRandom generator; |
| 269 | generator.Init(0, 0); |
| 270 | auto local_gen = generator.ReserveSamples32(num_examples()); |
| 271 | random::SimplePhilox random(&local_gen); |
| 272 | std::random_device rd; |
| 273 | std::mt19937 gen(rd()); |
| 274 | std::uniform_real_distribution<> dis(0, 1); |
| 275 | |
| 276 | // We use a decay of 10: the probability of an example is divided by 10 |
| 277 | // once that example is picked. A good approximation of that is to only |
| 278 | // keep a picked example with probability (1 / 10) ^ k where k is the |
| 279 | // number of times we already picked that example. We add a num_retries |
| 280 | // to avoid taking too long to sample. We then fill the sampled_index with |
| 281 | // unseen examples sorted by probabilities. |
| 282 | int id = 0; |
| 283 | int num_retries = 0; |
| 284 | while (id < num_examples() && num_retries < num_examples()) { |
| 285 | int picked_id = sampler.Sample(&random); |
| 286 | if (dis(gen) > MathUtil::IPow(0.1, sampled_count_[picked_id])) { |
| 287 | num_retries++; |
| 288 | continue; |
| 289 | } |
| 290 | sampled_count_[picked_id]++; |
| 291 | sampled_index_[id++] = picked_id; |
| 292 | } |
no test coverage detected