diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c861d26c..a7acea3b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,7 +42,7 @@ git push origin feature/my-feature Before submitting a contribution: -1. **Follow the code style guidelines** - JABS uses Ruff for linting and formatting +1. **Follow the code style guidelines** - JABS uses Ruff for linting and formatting, and follows the Google docstring style. 2. **Add tests** for new functionality 3. **Update documentation** as needed (docstrings, user guide, developer guide) 4. **Run the test suite** to ensure nothing is broken: `pytest` diff --git a/src/jabs/scripts/classify.py b/src/jabs/scripts/classify.py index 0b313463..55938698 100755 --- a/src/jabs/scripts/classify.py +++ b/src/jabs/scripts/classify.py @@ -137,13 +137,14 @@ def classify_pose( data = Classifier.combine_data(per_frame_features, window_features) if data.shape[0] > 0: - pred = classifier.predict(data, features["frame_indexes"]) + # Get probabilities for all classes pred_prob = classifier.predict_proba(data, features["frame_indexes"]) + # Derive predictions by taking argmax (class with highest probability) + # This is equivalent to predict() but avoids duplicate computation + pred = np.argmax(pred_prob, axis=1).astype(np.int8) + # Keep the probability for the predicted class only. - # The following code uses some - # numpy magic to use the pred array as column indexes - # for each row of the pred_prob array we just computed. pred_prob = pred_prob[np.arange(len(pred_prob)), pred] # Copy results into results matrix diff --git a/src/jabs/ui/classification_thread.py b/src/jabs/ui/classification_thread.py index db2710d5..7b0477a8 100644 --- a/src/jabs/ui/classification_thread.py +++ b/src/jabs/ui/classification_thread.py @@ -133,19 +133,18 @@ def check_termination_requested() -> None: check_termination_requested() if data.shape[0] > 0: - # make predictions - predictions[identity] = self._classifier.predict( - data, feature_values["frame_indexes"] - ) - - # also get the probabilities + # Get probabilities for all classes prob = self._classifier.predict_proba( data, feature_values["frame_indexes"] ) - # Save the probability for the predicted class only. - # The following code uses some - # numpy magic to use the _predictions array as column indexes - # for each row of the 'prob' array we just computed. + + # Derive predictions by taking argmax (class with highest probability) + # This is equivalent to predict() but avoids duplicate computation + # Consider using np.where with a threshold here if we want to be more conservative + # about predictions + predictions[identity] = np.argmax(prob, axis=1).astype(np.int8) + + # Use predictions as column indexes for each row of prob probabilities[identity] = prob[np.arange(len(prob)), predictions[identity]] else: predictions[identity] = np.array(0)