Skip to content

Commit 71979bf

Browse files
committed
fix: warn when MC dropout not injected
1 parent ee1fb2b commit 71979bf

1 file changed

Lines changed: 27 additions & 16 deletions

File tree

src/PredictionModelBuilder.cs

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,7 @@ private static T FitTemperatureFromProbabilities(Tensor<T> probabilities, Vector
722722
{
723723
var eps = numOps.FromDouble(1e-12);
724724
var sumTolerance = numOps.FromDouble(1e-3);
725+
var uniformProbability = numOps.Divide(numOps.One, numOps.FromDouble(classes));
725726
var logits = new Matrix<T>(batch, classes);
726727
var flat = probabilities.ToVector();
727728

@@ -738,23 +739,22 @@ private static T FitTemperatureFromProbabilities(Tensor<T> probabilities, Vector
738739
sum = numOps.Add(sum, p);
739740
}
740741

741-
if (numOps.LessThan(sum, eps))
742-
{
743-
throw new ArgumentException("Temperature scaling requires per-sample probabilities with a positive sum.", nameof(probabilities));
744-
}
745-
746-
var shouldNormalize = numOps.GreaterThan(numOps.Abs(numOps.Subtract(sum, numOps.One)), sumTolerance);
742+
var fallbackToUniform = numOps.LessThan(sum, eps);
743+
var shouldNormalize = !fallbackToUniform && numOps.GreaterThan(numOps.Abs(numOps.Subtract(sum, numOps.One)), sumTolerance);
747744

748745
for (int c = 0; c < classes; c++)
749746
{
750-
var p = flat[i * classes + c];
751-
if (numOps.LessThan(p, numOps.Zero))
752-
{
753-
p = numOps.Zero;
754-
}
755-
if (shouldNormalize)
747+
var p = fallbackToUniform ? uniformProbability : flat[i * classes + c];
748+
if (!fallbackToUniform)
756749
{
757-
p = numOps.Divide(p, sum);
750+
if (numOps.LessThan(p, numOps.Zero))
751+
{
752+
p = numOps.Zero;
753+
}
754+
if (shouldNormalize)
755+
{
756+
p = numOps.Divide(p, sum);
757+
}
758758
}
759759
if (numOps.LessThan(p, eps))
760760
{
@@ -861,24 +861,32 @@ private static void ApplyUncertaintyQuantificationIfConfigured(
861861
"ConfigureModel(new NeuralNetworkModel<T>(...)) to enable Monte Carlo Dropout uncertainty estimation.");
862862
}
863863

864-
TryInjectMonteCarloDropoutLayers(neuralNetworkModel, options);
864+
var injectedCount = TryInjectMonteCarloDropoutLayers(neuralNetworkModel, options);
865+
if (injectedCount == 0)
866+
{
867+
System.Diagnostics.Debug.WriteLine(
868+
"Warning: Monte Carlo Dropout was enabled but no dropout layers were injected automatically. " +
869+
"This can happen if the network has no suitable activation layers or uses a non-standard architecture. " +
870+
"Consider inserting MCDropoutLayer explicitly in your network definition.");
871+
}
865872
}
866873

867-
private static void TryInjectMonteCarloDropoutLayers(
874+
private static int TryInjectMonteCarloDropoutLayers(
868875
Models.NeuralNetworkModel<T> neuralNetworkModel,
869876
UncertaintyQuantificationOptions options)
870877
{
871878
var layers = neuralNetworkModel.Network.LayersReadOnly;
872879
if (layers.OfType<MCDropoutLayer<T>>().Any())
873880
{
874-
return;
881+
return -1;
875882
}
876883

877884
if (options.MonteCarloDropoutRate <= 0 || options.MonteCarloDropoutRate >= 1)
878885
{
879886
throw new ArgumentException("MonteCarloDropoutRate must be between 0 and 1.", nameof(options));
880887
}
881888

889+
var injectedCount = 0;
882890
for (int i = 0; i < layers.Count - 1; i++)
883891
{
884892
if (layers[i] is not ActivationLayer<T>)
@@ -898,8 +906,11 @@ private static void TryInjectMonteCarloDropoutLayers(
898906

899907
int? seed = options.RandomSeed.HasValue ? options.RandomSeed.Value + i : (int?)null;
900908
neuralNetworkModel.Network.InsertLayerIntoCollection(i + 1, new MCDropoutLayer<T>(options.MonteCarloDropoutRate, mcMode: false, randomSeed: seed));
909+
injectedCount++;
901910
i++;
902911
}
912+
913+
return injectedCount;
903914
}
904915

905916
/// <summary>

0 commit comments

Comments
 (0)