### Install Decord Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Installs the Decord library, which is used for video data loading and processing. Ensure it's compatible with your environment. ```bash !pip install decord ``` -------------------------------- ### Print Library Versions Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Prints the installed versions of MXNet, Decord, and GluonCV. This is useful for verifying the environment setup. ```python print(f'''Versions: mxnet: {mx.__version__} decord: {decord.__version__} gluoncv: {gluoncv.__version__} ''') ``` -------------------------------- ### Install Python Packages Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Installs necessary Python packages for the project. Note the potential conflict warning if both MXNet and PyTorch are installed. ```text Requirement already satisfied: charset-normalizer~=2.0.0 in /usr/local/lib/python3.10/dist-packages (from requests->torchvision==0.14.1) (2.0.12) Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->torchvision==0.14.1) (3.4) Installing collected packages: nvidia-cuda-runtime-cu11, nvidia-cuda-nvrtc-cu11, nvidia-cublas-cu11, nvidia-cudnn-cu11, torch, torchvision, torchaudio Attempting uninstall: torch Found existing installation: torch 2.0.1+cu118 Uninstalling torch-2.0.1+cu118: Successfully uninstalled torch-2.0.1+cu118 Attempting uninstall: torchvision Found existing installation: torchvision 0.15.2+cu118 Uninstalling torchvision-0.15.2+cu118: Successfully uninstalled torchvision-0.15.2+cu118 Attempting uninstall: torchaudio Found existing installation: torchaudio 2.0.2+cu118 Uninstalling torchaudio-2.0.2+cu118: Successfully uninstalled torchaudio-2.0.2+cu118 ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts. torchdata 0.6.1 requires torch==2.0.1, but you have torch 1.13.1 which is incompatible. torchtext 0.15.2 requires torch==2.0.1, but you have torch 1.13.1 which is incompatible. Successfully installed nvidia-cublas-cu11-11.10.3.66 nvidia-cuda-nvrtc-cu11-11.7.99 nvidia-cuda-runtime-cu11-11.7.99 nvidia-cudnn-cu11-8.5.0.96 torch-1.13.1 torchaudio-0.13.1 torchvision-0.14.1 ``` -------------------------------- ### Install GluonCV Library Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Installs or upgrades the GluonCV library, a deep learning toolkit for computer vision. Ensure you have a stable internet connection for the download. ```bash !pip install --upgrade gluoncv ``` -------------------------------- ### Install MXNet with CUDA 11.2 Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Installs the MXNet library with CUDA 11.2 support. This is necessary for GPU acceleration. ```bash # !apt install libnvrtc11.0 !pip install mxnet-cu112 ``` -------------------------------- ### Initialize SlowFast Model and Training Setup Source: https://context7.com/danishkhan24/shoplifting-detection/llms.txt Initializes the SlowFast ResNet50 model pretrained on Kinetics-400 dataset and configures training parameters including optimizer, learning rate schedule, and loss function. Ensure GPU availability and correct context setup for training. ```python import mxnet as mx from mxnet import gluon from gluoncv.model_zoo import get_model from gluoncv.utils import TrainingHistory # GPU configuration num_gpus = 1 ctx = [mx.gpu(i) for i in range(num_gpus)] # Initialize SlowFast model with custom number of classes net = get_model( name='slowfast_4x16_resnet50_custom', nclass=len(classes), # 3 classes: Normal, Robbery, Shoplifting num_segments=num_segments, ctx=ctx ) # Training hyperparameters lr_decay = 0.1 lr_decay_epoch = [50, 80] optimizer = 'sgd' optimizer_params = { 'learning_rate': 0.0001, 'wd': 1e-5, 'momentum': 0.9 } # Initialize trainer and loss function trainer = gluon.Trainer(net.collect_params(), optimizer, optimizer_params) loss_fn = gluon.loss.SoftmaxCrossEntropyLoss() # Metrics tracking train_metric = mx.metric.Accuracy() valid_metric = mx.metric.Accuracy() train_history = TrainingHistory(['training-acc']) valid_history = TrainingHistory(['valid-acc']) ``` -------------------------------- ### Install PyTorch, Torchvision, and Torchaudio Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Installs specific versions of PyTorch, Torchvision, and Torchaudio. These versions are critical for project compatibility and may require specific CUDA versions. ```bash !pip install torch==1.13.1 torchvision==0.14.1 torchaudio==0.13.1 ``` -------------------------------- ### Display Library Versions Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Shows the output of the version printing command, confirming the installed versions of MXNet, Decord, and GluonCV. ```text Output: Versions: mxnet: 1.9.1 decord: 0.6.0 gluoncv: 0.11.0 ``` -------------------------------- ### Install MXNet with CUDA 11.0 Support Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Installs the MXNet deep learning framework with CUDA 11.0 support. This command is commented out and may require specific environment configurations. ```python # !sudo ln -sfT /usr/local/cuda/cuda-11.0/ /usr/local/cuda # !pip install mxnet-cu110 ``` -------------------------------- ### Training Output Log Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Example output from the training loop, showing epoch number, training accuracy, loss, time taken, and precision/recall scores for different classes. ```text [Epoch 0] train=0.5208 loss=0.9652 time: 539.1 sec Train precision: {'Normal': 0.5339805825242718, 'Robbery': 0.37037037037037035, 'Shoplifting': 0.0} Train recall: {'Normal': 0.9322033898305084, 'Robbery': 0.08403361344537816, 'Shoplifting': 0.0} ``` -------------------------------- ### Verify MXNet Version Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Checks the installed version of the MXNet library. Ensure this matches the required version for compatibility. ```python import mxnet mxnet.__version__ ``` -------------------------------- ### Check CUDA Compiler Version Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Verifies the installed NVIDIA CUDA compiler version. This is crucial for projects that utilize GPU acceleration. ```bash !nvcc --version ``` -------------------------------- ### Example Usage of Video Inference Pipeline Source: https://context7.com/danishkhan24/shoplifting-detection/llms.txt Iterates through a list of video files in a specified input directory and processes each one using the `process_video` function, saving the results to an output directory. ```python # Example usage input_video_path = 'test' output_video_path = 'output' video_list = os.listdir(input_video_path) for video_name in video_list: results = process_video( video_name, input_video_path, output_video_path, net, transform_fn, classes, num_frames=48 ) # Expected output: # Processing: Robbery012_x264.mp4 # Total frames: 749, FPS: 30.0, Segments: 3 # [Segment 0] class: Robbery, probability: 0.5547 # [Segment 1] class: Robbery, probability: 0.6484 # [Segment 2] class: Robbery, probability: 0.5271 ``` -------------------------------- ### MXNet and PyTorch Version Warning Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb A warning indicating that both MXNet and PyTorch are installed, which might lead to increased GPU memory usage. ```text Output: /usr/local/lib/python3.10/dist-packages/gluoncv/__init__.py:40: UserWarning: Both `mxnet==1.9.1` and `torch==1.13.1+cu117` are installed. You might encounter increased GPU memory footprint if both framework are used at the same time. warnings.warn(f'Both `mxnet=={mx.__version__}` and `torch=={torch.__version__}` are installed. ' ``` -------------------------------- ### Predict Action in Video Clip Source: https://context7.com/danishkhan24/shoplifting-detection/llms.txt Classifies a video clip using a pre-trained network and transformation function. It reshapes the input and applies softmax to get the predicted class and probability. ```python def predict(net, clip, transform_fn, num_frames, classes): """Classify action in a video clip.""" clip_input = transform_fn(clip) clip_input = np.stack(clip_input, axis=0) clip_input = clip_input.reshape((-1,) + (num_frames, 3, 224, 224)) clip_input = np.transpose(clip_input, (0, 2, 1, 3, 4)) pred = net(nd.array(clip_input).as_in_context(ctx[0])) ind = nd.topk(pred, k=1)[0].astype('int') pred_class = classes[ind[0].asscalar()] pred_prob = nd.softmax(pred)[0][ind[0]].asscalar() return pred_class, pred_prob ``` -------------------------------- ### Initialize Model and Transformations for Video Processing Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Sets up the video transformation pipeline and initializes the SlowFast model with pre-trained weights for video classification. Ensure 'classes', 'num_segments', 'ctx', and 'models_path' are defined. ```python transform_fn = video.VideoGroupValTransform(size=224, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) net = get_model(name='slowfast_4x16_resnet50_custom', nclass=len(classes), num_segments=num_segments, pretrainded=False, pretrained_base=False, ctx=ctx) net.load_parameters(f'{models_path}/slowfast_ucf_19.params', ctx=ctx) ``` -------------------------------- ### Define Model Parameters and Data Loading Settings Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Sets up class labels, video segment parameters, batch size, and worker count for data loading. Adjust `per_device_batch_size` based on your GPU memory. ```python classes = ['Normal', 'Robbery', 'Shoplifting'] num_segments = 4 num_frames = 48 per_device_batch_size = 3 num_workers = 4 batch_size = num_gpus*per_device_batch_size ``` -------------------------------- ### Create Directories for Testing and Output Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Creates necessary directories for storing test data and output results. ```bash !mkdir test !mkdir output ``` -------------------------------- ### Define Input and Output Paths Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Sets the file paths for input test videos and output results. ```python input_video_path = 'test' # path to test video output_video_path = 'output' # path to the output results ``` -------------------------------- ### Initialize and Load Model Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Initializes a SlowFast model with specified parameters and loads pre-trained weights. Ensure 'classes', 'num_segments', and 'ctx' are defined. ```python net = get_model(name='slowfast_4x16_resnet50_custom', nclass=len(classes), num_segments=num_segments, pretrainded=False, pretrained_base=False, ctx=ctx) net.load_parameters(f'{models_path}/slowfast_ucf_19.params', ctx=ctx) ``` -------------------------------- ### Load Validation Dataset Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Sets up the validation dataset using custom video transformations and data loaders. Requires 'dataset_path', 'num_frames', 'batch_size', and 'num_workers' to be defined. ```python transform_valid = video.VideoGroupValTransform(size=224, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) valid_dataset = VideoClsCustom(root=dataset_path, setting=f'{dataset_path}/Anomaly_Test.txt', train=False, new_length=num_frames, num_segments=num_segments, transform=transform_valid, video_ext='mp4', video_loader=True, use_decord=True) print('Load %d valid samples.' % len(valid_dataset)) valid_data = gluon.data.DataLoader(valid_dataset, batch_size=batch_size, shuffle=True, num_workers=num_workers) ``` -------------------------------- ### Load Pre-trained Model and Configure Optimizer Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Initializes the SlowFast model with ResNet50 backbone and configures the SGD optimizer with specified learning rate, weight decay, and momentum. Learning rate decay is applied at specified epochs. ```python net = get_model(name='slowfast_4x16_resnet50_custom', nclass=len(classes), num_segments=num_segments, ctx=ctx) # Learning rate decay factor lr_decay = 0.1 # Epochs where learning rate decays lr_decay_epoch = [50, 80] # Stochastic gradient descent optimizer = 'sgd' # Set parameters optimizer_params = {'learning_rate': 0.0001, 'wd': 1e-5, 'momentum': 0.9} ``` -------------------------------- ### Import Project Libraries Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Imports essential libraries for video analysis, including MXNet, GluonCV, Decord, OpenCV, NumPy, and Matplotlib. ```python import mxnet as mx from mxnet import nd, gluon from mxnet import autograd as ag import gluoncv from gluoncv.data import VideoClsCustom from gluoncv.data.transforms import video from gluoncv.model_zoo import get_model from gluoncv.utils import split_and_load, TrainingHistory import decord from sklearn import metrics import cv2 import numpy as np import os import shutil import time import tqdm import matplotlib.pyplot as plt import seaborn as sn ``` -------------------------------- ### Configure GPU Context Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Initializes the computation context to use available GPUs. This allows for faster model training and inference. ```python num_gpus = 1 ctx = [mx.gpu(i) for i in range(num_gpus)] ``` -------------------------------- ### Create Model Directory Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Creates a directory named 'models' to store model checkpoints. ```python !mkdir models ``` -------------------------------- ### Define Trainer and Metrics Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Initializes the trainer for the neural network, defines the loss function, and sets up accuracy metrics for training and validation. ```python trainer = gluon.Trainer(net.collect_params(), optimizer, optimizer_params) loss_fn = gluon.loss.SoftmaxCrossEntropyLoss() train_metric = mx.metric.Accuracy() valid_metric = mx.metric.Accuracy() train_history = TrainingHistory(['training-acc']) valid_history = TrainingHistory(['valid-acc']) ``` -------------------------------- ### Initialize Video Data Transformations and Loaders Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Defines transformations for training and validation datasets and loads them using `gluon.data.DataLoader`. Ensure your dataset files (`Anomaly_Train_output.txt`, `Anomaly_Test_output.txt`) are correctly formatted. ```python transform_train = video.VideoGroupTrainTransform(size=(224, 224), scale_ratios=[1.0, 0.85, 0.75], mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) transform_valid = video.VideoGroupValTransform(size=224, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) train_dataset = VideoClsCustom(root=dataset_path, setting=f'{dataset_path}/Anomaly_Train_output.txt', train=True, new_length=num_frames, num_segments=num_segments, transform=transform_train, video_ext='mp4', video_loader=True, use_decord=True ) print('Load %d training samples.' % len(train_dataset)) train_data = gluon.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=num_workers) valid_dataset = VideoClsCustom(root=dataset_path, setting=f'{dataset_path}/Anomaly_Test_output.txt', train=False, new_length=num_frames, num_segments=num_segments, transform=transform_valid, video_ext='mp4', video_loader=True, use_decord=True) print('Load %d valid samples.' % len(valid_dataset)) valid_data = gluon.data.DataLoader(valid_dataset, batch_size=batch_size, shuffle=True, num_workers=num_workers) ``` -------------------------------- ### Configure Custom Video Datasets with GluonCV Source: https://context7.com/danishkhan24/shoplifting-detection/llms.txt Configure custom video datasets for training and validation using GluonCV's VideoClsCustom class. The system expects video files organized with corresponding annotation files listing video paths and class labels. Ensure 'dataset_path' points to your dataset directory and annotation files are correctly named. ```python from gluoncv.data import VideoClsCustom from gluoncv.data.transforms import video from mxnet import gluon # Define classes for detection classes = ['Normal', 'Robbery', 'Shoplifting'] # Configuration parameters dataset_path = 'dataset' num_segments = 4 num_frames = 48 batch_size = 3 num_workers = 4 # Define transforms for training and validation transform_train = video.VideoGroupTrainTransform( size=(224, 224), scale_ratios=[1.0, 0.85, 0.75], mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225] ) transform_valid = video.VideoGroupValTransform( size=224, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225] ) # Create training dataset train_dataset = VideoClsCustom( root=dataset_path, setting=f'{dataset_path}/Anomaly_Train_output.txt', train=True, new_length=num_frames, num_segments=num_segments, transform=transform_train, video_ext='mp4', video_loader=True, use_decord=True ) print(f'Loaded {len(train_dataset)} training samples.') # Create validation dataset valid_dataset = VideoClsCustom( root=dataset_path, setting=f'{dataset_path}/Anomaly_Test_output.txt', train=False, new_length=num_frames, num_segments=num_segments, transform=transform_valid, video_ext='mp4', video_loader=True, use_decord=True ) print(f'Loaded {len(valid_dataset)} validation samples.') # Create data loaders train_data = gluon.data.DataLoader( train_dataset, batch_size=batch_size, shuffle=True, num_workers=num_workers ) valid_data = gluon.data.DataLoader( valid_dataset, batch_size=batch_size, shuffle=True, num_workers=num_workers ) ``` -------------------------------- ### Copy Models to Local Directory Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Copies pre-trained models from Google Drive to the current directory. Ensure the path to your models in Google Drive is correct. ```python # !cp -r /content/drive/MyDrive/ML/models . ``` -------------------------------- ### Process Videos with YOLO Model Source: https://context7.com/danishkhan24/shoplifting-detection/llms.txt A command-line utility to process all video files in a directory using a trained YOLO model for shoplifting detection. It iterates through video files and applies object detection with saved weights. ```python import glob import sys import os # Process all videos in a directory with the trained model # Usage: python video_process.py /path/to/video/folder video_path = sys.argv[1] for file in glob.glob("{}"/*".format(video_path)): print(file) os.system("yolo detect predict model=best_shoplifting.pt save=True source={}".format(file)) ``` -------------------------------- ### Complete Training Loop for Shoplifting Detection Source: https://context7.com/danishkhan24/shoplifting-detection/llms.txt Implements a full training cycle with forward pass, backpropagation, metric calculation, and model checkpointing based on validation performance. Includes learning rate decay and detailed metric printing. ```python import time import numpy as np from sklearn import metrics from mxnet import autograd as ag from gluoncv.utils import split_and_load epochs = 20 lr_decay_count = 0 valid_loss_best = 1000 valid_acc_best = 0 models_path = 'models' for epoch in range(epochs): tic = time.time() train_metric.reset() valid_metric.reset() train_loss = 0 # Learning rate decay at specified epochs if epoch == lr_decay_epoch[lr_decay_count]: trainer.set_learning_rate(trainer.learning_rate * lr_decay) lr_decay_count += 1 y_true = np.array([], dtype='int') y_pred = np.array([], dtype='int') # Training phase for i, batch in enumerate(train_data): data = split_and_load(batch[0], ctx_list=ctx, batch_axis=0) label = split_and_load(batch[1], ctx_list=ctx, batch_axis=0) with ag.record(): output = [] for _, X in enumerate(data): X = X.reshape((-1,) + X.shape[2:]) pred = net(X) output.append(pred) loss = [loss_fn(yhat, y) for yhat, y in zip(output, label)] for l in loss: l.backward() trainer.step(batch_size) train_loss += sum([l.mean().asscalar() for l in loss]) train_metric.update(label, output) y_true = np.concatenate((y_true, label[0].asnumpy())) y_pred = np.concatenate((y_pred, pred.argmax(axis=1).astype('int').asnumpy())) name, acc = train_metric.get() precisions = metrics.precision_score(y_true, y_pred, average=None, zero_division=False) recall = metrics.recall_score(y_true, y_pred, average=None, zero_division=False) print(f'[Epoch {epoch}] train_acc={acc:.4f} loss={train_loss/(i+1):.4f} time: {time.time()-tic:.1f}s') print('Precision:', {k: v for k, v in zip(classes, precisions)}) print('Recall:', {k: v for k, v in zip(classes, recall)}) # Save best model based on validation performance if valid_loss_best > valid_loss or valid_acc_best < acc: valid_loss_best = valid_loss valid_acc_best = acc net.save_parameters(f"{models_path}/slowfast_ucf_{epoch}.params") print(f'Model saved: slowfast_ucf_{epoch}.params') ``` -------------------------------- ### Process Multiple Videos in a Directory Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Iterates through a list of video files in a directory and processes each one using the 'process_video' function. Assumes 'input_video_path', 'output_video_path', 'net', 'transform_fn', 'classes', and 'num_frames' are defined elsewhere. ```python video_list = os.listdir(input_video_path) for video_name in video_list: process_video(video_name, input_video_path, output_video_path, net, transform_fn, classes, num_frames=num_frames, verbose=1) ``` -------------------------------- ### Training Loop for Shoplifting Detection Model Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Iterates through epochs, handling learning rate decay, training on batches, calculating loss and metrics, and validating the model. Saves the best performing model parameters. ```python epochs = 20 lr_decay_count = 0 valid_loss_best = 1000 valid_acc_best = 10 hist_prec_train = [] hist_prec_test = [] hist_recall_train = [] hist_recall_test = [] hist_loss = [] hist_loss_valid = [] for epoch in range(epochs): tic = time.time() train_metric.reset() valid_metric.reset() train_loss = 0 valid_loss = 0 # Learning rate decay if epoch == lr_decay_epoch[lr_decay_count]: trainer.set_learning_rate(trainer.learning_rate*lr_decay) lr_decay_count += 1 # Loop through each batch of training data y_true = np.array([], dtype='int') y_pred = np.array([], dtype='int') for i, batch in enumerate(train_data): # Extract data and label data = split_and_load(batch[0], ctx_list=ctx, batch_axis=0) label = split_and_load(batch[1], ctx_list=ctx, batch_axis=0) # AutoGrad with ag.record(): output = [] for _, X in enumerate(data): X = X.reshape((-1,) + X.shape[2:]) pred = net(X) output.append(pred) loss = [loss_fn(yhat, y) for yhat, y in zip(output, label)] # Backpropagation for l in loss: l.backward() # Optimize trainer.step(batch_size) # Update metrics train_loss += sum([l.mean().asscalar() for l in loss]) train_metric.update(label, output) y_true = np.concatenate((y_true, label[0].asnumpy())) y_pred = np.concatenate((y_pred, pred.argmax(axis=1).astype('int').asnumpy())) name, acc = train_metric.get() precisions = metrics.precision_score(y_true, y_pred, average=None, zero_division=False) recall = metrics.recall_score(y_true, y_pred, average=None, zero_division=False) # Update history and print metrics train_history.update([acc]) print(f'[Epoch {epoch}] train={acc:.4f} loss={train_loss/(i+1):.4f} time: {time.time()-tic:.1f} sec') print('Train precision: ',{k:v for k,v in zip(classes, precisions)}) print('Train recall: ',{k:v for k,v in zip(classes, recall)}) hist_loss.append(train_loss/(i+1)) hist_prec_train.append({k:v for k,v in zip(classes, precisions)}) hist_recall_train.append({k:v for k,v in zip(classes, recall)}) y_true_v = np.array([], dtype='int') y_pred_v = np.array([], dtype='int') for i, batch in enumerate(valid_data): # Extract data and label data = split_and_load(batch[0], ctx_list=ctx, batch_axis=0) label = split_and_load(batch[1], ctx_list=ctx, batch_axis=0) output = [] for _, X in enumerate(data): X = X.reshape((-1,) + X.shape[2:]) pred = net(X) output.append(pred) loss = [loss_fn(yhat, y) for yhat, y in zip(output, label)] # Update metrics valid_loss += sum([l.mean().asscalar() for l in loss]) valid_metric.update(label, output) y_true_v = np.concatenate((y_true_v, label[0].asnumpy())) y_pred_v = np.concatenate((y_pred_v, pred.argmax(axis=1).astype('int').asnumpy())) name, acc = valid_metric.get() precisions_v = metrics.precision_score(y_true_v, y_pred_v, average=None, zero_division=False) recall_v = metrics.recall_score(y_true_v, y_pred_v, average=None, zero_division=False) # Update history and print metrics valid_history.update([acc]) print(f'valid_acc: {acc}, valid_loss: {valid_loss/(i+1)}') hist_loss_valid.append(valid_loss/(i+1)) print(f'valid precision:', {k:v for k,v in zip(classes, precisions_v)}) print(f'valid recall:', {k:v for k,v in zip(classes, recall_v)}) hist_prec_test.append({k:v for k,v in zip(classes, precisions_v)}) hist_recall_test.append({k:v for k,v in zip(classes, recall_v)}) if (valid_loss_best > valid_loss) or (valid_acc_best < acc) : valid_loss_best = valid_loss valid_acc_best = acc print(f'Best valid loss: {valid_loss_best}') file_name = f"{models_path}/slowfast_ucf_{epoch}.params" net.save_parameters(file_name) ``` -------------------------------- ### Define Dataset and Model Paths Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Sets the file paths for the dataset and model weights. These paths are crucial for loading data and pre-trained models. ```python dataset_path = 'dataset' # path to dataset models_path = 'models' # path to model weights ``` -------------------------------- ### Dataset Extraction Output Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Details the files and directories created after extracting the dataset zip archive, including 'dataset/dataset/Normal' and several .mp4 files. ```text Output: Archive: /content/drive/MyDrive/ucf-crime-shoplifting.zip creating: dataset/ creating: dataset/dataset/ creating: dataset/dataset/Normal/ inflating: dataset/dataset/Normal/Normal_Videos001_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos004_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos007_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos008_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos011_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos012_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos017_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos020_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos021_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos026_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos028_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos032_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos035_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos037_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos038_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos046_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos047_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos052_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos053_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos054_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos057_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos058_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos066_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos069_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos071_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos083_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos084_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos085_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos086_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos092_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos095_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos096_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos099_x264.mp4 inflating: dataset/dataset/Normal/Normal_Videos102_x264.mp4 ``` -------------------------------- ### Load and Validate Shoplifting Detection Model Source: https://context7.com/danishkhan24/shoplifting-detection/llms.txt Loads a pre-trained model and evaluates its performance on a validation dataset. Calculates precision, recall, and generates a confusion matrix for detailed analysis. ```python import numpy as np from sklearn import metrics import matplotlib.pyplot as plt import seaborn as sn from gluoncv.model_zoo import get_model # Load trained model net = get_model( name='slowfast_4x16_resnet50_custom', nclass=len(classes), num_segments=num_segments, pretrained=False, pretrained_base=False, ctx=ctx ) net.load_parameters(f'{models_path}/slowfast_ucf_19.params', ctx=ctx) # Validation loop valid_loss = 0 y_true = np.array([], dtype='int') y_pred = np.array([], dtype='int') for i, batch in enumerate(valid_data): data = split_and_load(batch[0], ctx_list=ctx, batch_axis=0) label = split_and_load(batch[1], ctx_list=ctx, batch_axis=0) output = [] for _, X in enumerate(data): X = X.reshape((-1,) + X.shape[2:]) pred = net(X) output.append(pred) loss = [loss_fn(yhat, y) for yhat, y in zip(output, label)] valid_loss += sum([l.mean().asscalar() for l in loss]) y_true = np.concatenate((y_true, label[0].asnumpy())) y_pred = np.concatenate((y_pred, pred.argmax(axis=1).astype('int').asnumpy())) # Calculate metrics precisions = metrics.precision_score(y_true, y_pred, average=None, zero_division=False) recalls = metrics.recall_score(y_true, y_pred, average=None, zero_division=False) print('Precision:', {k: v for k, v in zip(classes, precisions)}) print('Recall:', {k: v for k, v in zip(classes, recalls)}) # Generate confusion matrix cm = metrics.confusion_matrix(y_true, y_pred) ax = sn.heatmap(cm, annot=True, cmap=plt.cm.Blues, xticklabels=classes, yticklabels=classes) ax.set_title('Validation Confusion Matrix') plt.show() # Binary classification: Normal vs Anomaly print(f'Binary Precision (Normal vs Anomaly): {metrics.precision_score(y_true > 0, y_pred > 0):.4f}') print(f'Binary Recall (Normal vs Anomaly): {metrics.recall_score(y_true > 0, y_pred > 0):.4f}') ``` -------------------------------- ### Copy Output Directory to Google Drive Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Copies the '/content/output' directory to a specified path in Google Drive. This is a shell command executed within a Python environment. ```shell !cp -r /content/output /content/drive/MyDrive/Anomaly ``` -------------------------------- ### Process Video for Shoplifting Detection Source: https://context7.com/danishkhan24/shoplifting-detection/llms.txt Processes a single video file by splitting it into segments, performing inference on each segment, and merging the results into an output video with visual overlays. Requires pre-defined network, transform function, and class labels. ```python import decord import cv2 import numpy as np import os import shutil from mxnet import nd def process_video(video_name, input_path, output_path, net, transform_fn, classes, num_frames=48): """Process a video file and generate output with classification overlays.""" print(f'Processing: {video_name}') vr = decord.VideoReader(f'{input_path}/{video_name}') # Split video into segments of num_frames * num_segments length segments = split_on_segments(vr, net.num_segments * num_frames) anomaly_classes = [c for c in classes if c != 'Normal'] temp_output_path = f'{output_path}/{video_name}' os.makedirs(temp_output_path, exist_ok=True) results = {} video_data = None for i, segment in enumerate(segments): video_data = vr.get_batch(segment).asnumpy() pred_class, pred_prob = predict(net, video_data, transform_fn, num_frames, classes) results[i] = {'predicted_class': pred_class, 'probability': pred_prob} # Add visual overlay to frames display_class = 'Anomaly' if pred_class in anomaly_classes else pred_class add_result_on_clip(video_data, display_class, pred_prob, anomaly_classes) write_video_output(f'{temp_output_path}/batch_{i:04d}.mp4', video_data) print(f'[Segment {i}] class: {pred_class}, probability: {pred_prob:.4f}') # Merge all segments into final output video if video_data is not None: height, width = video_data.shape[1], video_data.shape[2] merge_clips(temp_output_path, video_name, output_path, (width, height)) shutil.rmtree(temp_output_path) return results ``` -------------------------------- ### Mount Google Drive Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Mounts Google Drive to the Colab environment. This is typically the first step to access datasets or save results. ```python from google.colab import drive drive.mount('/content/drive') ``` -------------------------------- ### Extract Dataset Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Unzips the project's dataset archive located at '/content/drive/MyDrive/ucf-crime-shoplifting.zip'. ```bash !unzip /content/drive/MyDrive/ucf-crime-shoplifting.zip ``` -------------------------------- ### Write Video Clip to File Source: https://context7.com/danishkhan24/shoplifting-detection/llms.txt Writes a given video data (NumPy array) to a specified output file path using the MP4V codec. Assumes input video data is in BGR format and converts it to RGB before writing. ```python def write_video_output(output_path, video_data): """Write video clip to file.""" height, width = video_data.shape[1], video_data.shape[2] out = cv2.VideoWriter(output_path, cv2.VideoWriter_fourcc(*'MP4V'), 30.0, (width, height)) for frame in video_data: out.write(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) out.release() ``` -------------------------------- ### Display Confusion Matrix (Multi-class) Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Generates and displays a confusion matrix for multi-class classification. Requires 'y_true', 'y_pred', 'classes', 'sn', and 'plt' to be defined. ```python cm = metrics.confusion_matrix(y_true, y_pred) ax = sn.heatmap(cm, annot=True, cmap=plt.cm.Blues, xticklabels=classes, yticklabels=classes) ax.set_title('Valid confusion matrix') plt.show() ``` -------------------------------- ### Add Classification and Alert Overlays to Video Clip Source: https://context7.com/danishkhan24/shoplifting-detection/llms.txt Iterates through each frame of a video clip to draw classification results and anomaly alerts. Requires `draw_classification_result` and `draw_alert_mark` functions to be defined. Alerts are drawn for anomalies with a probability above 0.65. ```python import cv2 import numpy as np def add_result_on_clip(clip, pred_class, pred_prob, anomaly_classes): """Add classification overlay to all frames in a clip.""" for frame in clip: draw_classification_result(frame, pred_class, pred_prob) # Add alert triangle for high-confidence anomalies if pred_class in anomaly_classes and pred_prob > 0.65: draw_alert_mark(frame) ``` -------------------------------- ### Copy Model Parameters Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Copies pre-trained model parameters from one location to another, typically for use in training or evaluation. ```python !cp -r /content/models/slowfast_ucf_19.params /content/drive/MyDrive/ ``` -------------------------------- ### Display Confusion Matrix (Binary) Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Generates and displays a confusion matrix for binary classification (Normal vs. Anomaly). Requires 'y_true', 'y_pred', 'sn', and 'plt' to be defined. ```python cm = metrics.confusion_matrix(y_true>0, y_pred>0) ax = sn.heatmap(cm, annot=True, cmap=plt.cm.Blues, xticklabels=['Normal', 'Anomaly'] , yticklabels=['Normal', 'Anomaly'] ) ax.set_title('Valid confusion matrix') plt.show() ``` -------------------------------- ### Split Video into Segments Source: https://context7.com/danishkhan24/shoplifting-detection/llms.txt Splits a video reader object into fixed-length segments. Ensures each segment meets the minimum required length for processing. ```python def split_on_segments(vr, segment_length=192): """Split video into fixed-length segments for classification.""" n_frames = len(vr) fps = vr.get_avg_fps() all_idx = np.arange(n_frames) segments = [] for i in range(0, len(all_idx), segment_length): segment = all_idx[i:i + segment_length] if len(segment) >= segment_length: segments.append(segment) print(f'Total frames: {n_frames}, FPS: {fps}, Segments: {len(segments)}') return segments ``` -------------------------------- ### Write Video Data to File Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Saves provided video data to a specified output path. Handles cases where video data is None. Requires OpenCV (cv2). ```python def write_video(output_path, video_data): ''' Args: output_path: path to output video file video_data: video data that should be saved to file ''' if video_data is None: print(f'{output_path} can\'t write file.') return height = video_data.shape[1] width = video_data.shape[2] out = cv2.VideoWriter(f'{output_path}', cv2.VideoWriter_fourcc(*'MP4V'), 30.0, (width, height)) for frame in video_data: out.write(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) out.release() ``` -------------------------------- ### Predict Action on Video Clip Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Performs action prediction on a given video clip using a neural network. Requires a pre-trained network, a transformation function, and a list of possible classes. Ensure clip data is preprocessed correctly. ```python def predict(net, clip, transform_fn, num_frames, classes): ''' Predict action on clip. Args: net: the net to perform classification clip: video clip for predicting action on it transform_fn: a function that transforms data num_frames: the length of input video clip classes: list of action that can be detected on video Returns: str, float: Class label with class probability. ''' clip_input = transform_fn(clip) clip_input = np.stack(clip_input, axis=0) clip_input = clip_input.reshape((-1,) + (num_frames, 3, 224, 224)) clip_input = np.transpose(clip_input, (0, 2, 1, 3, 4)) pred = net(nd.array(clip_input).as_in_context(ctx[0])) ind = nd.topk(pred, k=1)[0].astype('int') pred_class = classes[ind[0].asscalar()] pred_class_prob = nd.softmax(pred)[0][ind[0]].asscalar() return pred_class, pred_class_prob ``` -------------------------------- ### Validation Loop and Metric Calculation Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Iterates through the validation data to calculate loss, accuracy, and collect true labels and predictions. Requires 'valid_data', 'net', 'loss_fn', 'ctx', and 'split_and_load' to be defined. ```python valid_loss = 0 loss_fn = gluon.loss.SoftmaxCrossEntropyLoss() y_true = np.array([],dtype='int') y_pred = np.array([],dtype='int') outputs = [] acc = mx.metric.Accuracy() for i, batch in tqdm.tqdm(enumerate(valid_data)): # Extract data and label data = split_and_load(batch[0], ctx_list=ctx, batch_axis=0) label = split_and_load(batch[1], ctx_list=ctx, batch_axis=0) output = [] for _, X in enumerate(data): X = X.reshape((-1,) + X.shape[2:]) pred = net(X) output.append(pred) loss = [loss_fn(yhat, y) for yhat, y in zip(output, label)] acc.update(label, output) # Update metrics valid_loss += sum([l.mean().asscalar() for l in loss]) y_true = np.concatenate((y_true, label[0].asnumpy())) y_pred = np.concatenate((y_pred, pred.argmax(axis=1).astype('int').asnumpy())) outputs.append((output,label)) ``` -------------------------------- ### Split Video into Segments Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Splits a video into segments of a specified length. Useful for processing long videos in manageable chunks. Ensure the VideoReader object is correctly initialized. ```python def split_on_segments(vr, segm_length=48, verbose=True): ''' Split video on segments with *segm_length* length. Args: vr: decode.VideoReader segm_length: segment length verbose: verbosity level Returns: list: List of frame indexes, splitted on segments. ''' n_frames = len(vr) fps = vr.get_avg_fps() duration = n_frames/fps all_idx = np.arange(n_frames) idx = range(0, len(all_idx), segm_length) segments = [] for i in idx: segment = all_idx[i:i+segm_length] if len(segment) >= segm_length: segments.append(segment) if verbose: print(f'[Frames partitioning] total frames: {n_frames}, fps: {fps}, duration: {duration:.1f} sec, split on: {len(segments)} segments, segments length: {[i.shape[0] for i in segments]} frames') return segments ``` -------------------------------- ### Merge Video Clips Source: https://github.com/danishkhan24/shoplifting-detection/blob/main/anomaly_detection.ipynb Merges multiple video clips from a specified directory into a single output video. Requires os and OpenCV (cv2). ```python def merge_clips(clips_path, video_name, output_path, video_shape): ''' Merge clips into one video. Args: clips_path: path to clips folder video_name: video name output_path: path to output folder video_shape: (width, height) shape of output video ''' out = cv2.VideoWriter(f'{output_path}/output_{video_name}', cv2.VideoWriter_fourcc(*'MP4V'), 30.0, video_shape) clips_list = sorted(os.listdir(clips_path)) for clip_name in clips_list: clip = cv2.VideoCapture(f'{clips_path}/{clip_name}') ret, frame = clip.read() while(ret): out.write(frame) ret, frame = clip.read() clip.release() out.release() ```