svn commit: r1932126 - spamassassin/trunk/lib/Mail/SpamAssassin/Plugin

[email protected]
Newsgroups gmane.mail.spam.spamassassin.cvs
Message-ID <177253180978.3267978.2743422279481180635@svn02-us-east.apache.org>
Author: gbechis
Date: Tue Mar  3 09:56:49 2026
New Revision: 1932126

Log:
correctly retrain if vocabulary size changes

Modified:
   spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/NeuralNetwork.pm

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/NeuralNetwork.pm
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/NeuralNetwork.pm	Tue Mar  3 09:55:38 2026	(r1932125)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/NeuralNetwork.pm	Tue Mar  3 09:56:49 2026	(r1932126)
@@ -633,13 +633,33 @@ sub learn_message {
   if(defined $self->{neural_model} && $self->{neural_model}->num_inputs() == $num_input) {
     $network = $self->{neural_model};
   } else {
-    # Vocabulary size changed, retrain from vocabulary statistics
-    $network = $self->_retrain_from_vocabulary($self->{main}->{conf}, $nn_data_dir, $num_input);
-    if (!defined $network) {
-      # No vocabulary stats available yet, create a fresh network
-      $network = AI::FANN->new_standard($num_input, $num_hidden_neurons, $num_output_neurons);
-      $network->hidden_activation_function(FANN_SIGMOID_STEPWISE);
-      $network->output_activation_function(FANN_SIGMOID_STEPWISE);
+    # Try to load the existing model from disk if not already in memory
+    my $existing_network = $self->{neural_model};
+    if (!defined $existing_network && -f $dataset_path) {
+      eval {
+        $existing_network = AI::FANN->new_from_file($dataset_path);
+        1;
+      } or do {
+        dbg("Failed to load existing model for size check: " . ($@ || 'unknown'));
+      };
+    }
+
+    if (defined $existing_network) {
+      # Vocabulary grew: preserve the trained model by adjusting the training vectors
+      my $model_size = $existing_network->num_inputs();
+      dbg("Vocabulary size changed ($num_input vs model $model_size), adjusting training vectors");
+      $feature_vectors = [ map { _adjust_vector_size($_, $model_size) } @$feature_vectors ];
+      $num_input = $model_size;
+      $network = $existing_network;
+    } else {
+      # No existing model: create a baseline from vocabulary statistics
+      $network = $self->_retrain_from_vocabulary($self->{main}->{conf}, $nn_data_dir, $num_input);
+      if (!defined $network) {
+        # No vocabulary stats available yet, create a fresh network
+        $network = AI::FANN->new_standard($num_input, $num_hidden_neurons, $num_output_neurons);
+        $network->hidden_activation_function(FANN_SIGMOID_STEPWISE);
+        $network->output_activation_function(FANN_SIGMOID_STEPWISE);
+      }
     }
   }
   $network->learning_rate($learning_rate);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.