4/20/25, 2:17 PM Transfer_Learning.
ipynb - Colab
import os
import cv2
import numpy as np
import random
from tqdm import tqdm
from sklearn.model_selection import train_test_split
# Import required libraries
import tensorflow as tf
import numpy as np
import os
import cv2
import random
from tqdm import tqdm
from [Link] import LSTM, Bidirectional, Conv2D, Dense, Flatten, MaxPooling2D, TimeDistributed, Reshape, Dropout, Global
from [Link] import Sequential, load_model
from [Link] import MobileNetV2
from [Link] import TensorBoard, ModelCheckpoint, EarlyStopping
from sklearn.model_selection import train_test_split, KFold
from [Link] import classification_report, confusion_matrix
import [Link] as plt
import seaborn as sns
# Constants
IMG_SIZE = 224
SEQUENCE_LENGTH = 10 # Number of frames in each sequence
TEST_SIZE = 0.2 # 20% for testing
RANDOM_SEED = 42
LR = 0.0001
BATCH_SIZE = 32
IMG_SIZE = 224
EPOCHS = 20
SEQUENCE_LENGTH = 10
from [Link] import drive
[Link]('/content/drive')
Drive already mounted at /content/drive; to attempt to forcibly remount, call [Link]("/content/drive", force_remount=True).
FIGHTS_DIR = "/content/drive/MyDrive/Peliculas/fights"
NO_FIGHTS_DIR = "/content/drive/MyDrive/Peliculas/noFights"
import os
print(len([Link](NO_FIGHTS_DIR))) # Check the number of files in the directory
101
def load_and_preprocess_data(folder_path, label, num_frames=10):
"""Load and preprocess video data, returning a list of (video_frames, label)"""
data = []
for filename in tqdm([Link](folder_path), desc=f"Loading {label}"):
if [Link](('.avi', '.mpg')): # Check for both .avi and .mpg files
video_path = [Link](folder_path, filename)
try:
cap = [Link](video_path)
frame_count = int([Link](cv2.CAP_PROP_FRAME_COUNT))
frames = []
# Sample frames evenly throughout the video
for i in range(0, frame_count, max(1, frame_count // num_frames)):
[Link](cv2.CAP_PROP_POS_FRAMES, i)
ret, frame = [Link]()
if ret:
frame = [Link](frame, (IMG_SIZE, IMG_SIZE))
frame = [Link]('float32') / 255.0
[Link](frame)
if len(frames) == num_frames:
break
[Link]()
if len(frames) == num_frames:
[Link](([Link](frames), [Link](label))) # Ensure the label is converted to an integer
# Ensure label is passed correctly
[Link] 1/9
4/20/25, 2:17 PM Transfer_Learning.ipynb - Colab
except Exception as e:
print(f"Error processing {video_path}: {e}")
return data
print("Loading data...")
fights_data = load_and_preprocess_data(FIGHTS_DIR, [1, 0]) # Fight label
no_fights_data = load_and_preprocess_data(NO_FIGHTS_DIR, [0, 1]) # No-fight label
Loading data...
Loading [1, 0]: 100%|██████████| 100/100 [00:24<00:00, 4.03it/s]
Loading [0, 1]: 100%|██████████| 101/101 [00:06<00:00, 14.55it/s]
all_data = fights_data + no_fights_data
[Link](all_data)
print(len(all_data))
201
print(len(fights_data)) # Should be 100
print(len(no_fights_data)) # Should be 100
100
101
sample = all_data[0]
print(f"Type of one sample: {type(sample)}")
# Unpack
frames, label = sample
print(f"Type of frames: {type(frames)}")
print(f"Type of label: {type(label)}")
Type of one sample: <class 'tuple'>
Type of frames: <class '[Link]'>
Type of label: <class 'numpy.int64'>
y_true = [item[1] for item in all_data]
fight_count = len([label for label in y_true if label == 0]) # Fight class
no_fight_count = len([label for label in y_true if label == 1]) # No-Fight class
print(f"Fight samples: {fight_count}, No-Fight samples: {no_fight_count}")
Fight samples: 100, No-Fight samples: 101
# Split into train and test sets
X = [Link]([item[0] for item in all_data])
y = [Link]([item[1] for item in all_data])
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=TEST_SIZE, random_state=RANDOM_SEED
)
print(X_train.shape)
print(y_train.shape)
(160, 10, 224, 224, 3)
(160,)
import numpy as np
def create_sequences_in_batches(frames, labels, sequence_length, batch_size):
"""
Creates sequences from frames and labels in batches to save memory.
Yields batches of sequences (X_batch, y_batch) instead of creating everything at once.
Parameters:
- frames: List of video frames
- labels: List of corresponding labels
- sequence_length: Length of the sequence to generate
- batch_size: Number of samples per batch
Yields:
- X_batch: A batch of sequence frames
[Link] 2/9
4/20/25, 2:17 PM Transfer_Learning.ipynb - Colab
- y_batch: A batch of labels corresponding to the sequences
"""
num_samples = len(frames) - sequence_length
for i in range(0, num_samples, batch_size):
# Get the current batch (from index i to i + batch_size)
X_batch = []
y_batch = []
for j in range(i, min(i + batch_size, num_samples)):
X_seq = frames[j:j + sequence_length]
y_seq = labels[j + sequence_length - 1] # Label for the last frame in the sequence
X_batch.append(X_seq)
y_batch.append(y_seq)
# Convert lists to numpy arrays before yielding
yield [Link](X_batch), [Link](y_batch)
# Set parameters
sequence_length = 10
batch_size = 32
# Create batches for training data
for X_batch, y_batch in create_sequences_in_batches(X_train, y_train, sequence_length, batch_size):
# Perform your model training or data processing here with X_batch and y_batch
print(f"Batch X shape: {X_batch.shape}")
print(f"Batch y shape: {y_batch.shape}")
Batch X shape: (32, 10, 10, 224, 224, 3)
Batch y shape: (32,)
Batch X shape: (32, 10, 10, 224, 224, 3)
Batch y shape: (32,)
Batch X shape: (32, 10, 10, 224, 224, 3)
Batch y shape: (32,)
Batch X shape: (32, 10, 10, 224, 224, 3)
Batch y shape: (32,)
Batch X shape: (22, 10, 10, 224, 224, 3)
Batch y shape: (22,)
print(f"\nFinal dataset shapes:")
print(f"Training sequences: {X_train.shape}")
print(f"Training labels: {y_train.shape}")
print(f"Test sequences: {X_test.shape}")
print(f"Test labels: {y_test.shape}")
Final dataset shapes:
Training sequences: (160, 10, 224, 224, 3)
Training labels: (160,)
Test sequences: (41, 10, 224, 224, 3)
Test labels: (41,)
# Create the model
def create_model():
# Load MobileNetV2 as base model
base_model = MobileNetV2(
include_top=False,
weights="imagenet",
input_shape=(IMG_SIZE, IMG_SIZE, 3)
)
base_model.trainable = False # Freeze base model layers
model = Sequential([
# TimeDistributed wrapper for CNN (process each frame independently)
TimeDistributed(base_model, input_shape=(SEQUENCE_LENGTH, IMG_SIZE, IMG_SIZE, 3)),
# Global average pooling for each timestep
TimeDistributed(GlobalAveragePooling2D()),
# Bidirectional LSTM layers for temporal modeling
Bidirectional(LSTM(128, return_sequences=True)),
Bidirectional(LSTM(64)),
# Classification head
Dense(64, activation='relu'),
Dropout(0.5),
Dense(2, activation='softmax')
])
[Link] 3/9
4/20/25, 2:17 PM Transfer_Learning.ipynb - Colab
return model
model = create_model()
/usr/local/lib/python3.11/dist-packages/keras/src/layers/core/[Link]: UserWarning: Do not pass an `input_shape`/`input_dim` a
super().__init__(**kwargs)
# Compile the model
optimizer = [Link](learning_rate=LR)
[Link](
loss='categorical_crossentropy',
optimizer=optimizer,
metrics=['accuracy', [Link](), [Link]()]
)
[Link]()
Model: "sequential"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type) ┃ Output Shape ┃ Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ time_distributed │ (None, 10, 7, 7, 1280) │ 2,257,984 │
│ (TimeDistributed) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ time_distributed_1 │ (None, 10, 1280) │ 0 │
│ (TimeDistributed) │ │ │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ bidirectional (Bidirectional) │ (None, 10, 256) │ 1,442,816 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ bidirectional_1 (Bidirectional) │ (None, 128) │ 164,352 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense (Dense) │ (None, 64) │ 8,256 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout (Dropout) │ (None, 64) │ 0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_1 (Dense) │ (None, 2) │ 130 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
Total params: 3,873,538 (14.78 MB)
Trainable params: 1,615,554 (6.16 MB)
t i bl 2 2 98 (8 )
# Callbacks
callbacks = [
TensorBoard(log_dir='logs/lstm_mobilenet'),
ModelCheckpoint(
'best_lstm_mobilenet_model.h5',
monitor='val_accuracy',
save_best_only=True,
mode='max'
),
EarlyStopping(
monitor='val_loss',
patience=5,
restore_best_weights=True
)
]
# Convert labels to one-hot encoded vectors
from [Link] import to_categorical
y_train = to_categorical(y_train, num_classes=2)
y_test = to_categorical(y_test, num_classes=2)
# Train the model
print("Training model...")
try:
history = [Link](
X_train,
y_train,
batch_size=BATCH_SIZE,
epochs=EPOCHS,
validation_data=(X_test, y_test),
callbacks=callbacks
)
except ValueError:
print("Restart the runtime and run all cells prior to this one.")
# Save the final model
[Link]('final_lstm_mobilenet_model.h5')
print("Model saved successfully.")
[Link] 4/9
4/20/25, 2:17 PM Transfer_Learning.ipynb - Colab
Training model...
Epoch 1/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 0s 495ms/step - accuracy: 0.5626 - loss: 0.6598 - precision: 0.5626 - recall: 0.5626WARNING:absl:You are sa
5/5 ━━━━━━━━━━━━━━━━━━━━ 63s 4s/step - accuracy: 0.5761 - loss: 0.6527 - precision: 0.5761 - recall: 0.5761 - val_accuracy: 0.7805
Epoch 2/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 0s 483ms/step - accuracy: 0.8429 - loss: 0.4996 - precision: 0.8429 - recall: 0.8429WARNING:absl:You are sa
5/5 ━━━━━━━━━━━━━━━━━━━━ 23s 925ms/step - accuracy: 0.8441 - loss: 0.4986 - precision: 0.8441 - recall: 0.8441 - val_accuracy: 0.951
Epoch 3/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 4s 705ms/step - accuracy: 0.9109 - loss: 0.3841 - precision: 0.9109 - recall: 0.9109 - val_accuracy: 0.9512
Epoch 4/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 5s 741ms/step - accuracy: 0.9204 - loss: 0.3126 - precision: 0.9204 - recall: 0.9204 - val_accuracy: 0.9512
Epoch 5/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 0s 484ms/step - accuracy: 0.9783 - loss: 0.2099 - precision: 0.9783 - recall: 0.9783WARNING:absl:You are sa
5/5 ━━━━━━━━━━━━━━━━━━━━ 5s 920ms/step - accuracy: 0.9778 - loss: 0.2091 - precision: 0.9778 - recall: 0.9778 - val_accuracy: 1.0000
Epoch 6/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 4s 826ms/step - accuracy: 0.9422 - loss: 0.2027 - precision: 0.9422 - recall: 0.9422 - val_accuracy: 1.0000
Epoch 7/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 4s 715ms/step - accuracy: 0.9717 - loss: 0.1407 - precision: 0.9717 - recall: 0.9717 - val_accuracy: 1.0000
Epoch 8/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 6s 833ms/step - accuracy: 1.0000 - loss: 0.0982 - precision: 1.0000 - recall: 1.0000 - val_accuracy: 1.0000
Epoch 9/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 3s 706ms/step - accuracy: 0.9871 - loss: 0.1051 - precision: 0.9871 - recall: 0.9871 - val_accuracy: 1.0000
Epoch 10/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 4s 741ms/step - accuracy: 1.0000 - loss: 0.0588 - precision: 1.0000 - recall: 1.0000 - val_accuracy: 1.0000
Epoch 11/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 6s 827ms/step - accuracy: 1.0000 - loss: 0.0613 - precision: 1.0000 - recall: 1.0000 - val_accuracy: 1.0000
Epoch 12/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 4s 710ms/step - accuracy: 1.0000 - loss: 0.0439 - precision: 1.0000 - recall: 1.0000 - val_accuracy: 1.0000
Epoch 13/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 5s 760ms/step - accuracy: 1.0000 - loss: 0.0323 - precision: 1.0000 - recall: 1.0000 - val_accuracy: 1.0000
Epoch 14/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 4s 715ms/step - accuracy: 1.0000 - loss: 0.0313 - precision: 1.0000 - recall: 1.0000 - val_accuracy: 1.0000
Epoch 15/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 4s 840ms/step - accuracy: 1.0000 - loss: 0.0320 - precision: 1.0000 - recall: 1.0000 - val_accuracy: 1.0000
Epoch 16/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 5s 855ms/step - accuracy: 1.0000 - loss: 0.0238 - precision: 1.0000 - recall: 1.0000 - val_accuracy: 1.0000
Epoch 17/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 4s 708ms/step - accuracy: 1.0000 - loss: 0.0243 - precision: 1.0000 - recall: 1.0000 - val_accuracy: 1.0000
Epoch 18/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 5s 832ms/step - accuracy: 1.0000 - loss: 0.0224 - precision: 1.0000 - recall: 1.0000 - val_accuracy: 1.0000
Epoch 19/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 5s 868ms/step - accuracy: 1.0000 - loss: 0.0209 - precision: 1.0000 - recall: 1.0000 - val_accuracy: 1.0000
Epoch 20/20
5/5 ━━━━━━━━━━━━━━━━━━━━ 5s 837ms/step - accuracy: 1.0000 - loss: 0.0135 - precision: 1.0000 - recall: 1.0000 - val_accuracy: 1.0000
WARNING:absl:You are saving your model as an HDF5 file via `[Link]()` or `[Link].save_model(model)`. This file format is c
Model saved successfully.
[Link]('my_model.keras')
def plot_history(history):
[Link](figsize=(12, 4))
# Plot training & validation accuracy values
[Link](1, 2, 1)
[Link]([Link]['accuracy'])
[Link]([Link]['val_accuracy'])
[Link]('Model Accuracy')
[Link]('Accuracy')
[Link]('Epoch')
[Link](['Train', 'Validation'], loc='upper left')
# Plot training & validation loss values
[Link](1, 2, 2)
[Link]([Link]['loss'])
[Link]([Link]['val_loss'])
[Link]('Model Loss')
[Link]('Loss')
[Link]('Epoch')
[Link](['Train', 'Validation'], loc='upper left')
plt.tight_layout()
[Link]('training_history.png')
[Link]()
# Plot training history
plot_history(history)
[Link] 5/9
4/20/25, 2:17 PM Transfer_Learning.ipynb - Colab
# Evaluate the model
def evaluate_model(model, X_test, y_test):
# Predict classes
y_pred = [Link](X_test)
y_pred_classes = [Link](y_pred, axis=1)
y_true = [Link](y_test, axis=1)
# Get unique classes in predictions and true labels
unique_pred_classes = [Link](y_pred_classes)
unique_true_classes = [Link](y_true)
# Print unique classes for debugging
print("Unique predicted classes:", unique_pred_classes)
print("Unique true classes:", unique_true_classes)
# Classification report
print("\nClassification Report:")
print(classification_report(y_true, y_pred_classes, target_names=['No Fight', 'Fight'], labels=unique_pred_classes)) #pass the label
# Confusion matrix
cm = confusion_matrix(y_true, y_pred_classes)
[Link](figsize=(6, 6))
[Link](cm, annot=True, fmt='d', cmap='Blues',
xticklabels=['No Fight', 'Fight'],
yticklabels=['No Fight', 'Fight'])
[Link]('Confusion Matrix')
[Link]('True label')
[Link]('Predicted label')
[Link]('confusion_matrix.png')
[Link]()
# Calculate and print additional metrics
test_loss, test_acc, test_precision, test_recall = [Link](X_test, y_test, verbose=0)
print(f"\nTest Accuracy: {test_acc:.4f}")
print(f"Test Precision: {test_precision:.4f}")
print(f"Test Recall: {test_recall:.4f}")
print(f"Test F1-Score: {2 * (test_precision * test_recall) / (test_precision + test_recall):.4f}")
print("\nEvaluating model on test set...")
evaluate_model(model, X_test, y_test)
[Link] 6/9
4/20/25, 2:17 PM Transfer_Learning.ipynb - Colab
Evaluating model on test set...
2/2 ━━━━━━━━━━━━━━━━━━━━ 30s 13s/step
Unique predicted classes: [0 1]
Unique true classes: [0 1]
Classification Report:
precision recall f1-score support
No Fight 1.00 1.00 1.00 22
Fight 1.00 1.00 1.00 19
accuracy 1.00 41
macro avg 1.00 1.00 1.00 41
weighted avg 1.00 1.00 1.00 41
Test Accuracy: 1.0000
Test Precision: 1.0000
Test Recall: 1.0000
Test F1-Score: 1.0000
def predict_fight(model, frame_sequence):
"""Predict whether a sequence of frames contains a fight"""
# Preprocess frames (should match training preprocessing)
frames = [Link]([[Link](frame, (IMG_SIZE, IMG_SIZE)) for frame in frame_sequence])
frames = [Link]('float32') / 255
frames = np.expand_dims(frames, axis=0) # Add batch dimension
# Make prediction
prediction = [Link](frames)
class_idx = [Link](prediction)
confidence = prediction[0][class_idx]
class_label = "Fight" if class_idx == 0 else "No Fight"
return class_label, confidence
!pip install google-colab-research-common
import cv2
import numpy as np
from [Link] import cv2_imshow # Import cv2_imshow
def process_video(model, video_path, output_path=None, show=True):
"""
Process a video file and detect fights
Args:
model: Your trained LSTM model
video_path: Path to input video
output_path: If provided, saves output video
show: Whether to display real-time results
"""
[Link] 7/9
4/20/25, 2:17 PM Transfer_Learning.ipynb - Colab
# Initialize video capture
cap = [Link](video_path)
if not [Link]():
raise ValueError("Could not open video")
# Get video properties
fps = [Link](cv2.CAP_PROP_FPS)
width = int([Link](cv2.CAP_PROP_FRAME_WIDTH))
height = int([Link](cv2.CAP_PROP_FRAME_HEIGHT))
# Initialize video writer if output path provided
if output_path:
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = [Link](output_path, fourcc, fps, (width, height))
# Buffer to store frames
frame_buffer = []
predictions = []
while True:
ret, frame = [Link]()
if not ret:
break
# Preprocess frame
resized_frame = [Link](frame, (IMG_SIZE, IMG_SIZE))
normalized_frame = resized_frame.astype('float32') / 255.0
# Add to buffer (maintain SEQUENCE_LENGTH)
frame_buffer.append(normalized_frame)
if len(frame_buffer) > SEQUENCE_LENGTH:
frame_buffer.pop(0)
# When buffer has enough frames
if len(frame_buffer) == SEQUENCE_LENGTH:
# Convert to model input format
sequence = np.expand_dims([Link](frame_buffer), axis=0)
# Predict
pred = [Link](sequence, verbose=0)[0]
is_fight = [Link](pred)
confidence = pred[is_fight]
[Link](is_fight)
# Visualize
label = "FIGHT" if is_fight == 0 else "No fight"
color = (0, 0, 255) if is_fight == 0 else (0, 255, 0)
[Link](frame, f"{label} ({confidence:.2f})",
(20, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, color, 2)
# Display/output
if output_path:
[Link](frame)
if show:
cv2_imshow(frame) # Use cv2_imshow instead of [Link]
if [Link](1) & 0xFF == ord('q'):
break
# Cleanup
[Link]()
if output_path:
[Link]()
[Link]()
return predictions
# Usage:
# Load your trained model
model = load_model('best_lstm_mobilenet_model.h5')
# Process video
process_video(
model=model,
video_path='/content/13469152_1920_1080_30fps.mp4',
output_path='/content/output_video.mp4',
show=True
)
[Link] 8/9
4/20/25, 2:17 PM Transfer_Learning.ipynb - Colab
WARNING:absl:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty unti
[Link] 9/9