Normalize forest sample weights#3674
Conversation
|
/azp run CI |
|
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Pull request overview
This PR adjusts decision forest training to reduce sensitivity to the absolute scale of sample weights by introducing a weight-rescaling step (max weight scaled to 1) and applying it in both classification and regression forest training paths. It also aligns an internal regression split-selection accumulator type with the higher-precision intermediate type used in the surrounding impurity math.
Changes:
- Added
normalizeWeights()helper to rescale input sample weights before training. - Applied weight normalization in both classification and regression
*TrainBatchKernel::compute()implementations. - Updated a regression split-selection variable (
vBest) to useintermSummFPTypefor consistency with intermediate computations.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| cpp/daal/src/algorithms/dtrees/forest/df_train_dense_default_impl.i | Adds normalizeWeights() helper and required include to create a normalized weights table. |
| cpp/daal/src/algorithms/dtrees/forest/regression/df_regression_train_dense_default_impl.i | Uses normalized weights in training and adjusts split-selection accumulator precision. |
| cpp/daal/src/algorithms/dtrees/forest/classification/df_classification_train_dense_default_impl.i | Uses normalized weights in training. |
| const size_t nRows = weights->getNumberOfRows(); | ||
| if (!nRows) return empty; |
| algorithmFPType maxWeight = 0; | ||
| for (size_t i = 0; i < nRows; ++i) | ||
| { | ||
| if (src[i] > maxWeight) maxWeight = src[i]; | ||
| } | ||
| if (!(maxWeight > 0)) return empty; | ||
|
|
||
| services::SharedPtr<HomogenNumericTableCPU<algorithmFPType, cpu> > normalized = | ||
| HomogenNumericTableCPU<algorithmFPType, cpu>::create(1, nRows, &s); | ||
| if (!s) return empty; | ||
|
|
||
| WriteOnlyRows<algorithmFPType, cpu> dstBlock(normalized.get(), 0, nRows); | ||
| s |= dstBlock.status(); | ||
| if (!s) return empty; | ||
| algorithmFPType * dst = dstBlock.get(); | ||
|
|
||
| for (size_t i = 0; i < nRows; ++i) | ||
| { | ||
| dst[i] = src[i] / maxWeight; | ||
| } |
| ImpurityData right; | ||
| IndexType iBest = -1; | ||
| algorithmFPType vBest; | ||
| intermSummFPType vBest; |
There was a problem hiding this comment.
If you're going to do this, then it makes more sense to make normalizedWeights of intermSummFPType. It also would need to be modified in a lot of other places to be consistent.
There was a problem hiding this comment.
The normalized table can't be intermSummFPType - it's read back as algorithmFPType by _helper.init/ReadRows, so a float32 fit needs a float32 table
There was a problem hiding this comment.
Then please change the dtype in all other places that calculate similar quantities to be consistent.
There was a problem hiding this comment.
I made one other change that I think is related to what you are eluding to, otherwise you're going to need to be more specific as I am not very familiar with these files.
| } | ||
| if (!(maxWeight > 0)) return empty; | ||
|
|
||
| services::SharedPtr<HomogenNumericTableCPU<algorithmFPType, cpu> > normalized = |
There was a problem hiding this comment.
Does this need to be a oneDAL table? It's just a one-dimensional array which could be passed as a unique or shared pointer.
There was a problem hiding this comment.
Downstream functionality (compute, computeForSpecificHelper, TrainBatchTask) all consume NumericTables so it sets up well for those
| if (!s) return empty; | ||
| algorithmFPType * dst = dstBlock.get(); | ||
|
|
||
| for (size_t i = 0; i < nRows; ++i) |
There was a problem hiding this comment.
It could use ?rscl (preferrably) or ?scal from MKL.
There was a problem hiding this comment.
On a second look, if it's going to copy beforehand, maybe it'd make more sense to replace with a vectorized loop. Could also set a pragma for the alignment, given that the new array is allocated through oneDAL.
There was a problem hiding this comment.
I believe your MKL suggestion would be preferable
|
Updated combined CI: http://intel-ci.intel.com/f171b38c-632b-f18e-89b1-d4f5ef20c6a0 |
Description
Fixes test deselected in uxlfoundation/scikit-learn-intelex#3231
Accompanies uxlfoundation/scikit-learn-intelex#3292
Combined CI: http://intel-ci.intel.com/f170e0af-9e7a-f1a7-82dc-d4f5ef20c6a0
Checklist:
Completeness and readability
Testing
Performance