Skip to content

ElenaViewSynthesis/Fine-Grained-Knife-Classification-using-DCNN

Repository files navigation

Fine-Grained Knife Classification using DCNN

This repository contains PyTorch code and experiment artifacts for fine-grained knife image classification. The project trains pretrained convolutional image classifiers, mainly EfficientNet and DenseNet variants from timm, to classify knife images into 192 classes.

The code appears to have been developed and run in Google Colab with the dataset mounted from Google Drive at /content/drive/My Drive/Knives.

Repository Contents

Path Description
train.py Training entry point. Loads train.csv and val.csv, fine-tunes a pretrained timm model, logs training/validation metrics, saves checkpoints, and writes plots.
test.py Evaluation entry point. Loads test.csv, restores a saved model checkpoint, and reports test mAP.
data.py Custom knifeDataset class for reading image paths from CSV files and applying train/validation/test transforms.
config.py Active hyperparameter configuration: class count, image size, batch size, epochs, and learning rate.
utils.py Logging, metric helpers, average meters, checkpoint helper, and loss utilities.
requirements.txt Pinned Python package versions used by the project.
train.csv, val.csv, test.csv Dataset index files with Id,Label columns. The image files themselves are not included in this repository.
Knife.ipynb Colab notebook used to mount Drive, install dependencies, and run training/testing commands.
Experiments/ Experiment notebook, config snapshots, metric plots, and a training log.
Paper/ Project report files in PDF/DOCX format.

Dataset

The CSV files use two columns:

  • Id: relative path to an image, for example ./Train/.../IMG_4107.JPEG
  • Label: integer class id

Current CSV sizes:

Split Rows Distinct labels in CSV
Train 9,624 192
Validation 400 154
Test 351 109

The scripts expect the full dataset to exist under:

/content/drive/My Drive/Knives

Expected layout:

/content/drive/My Drive/Knives/
  train.csv
  val.csv
  test.csv
  Train/
  Test/
  Model_Checkpoints/
  FinalPlots/

train.py prepends /content/drive/My Drive/Knives/ to the relative image paths in train.csv and val.csv. test.py reads /content/drive/My Drive/Knives/test.csv; if running locally instead of Colab, update the hard-coded paths in train.py, test.py, and, if needed, data.py.

Environment Setup

The pinned dependencies are:

numpy==1.21.5
opencv_python_headless==4.7.0.72
pandas==1.4.4
Pillow==10.0.1
scikit_learn==1.0.2
timm==0.6.12
torch==1.12.1
torchvision==0.13.1

Install them with:

pip install -r requirements.txt

CUDA is strongly recommended. The current scripts call .cuda() directly in several places, so CPU-only execution requires code changes.

Configuration

The active settings are defined in config.py:

n_classes = 192
img_weight = 224
img_height = 224
batch_size = 16
epochs = 11
learning_rate = 0.00005

The default model in train.py is:

model_variant_name = 'tf_efficientnet_b0'

Other model variants are present as commented options, including:

  • densenet121
  • densenet264
  • tf_efficientnet_b6
  • deit_tiny_patch16_224

DenseNet models are composed of dense blocks, where each layer receives feature maps from all preceding layers in the same block. The growth rate, k, controls how many new feature maps each layer contributes to the block, influencing model capacity and feature reuse.

Historical config snapshots are stored in Experiments/config (2).py, Experiments/config (3).py, and Experiments/config (4).py.

Hyperparameter Optimisation

The experiments include hyperparameter optimisation around optimiser choice, learning rate, weight decay, and momentum.

  • The learning rate, eta, determines the gradient descent step size during optimisation.
  • L2 regularisation, controlled by weight decay lambda, encourages the models to learn more generalizable representations of knife images.
  • Momentum was considered with coefficient values in the [0.5, 0.9] range.
  • Momentum is integrated into the SGD optimiser to improve the convergence of stochastic gradient descent. During EfficientNet-B6 and DenseNet264 training, it influenced the learning process and helped the optimiser escape local minima.

Optimizer Comparison Based on mAP Convergence

The optimizer comparison tracks mAP progression over 10 epochs for Adam, RMSprop, and SGD.

SGD shows the fastest and most stable early convergence, reaching 0.58 mAP by epoch 2 and around 0.66-0.68 mAP by epochs 3-10. RMSprop also converges strongly, reaching 0.58 mAP by epoch 3 and stabilising near 0.68 mAP from epoch 4 onward.

Adam improves more slowly and less smoothly. It starts below 0.30 mAP until epoch 3, but eventually catches up and reaches similar final performance of around 0.68-0.69 mAP by epoch 10.

Comparison of Learning Rate Schedulers

The scheduler comparison evaluates the best mAP values obtained with CosineAnnealingLR and StepLR under three learning rates: 0.01, 0.001, and 0.0001.

Both schedulers show similar performance, with the strongest results achieved at lr = 0.001, reaching approximately 0.68 mAP. The learning rate 0.01 performs noticeably worse for both schedulers, staying close to 0.60 mAP.

Overall, StepLR and CosineAnnealingLR behave comparably, while lower learning rates provide more stable and effective fine-tuning.

Training

In the original Colab workflow:

python3 /content/drive/MyDrive/Knives/train.py

From the repository root, after adjusting dataset paths if needed:

python3 train.py

Training behavior:

  • Uses knifeDataset with image resize to 224 x 224.
  • Applies data augmentation during training: color jitter, random rotation, random vertical flip, and random horizontal flip.
  • Uses ImageNet normalization for all splits.
  • Creates a pretrained timm model with num_classes=192.
  • Uses Adam with cosine annealing learning-rate scheduling.
  • Uses cross-entropy loss.
  • Computes validation mAP@5 after each epoch.
  • Saves model weights every 4 epochs using names like Knife-Effb0-E4.pt.
  • Writes final training/validation loss and validation mAP plots under FinalPlots/<model_variant_name>/.

Evaluation

test.py loads the test CSV, creates a test dataloader, restores model weights, and prints mAP:

python3 test.py

By default it expects weights at:

logs/Knife-Effb0-E9.pt

Update this line in test.py if the checkpoint filename or location is different:

model.load_state_dict(torch.load('logs/Knife-Effb0-E9.pt'))

Recorded Results

The notebooks and experiment log include several recorded mAP values:

Experiment note Recorded test mAP
EfficientNet-B0, batch 32, 15 epochs, lr 0.0001 0.6180
EfficientNet-B0, batch 64, 20 epochs, lr 0.001 0.6231
EfficientNet-B0, batch 48, 20 epochs, lr 0.0005 0.6365
EfficientNet-B6, batch 48, 40 epochs, lr 0.0005 0.6785
Later EfficientNet run marked "try 60 epochs" 0.7316
DenseNet121, batch 64, 22 epochs, lr 0.0001 0.6433
DenseNet121, batch 64, 32 epochs, lr 0.0001 0.6536
DenseNet121, batch 32, 32 epochs, lr 0.0001 0.6829
DenseNet121, batch 16, 36 epochs, lr 0.0001 0.6800

Experiments/%s_log_train.txt also records validation mAP during one run, reaching approximately 0.715 at epoch 16.

Training Curves

The experiment artifacts include two training-curve plots:

  • Training and Validation Loss over Epochs
  • Validation Mean Average Precision (mAP) over Epochs

Observation 3: Slight rises were detected in validation loss during EfficientNet-B6 and DenseNet264 training. These rises were attributed to the use of a relatively high learning rate. The oscillations were expected, because modifying the models caused groups of knife images to be misclassified at a time, significantly lowering or raising the mAP.

When training the baseline EfficientNet-B0 model, the validation loss decreased during the first 5 epochs, then gradually reduced close to 0.

Known Caveats

  • The dataset images and trained model weights are not tracked in this repository.
  • Several paths are hard-coded to Google Drive/Colab locations.
  • train.py imports ModifiedAlexNet from alexNetModel, but alexNetModel.py is not present in the repository. The import must be removed/commented or the missing module must be restored before the active script can run.
  • test.py expects a checkpoint file in logs/, but no checkpoint files are included.
  • utils.save_checkpoint() references config attributes such as weights, model_name, and best_models that are not defined in the active config.py; this helper is not used by the current training loop.
  • The active metric variable is named map, which shadows Python's built-in map.

Reports and Artifacts

Project reports are stored in Paper/, and experiment assets are stored in Experiments/. The image plots in Experiments/ show training/validation loss and validation mAP curves from a recorded run.

About

Inductive Transfer learning using Deep Convolutional Neural Networks (DCNNs) for fine-grained Knife classification using Metropolitan Police Data (knife stabbings incidents)

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors