哈嘍,大家好。
之前給大家分享過摔倒識(shí)別、打架識(shí)別?,今天以摔倒識(shí)別?為例,我們看看能不能完全交給ChatGPT來做。
讓ChatGPT?來做這件事,最核心的是如何向ChatGPT?提問,把問題一股腦的直接丟給ChatGPT?,如:用 Python 寫個(gè)摔倒檢測代碼 是不可取的, 而是要像擠牙膏一樣,一點(diǎn)一點(diǎn)引導(dǎo)ChatGPT?得到準(zhǔn)確的答案,從而才能真正讓ChatGPT提高我們解決問題的效率。
今天分享的摔倒識(shí)別?案例,與ChatGPT?對(duì)話的思路清晰,代碼可用度高,按照GPT?返回的結(jié)果完全可以開發(fā)一個(gè)摔倒識(shí)別的項(xiàng)目了,并且還有一些延伸的話題,如:畢設(shè)的改進(jìn)點(diǎn)。
下面開始正式的分享。
1. 角色設(shè)定
向ChatGPT?提問首先要給他一個(gè)角色設(shè)定,在算法領(lǐng)域這叫prompt,有了進(jìn)入了角色,才能更好地回答問題。所以,我提問的第一句是:
假如你是一名AI工程師,我想識(shí)別視頻中是否有摔倒行為,有哪些辦法
沒必要?jiǎng)偵蟻砭妥屗苯訉懘a,先問問他有哪些辦法或者思路。
我們看看ChatGPT的回答

給出了3個(gè)方案,有傳統(tǒng)的圖像方法,也有深度學(xué)習(xí)方法。
2. 思路引導(dǎo)
我們當(dāng)然是對(duì)深度學(xué)習(xí)感興趣了,所以繼續(xù)詢問關(guān)于深度學(xué)習(xí)的方法
使用深度學(xué)習(xí)的方法有哪些
ChatGPT回答

從卷積神經(jīng)網(wǎng)絡(luò)到卷積循環(huán)神經(jīng)網(wǎng)絡(luò)說了個(gè)遍。
看起來循環(huán)神經(jīng)網(wǎng)絡(luò) RNN更簡單、靠譜,接下來我的提問是
我需要 循環(huán)神經(jīng)網(wǎng)絡(luò) (RNN) 的方法
ChatGPT回答

給出了非常詳細(xì)的、實(shí)操性非常強(qiáng)的步驟,我簡單歸類一下,大致是兩步:
第一步,對(duì)視頻預(yù)處理,用卷積神經(jīng)網(wǎng)絡(luò)(如:ResNet)提取視頻動(dòng)作特征(類似 wordembedding) 第二步,用動(dòng)作特征作為 lstm 模型的輸入,訓(xùn)練 lstm 循環(huán)神經(jīng)網(wǎng)絡(luò),對(duì)動(dòng)作特征分類,從而識(shí)別出摔倒行為
3. 寫代碼
到目前,ChatGPT 提供給我們的,解決問題的思路非常清晰,并且可執(zhí)行性非常強(qiáng)。
所以,這時(shí)候我們可以讓ChatGPT寫代碼了。
按照我上面劃分的步驟,我讓他一次性把第一步代碼寫出來,所以,我的提問是:
寫一下視頻預(yù)處理的代碼,并用 pytorch resnet提取視頻特征
ChatGPT的回答
好的,下面是通過 Pytorch 的 ResNet 提取視頻特征的代碼,以及視頻預(yù)處理的示例代碼:
視頻預(yù)處理:
import cv2
import numpy as np
def preprocess_video(video_path, n_frames=16, resize=(224, 224)):
# 讀取視頻
cap = cv2.VideoCapture(video_path)
frames = []
while True:
ret, frame = cap.read()
if not ret:
break
# 強(qiáng)制轉(zhuǎn)換為 RGB
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
# 圖像縮放
frame = cv2.resize(frame, resize)
# 圖像增強(qiáng)等操作
# ...
frames.append(frame)
cap.release()
# 取固定幀數(shù) n_frames,超過后從中間開始截取
n_frames = min(len(frames), n_frames)
start = (len(frames) - n_frames) // 2
end = start + n_frames
# 截取幀數(shù)后堆疊成四維數(shù)組
frames = np.stack(frames[start:end], axis=0)
# 轉(zhuǎn)換為支持 Pytorch 模型的格式 (B, C, T, H, W)
frames = np.transpose(frames, (0, 3, 1, 2))
return frames
提取視頻特征:
import torch
import torchvision.models as models
def extract_features(frames):
# 加載 ResNet 模型
resnet = models.resnet50(pretrained=True)
# 去掉最后的全連接層
resnet = torch.nn.Sequential(*list(resnet.children())[:-1])
# 將 ResNet 設(shè)置為評(píng)估模式
resnet.eval()
# 將預(yù)處理后的視頻序列轉(zhuǎn)化為 Tensor,并調(diào)整為指定的數(shù)據(jù)類型和范圍
frames = torch.from_numpy(frames).float() / 255.0
# 減去 ImageNet 數(shù)據(jù)集的均值和標(biāo)準(zhǔn)差
normalize = torch.nn.Normalize(
mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]
)
frames = normalize(frames)
# 前向預(yù)測,輸出 2048 維特征向量
with torch.no_grad():
features = resnet(frames)
return features.reshape(-1, 2048)
在上面這兩塊代碼中,preprocess_video() 函數(shù)將讀取視頻,并將其轉(zhuǎn)換為指定大小的圖像幀,返回處理后的數(shù)據(jù);extract_features() 函數(shù)將接受上一步處理后的數(shù)據(jù),并將其轉(zhuǎn)化為 Pytorch 的 Tensor,使用訓(xùn)練好的 ResNet 模型對(duì)每一幀圖像進(jìn)行特征提取,并返回一個(gè)形狀為 (B, 2048) 的 Tensor,其中 B 為幀數(shù)。
圖片太長了,為了大家能更好的感受ChatGPT的回答,我直接把代碼文本貼出來了。
定義了兩個(gè)獨(dú)立函數(shù),分別完成了第一步中的兩小步內(nèi)容。
代碼沒有問題,先調(diào)用preprocess_video?函數(shù)對(duì)視頻預(yù)處理,再調(diào)用 extract_features?卷積操作,就可以將一個(gè)向量embedding?成一個(gè)2048維的向量。
第二步,我拆分成了兩小步,先搭建lstm模型,再訓(xùn)練
基于上面產(chǎn)出的結(jié)果,用 pytorch lstm搭建視頻分類模型
ChatGPT的回答

寫一下模型訓(xùn)練的代碼
ChatGPT的回答
好的,下面是使用 Pytorch 訓(xùn)練視頻分類模型的代碼:
import torch
import torch.nn as nn
import torch.optim as optim
# 訓(xùn)練函數(shù)
def train(model, criterion, optimizer, dataloader, num_epochs=10):
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device) # 將模型移動(dòng)到 GPU 或 CPU 上
for epoch in range(num_epochs):
running_loss = 0.0
correct_predictions = 0
total_predictions = 0
for inputs, labels in dataloader:
inputs = inputs.to(device)
labels = labels.to(device)
optimizer.zero_grad()
with torch.set_grad_enabled(True):
outputs = model(inputs)
_, preds = torch.max(outputs, 1)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item() * inputs.size(0)
correct_predictions += torch.sum(preds == labels.data)
total_predictions += labels.size(0)
epoch_loss = running_loss / len(dataloader.dataset)
epoch_acc = correct_predictions.double() / total_predictions
print("Epoch {}: Loss {:.4f} Acc: {:.4f}".format(epoch + 1, epoch_loss, epoch_acc))
# 定義超參數(shù)
BATCH_SIZE = 4
NUM_EPOCHS = 20
# 定義數(shù)據(jù)集,假設(shè)已經(jīng)準(zhǔn)備好了訓(xùn)練數(shù)據(jù)集和測試數(shù)據(jù)集
train_dataset = ...
test_dataset = ...
# 定義數(shù)據(jù)加載器
train_dataloader = torch.utils.data.DataLoader(
train_dataset, batch_size=BATCH_SIZE, shuffle=True
)
test_dataloader = torch.utils.data.DataLoader(
test_dataset, batch_size=BATCH_SIZE, shuffle=False
)
# 定義模型
input_size = 2048
hidden_size = 512
num_layers = 1
num_classes = 2
model = VideoLSTM(input_size, hidden_size, num_layers, num_classes)
# 定義損失函數(shù)和優(yōu)化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters())
# 訓(xùn)練模型
train(model, criterion, optimizer, train_dataloader, num_epochs=NUM_EPOCHS)
在代碼中,首先定義了模型的超參數(shù),如 BATCH_SIZE 和 NUM_EPOCHS。接著定義了訓(xùn)練數(shù)據(jù)集和測試數(shù)據(jù)集,并使用 Pytorch 的 DataLoader 將數(shù)據(jù)加載為 batch。然后定義了模型、損失函數(shù)和優(yōu)化器。最后調(diào)用 train() 函數(shù)進(jìn)行模型訓(xùn)練。
在訓(xùn)練過程中,每個(gè) epoch 循環(huán)訓(xùn)練所有的視頻幀,計(jì)算損失函數(shù),計(jì)算準(zhǔn)確率,并輸出當(dāng)前 epoch 的平均損失和準(zhǔn)確率。訓(xùn)練完成后,可以將模型的參數(shù)保存到磁盤上,以便以后使用。
代碼的可用性非常高。除了代碼串聯(lián)有一些成本,各個(gè)獨(dú)立模塊基本不需要?jiǎng)樱_發(fā)效率非常高效。
還可以讓ChatGPT找一些數(shù)據(jù)集

還可以讓他寫一下模型推理的代碼

他可以自動(dòng)幫我們把視頻預(yù)處理、特征提取和推理三部分都串起來,形成一個(gè)完整的項(xiàng)目。
4. 擴(kuò)展
到這里,我們就完全用ChatGPT把項(xiàng)目做完了。
我們還可以聊一些擴(kuò)展性的話題,如:

還可以讓ChatGPT幫我們想一些能突出學(xué)術(shù)價(jià)值的點(diǎn)

看到這里,說明我的文章對(duì)你多少有一丟丟的幫助。不管是否加入星球,我都感謝對(duì)大家對(duì)我的認(rèn)可和信任。