iT邦幫忙

2024 iThome 鐵人賽

DAY 28
0
Software Development

LSTM結合Yolo v8對於多隻斑馬魚行為分析系列 第 28

day 28 Lstm結合yolo v8 多隻斑馬魚行為分析效能評估

  • 分享至 

  • xImage
  •  

今天是第二十八天我們可以寫一個Lstm結合yolo v8多隻斑馬魚行為分析的效能評估,以下是程式碼

import torch
import cv2
import numpy as np
from ultralytics import YOLO
from keras.models import Sequential
from keras.layers import LSTM, Dense, Dropout
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

# 1. 加載YOLOv8模型並進行斑馬魚檢測與追蹤
def detect_and_track(video_path, model_path):
    model = YOLO(model_path)
    cap = cv2.VideoCapture(video_path)
    tracks = []
    
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        results = model(frame)
        boxes = results.xyxy[0].cpu().numpy()  # 提取YOLO檢測框
        
        # 簡單的跟蹤策略:以最近的框位置作為跟蹤結果
        for box in boxes:
            x1, y1, x2, y2, conf, cls = box
            tracks.append([(x1 + x2) / 2, (y1 + y2) / 2])  # 使用框中心作為位置
        
    cap.release()
    return np.array(tracks)

# 2. 特徵提取
def extract_features(tracks, lookback=9):
    features = []
    for i in range(len(tracks) - lookback):
        feature = tracks[i:i+lookback]  # 提取過去lookback步的位置信息
        speed = np.linalg.norm(feature[1:] - feature[:-1], axis=1)  # 計算速度
        angles = np.arctan2(feature[1:, 1] - feature[:-1, 1], feature[1:, 0] - feature[:-1, 0])  # 計算角度
        feature = np.hstack((feature.flatten(), speed, angles))
        features.append(feature)
    return np.array(features)

# 3. LSTM模型訓練與預測
def train_lstm_model(X_train, y_train, input_shape):
    model = Sequential()
    model.add(LSTM(128, input_shape=input_shape, return_sequences=True))
    model.add(Dropout(0.2))
    model.add(LSTM(64, return_sequences=False))
    model.add(Dropout(0.2))
    model.add(Dense(64, activation='relu'))
    model.add(Dense(2))  # 假設預測的行為是二分類問題

    model.compile(optimizer='adam', loss='mse')
    model.fit(X_train, y_train, epochs=50, batch_size=64, validation_split=0.2)
    return model

# 4. 效能評估
def evaluate_performance(model, X_test, y_test):
    y_pred = model.predict(X_test)
    accuracy = accuracy_score(y_test, np.round(y_pred))
    precision = precision_score(y_test, np.round(y_pred), average='weighted')
    recall = recall_score(y_test, np.round(y_pred), average='weighted')
    f1 = f1_score(y_test, np.round(y_pred), average='weighted')
    return accuracy, precision, recall, f1

# 主流程
video_path = 'path_to_your_video.mp4'
yolo_model_path = 'path_to_yolo_v8_weights.pt'
lstm_model_path = 'path_to_save_lstm_model.h5'

# 步驟1:檢測與跟蹤
tracks = detect_and_track(video_path, yolo_model_path)

# 步驟2:特徵提取
lookback = 9  # 根據需求調整
features = extract_features(tracks, lookback)

# 假設我們有標註好的行為類別
labels = ...  # 加載標籤數據
X_train, X_test, y_train, y_test = ...  # 將數據分為訓練集和測試集

# 步驟3:LSTM訓練
input_shape = (X_train.shape[1], X_train.shape[2])
lstm_model = train_lstm_model(X_train, y_train, input_shape)

# 步驟4:模型評估
accuracy, precision, recall, f1 = evaluate_performance(lstm_model, X_test, y_test)
print(f"Accuracy: {accuracy}, Precision: {precision}, Recall: {recall}, F1 Score: {f1}")

1. YOLOv8模型檢測與追蹤 (detect_and_track 函數)

def detect_and_track(video_path, model_path):
    model = YOLO(model_path)
    cap = cv2.VideoCapture(video_path)
    tracks = []
    
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        results = model(frame)
        boxes = results.xyxy[0].cpu().numpy()
        
        for box in boxes:
            x1, y1, x2, y2, conf, cls = box
            tracks.append([(x1 + x2) / 2, (y1 + y2) / 2])
        
    cap.release()
    return np.array(tracks)

功能說明:

  • YOLO模型加載:使用YOLO(model_path)加載YOLOv8模型。
  • 視頻捕捉:使用cv2.VideoCapture(video_path)打開視頻文件,並逐幀處理視頻。
  • 斑馬魚檢測:對每一幀圖片,YOLO模型進行目標檢測,返回目標邊界框(boxes),每個框包括四個邊界坐標(x1, y1, x2, y2)、置信度(conf)和分類標籤(cls)。
  • 目標跟蹤:通過計算邊界框的中心點,將每一幀的斑馬魚位置記錄在tracks列表中。
  • 返回結果:最後返回所有斑馬魚位置的列表,tracks是由每幀位置組成的二維數組。

2. 特徵提取 (extract_features 函數)

def extract_features(tracks, lookback=9):
    features = []
    for i in range(len(tracks) - lookback):
        feature = tracks[i:i+lookback]
        speed = np.linalg.norm(feature[1:] - feature[:-1], axis=1)
        angles = np.arctan2(feature[1:, 1] - feature[:-1, 1], feature[1:, 0] - feature[:-1, 0])
        feature = np.hstack((feature.flatten(), speed, angles))
        features.append(feature)
    return np.array(features)

功能說明:

  • 特徵窗口:為每個時間步提取一個大小為lookback的窗口,這個窗口包含該時間點之前lookback步的所有位置信息。
  • 速度計算:通過計算每兩個相鄰位置之間的歐幾里得距離來獲得速度。
  • 角度計算:使用arctan2函數計算位置變化的角度,這可以描述斑馬魚的運動方向。
  • 特徵拼接:將位置、速度和角度數據拼接成一個長的特徵向量。最終這些特徵將作為LSTM模型的輸入。

3. LSTM模型訓練與預測 (train_lstm_model 函數)

def train_lstm_model(X_train, y_train, input_shape):
    model = Sequential()
    model.add(LSTM(128, input_shape=input_shape, return_sequences=True))
    model.add(Dropout(0.2))
    model.add(LSTM(64, return_sequences=False))
    model.add(Dropout(0.2))
    model.add(Dense(64, activation='relu'))
    model.add(Dense(2))  # 假設預測的行為是二分類問題

    model.compile(optimizer='adam', loss='mse')
    model.fit(X_train, y_train, epochs=50, batch_size=64, validation_split=0.2)
    return model

功能說明:

  • 模型結構

    • 第一層LSTM有128個單元,並且返回所有時間步的輸出(return_sequences=True)。
    • 第二層LSTM有64個單元,不返回序列(return_sequences=False),即只返回最後一個時間步的輸出。
    • Dropout層用於防止過擬合,每層LSTM之後都加了一個Dropout層。
    • 最後是兩個全連接層,最終輸出一個大小為2的向量,用於二分類問題。
  • 編譯與訓練

    • 模型使用adam優化器,mse損失函數進行編譯。
    • 使用model.fit方法進行訓練,迭代50次(epochs=50),每次批量處理64個樣本,並將20%的數據用於驗證。

4. 效能評估 (evaluate_performance 函數)

def evaluate_performance(model, X_test, y_test):
    y_pred = model.predict(X_test)
    accuracy = accuracy_score(y_test, np.round(y_pred))
    precision = precision_score(y_test, np.round(y_pred), average='weighted')
    recall = recall_score(y_test, np.round(y_pred), average='weighted')
    f1 = f1_score(y_test, np.round(y_pred), average='weighted')
    return accuracy, precision, recall, f1

功能說明:

  • 預測:使用訓練好的LSTM模型對測試數據進行預測。

  • 指標計算

    • accuracy_score:計算預測的準確率。
    • precision_score:計算預測的精確率,使用加權平均(average='weighted')。
    • recall_score:計算預測的召回率,同樣使用加權平均。
    • f1_score:計算F1分數,這是精確率和召回率的調和平均數。
  • 返回結果:最終返回這些效能指標。

5. 主流程

video_path = 'path_to_your_video.mp4'
yolo_model_path = 'path_to_yolo_v8_weights.pt'
lstm_model_path = 'path_to_save_lstm_model.h5'

tracks = detect_and_track(video_path, yolo_model_path)
features = extract_features(tracks, lookback=9)

# 假設我們有標註好的行為類別
labels = ...  # 加載標籤數據
X_train, X_test, y_train, y_test = ...  # 將數據分為訓練集和測試集

input_shape = (X_train.shape[1], X_train.shape[2])
lstm_model = train_lstm_model(X_train, y_train, input_shape)

accuracy, precision, recall, f1 = evaluate_performance(lstm_model, X_test, y_test)
print(f"Accuracy: {accuracy}, Precision: {precision}, Recall: {recall}, F1 Score: {f1}")

功能說明:

  • 資料路徑:指定視頻、YOLO模型權重和LSTM模型保存路徑。
  • 檢測與追蹤:調用detect_and_track函數檢測視頻中的斑馬魚並跟蹤它們的位置。
  • 特徵提取:提取用於LSTM輸入的特徵。
  • 訓練和測試資料:將特徵和行為標籤分成訓練集和測試集。
  • 模型訓練:訓練LSTM模型。
  • 效能評估:計算模型的準確率、精確率、召回率和F1分數,並打印出結果。

這段程式碼的設計目的是結合YOLOv8的強大目標檢測能力和LSTM在序列數據上的預測能力,實現多隻斑馬魚行為的自動化分析和評估。


上一篇
Day 27Lstm與Yolo多斑馬魚行為分析介面mock test
下一篇
day 29 lstm結合yolo v8對於多隻斑馬魚行為分析
系列文
LSTM結合Yolo v8對於多隻斑馬魚行為分析29
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言