今天是第二十七天我們可以寫一個人工智慧結合lstm去分析多隻斑馬魚行為分析,並且預測斑馬魚身體狀態,以下是程式碼
我們需要經過數據預處理、特徵提取、LSTM 模型構建與訓練、模型評估等多個步驟。
首先,我們需要準備一個模擬的數據集,這個數據集應該包含多隻斑馬魚在不同時間點的行為數據,並附有它們的身體狀態標籤。
import numpy as np
import pandas as pd
# 模擬數據集參數
num_fish = 10 # 斑馬魚數量
num_timesteps = 100 # 時間步數
num_features = 5 # 行為特徵數量
state_labels = ['Normal', 'Stress', 'Fear', 'Anxiety', 'Depression'] # 身體狀態
# 模擬斑馬魚行為數據
data = np.random.rand(num_fish, num_timesteps, num_features)
# 模擬狀態標籤
labels = np.random.choice(state_labels, num_fish)
# 將數據轉換為 DataFrame 形式以便進行處理
columns = [f'feature_{i}' for i in range(num_features)]
df = pd.DataFrame({
'fish_id': np.repeat(np.arange(num_fish), num_timesteps),
'time_step': np.tile(np.arange(num_timesteps), num_fish),
**{columns[i]: data[:, :, i].flatten() for i in range(num_features)},
'state': np.repeat(labels, num_timesteps)
})
print(df.head())
在這一步,我們需要將數據進行標準化,並將標籤轉換為數字形式以便用於模型訓練。
from sklearn.preprocessing import LabelEncoder, StandardScaler
# 將特徵標準化
scaler = StandardScaler()
scaled_features = scaler.fit_transform(df[columns])
# 將狀態標籤進行數字化編碼
label_encoder = LabelEncoder()
encoded_labels = label_encoder.fit_transform(df['state'])
# 重塑數據以適應 LSTM 的輸入格式
X = scaled_features.reshape(num_fish, num_timesteps, num_features)
y = encoded_labels.reshape(num_fish, num_timesteps)
構建一個 LSTM 模型來分析行為數據並預測斑馬魚的身體狀態。
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout, TimeDistributed
# 構建 LSTM 模型
model = Sequential()
model.add(LSTM(128, input_shape=(num_timesteps, num_features), return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(64, return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(32, return_sequences=False))
model.add(Dropout(0.2))
model.add(Dense(64, activation='relu'))
model.add(Dense(len(state_labels), activation='softmax'))
# 編譯模型
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# 模型摘要
model.summary()
使用訓練數據來訓練模型。
# 訓練模型
history = model.fit(X, y, epochs=50, batch_size=2, validation_split=0.2)
在訓練完成後,使用測試數據來評估模型的準確性,並預測斑馬魚的身體狀態。
# 模擬新數據進行預測
new_data = np.random.rand(num_fish, num_timesteps, num_features)
scaled_new_data = scaler.transform(new_data.reshape(-1, num_features)).reshape(num_fish, num_timesteps, num_features)
# 預測斑馬魚的身體狀態
predictions = model.predict(scaled_new_data)
predicted_states = label_encoder.inverse_transform(np.argmax(predictions, axis=1))
print("Predicted States for Zebrafish: ", predicted_states)
import numpy as np
import pandas as pd
# 模擬數據集參數
num_fish = 10 # 斑馬魚數量
num_timesteps = 100 # 時間步數
num_features = 5 # 行為特徵數量
state_labels = ['Normal', 'Stress', 'Fear', 'Anxiety', 'Depression'] # 身體狀態
# 模擬斑馬魚行為數據
data = np.random.rand(num_fish, num_timesteps, num_features)
# 模擬狀態標籤
labels = np.random.choice(state_labels, num_fish)
# 將數據轉換為 DataFrame 形式以便進行處理
columns = [f'feature_{i}' for i in range(num_features)]
df = pd.DataFrame({
'fish_id': np.repeat(np.arange(num_fish), num_timesteps),
'time_step': np.tile(np.arange(num_timesteps), num_fish),
**{columns[i]: data[:, :, i].flatten() for i in range(num_features)},
'state': np.repeat(labels, num_timesteps)
})
print(df.head())
數據集參數設定:
num_fish
:定義了模擬的斑馬魚數量。num_timesteps
:定義了每隻斑馬魚行為記錄的時間步數。num_features
:每個時間步的行為特徵數量,例如速度、方向、距離等。state_labels
:定義了斑馬魚的五種身體狀態,包括正常、壓力、恐懼、焦慮、抑鬱。數據生成:
data
:使用 np.random.rand
生成了形狀為 (num_fish, num_timesteps, num_features)
的隨機數據矩陣,模擬多隻斑馬魚在不同時間步的行為特徵。labels
:隨機分配每隻斑馬魚的身體狀態。數據框準備:
columns
:為每個行為特徵命名,例如 feature_0
, feature_1
, 等等。df
:使用 pandas.DataFrame
生成數據框,其中包括魚的編號(fish_id
)、時間步(time_step
)、特徵數據和狀態標籤。print(df.head())
:打印數據框的前幾行來檢查數據。from sklearn.preprocessing import LabelEncoder, StandardScaler
# 將特徵標準化
scaler = StandardScaler()
scaled_features = scaler.fit_transform(df[columns])
# 將狀態標籤進行數字化編碼
label_encoder = LabelEncoder()
encoded_labels = label_encoder.fit_transform(df['state'])
# 重塑數據以適應 LSTM 的輸入格式
X = scaled_features.reshape(num_fish, num_timesteps, num_features)
y = encoded_labels.reshape(num_fish, num_timesteps)
標準化數據:
StandardScaler
:用來標準化特徵數據,使得每個特徵的均值為 0、標準差為 1。這有助於加快模型的收斂速度。scaled_features
:對 df[columns]
中的行為數據進行標準化,生成標準化後的數據矩陣。標籤編碼:
LabelEncoder
:將狀態標籤從字符串形式轉換為數字形式,例如 'Normal' -> 0, 'Stress' -> 1, 等等。encoded_labels
:將數據框中的 state
列進行編碼,生成數字形式的標籤。重塑數據:
X
:將標準化後的特徵數據重塑為 (num_fish, num_timesteps, num_features)
的形狀,以適應 LSTM 模型的輸入格式。y
:將編碼後的標籤數據重塑為 (num_fish, num_timesteps)
的形狀。import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout, TimeDistributed
# 構建 LSTM 模型
model = Sequential()
model.add(LSTM(128, input_shape=(num_timesteps, num_features), return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(64, return_sequences=True))
model.add(Dropout(0.2))
model.add(LSTM(32, return_sequences=False))
model.add(Dropout(0.2))
model.add(Dense(64, activation='relu'))
model.add(Dense(len(state_labels), activation='softmax'))
# 編譯模型
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
# 模型摘要
model.summary()
模型結構:
Sequential
:表示我們將按順序構建模型,每一層依次添加。LSTM(128)
:第一層 LSTM 有 128 個單元。input_shape
定義了輸入的形狀,即時間步數和每步的特徵數量。return_sequences=True
表示每一層 LSTM 都會返回完整的序列,而不是僅僅返回最後一個時間步的輸出。LSTM(64)
和 LSTM(32)
:後續的兩層 LSTM,分別具有 64 和 32 個單元。最後一層 LSTM 的 return_sequences=False
表示只返回最後一個時間步的輸出。Dropout(0.2)
:在每層 LSTM 之後添加 Dropout 層,以防止過擬合。20% 的神經元將在每次訓練更新中隨機忽略。Dense(64)
:一個全連接層,有 64 個神經元,激活函數使用 ReLU。Dense(len(state_labels))
:最終輸出層,其神經元數量與狀態標籤的數量一致,激活函數使用 softmax,用於多分類。編譯模型:
sparse_categorical_crossentropy
:適用於多類別的分類問題,標籤數據以整數形式表示。adam
:自適應學習率優化器,有助於更快且更穩定的訓練。accuracy
:評估指標是準確率。模型摘要:
model.summary()
:顯示模型的結構、層的順序、參數數量等信息。# 訓練模型
history = model.fit(X, y, epochs=50, batch_size=2, validation_split=0.2)
模型訓練:
epochs=50
:模型將訓練 50 個完整的數據集迭代(即 50 次完整的前向和反向傳播)。batch_size=2
:每次模型更新的數據批次大小為 2。較小的批次大小通常可以使模型學習得更穩定,但訓練速度可能會慢一些。validation_split=0.2
:20% 的數據將用於驗證集,以在訓練過程中評估模型的性能,這有助於監控過擬合情況。訓練過程:
sparse_categorical_crossentropy
,並計算每個 epoch 的準確率。history
:這個變量將保存模型訓練過程中的損失和準確率歷史記錄。# 模擬新數據進行預測
new_data = np.random.rand(1, num_timesteps, num_features)
new_data_scaled = scaler.transform(new_data.reshape(-1, num_features)).reshape(1, num_timesteps, num_features)
# 預測新數據的斑馬魚狀態
predicted_probs = model.predict(new_data_scaled)
predicted_state = label_encoder.inverse_transform(np.argmax(predicted_probs, axis=1))
print(f"預測的斑馬魚狀態為: {predicted_state[0]}")
模擬新數據:
new_data
:生成了一隻斑馬魚的隨機行為特徵數據,形狀為 (1, num_timesteps, num_features)
。new_data_scaled
:對新數據進行標準化處理,以確保與訓練數據的尺度一致。首先將數據展開為 2D 形式 (reshape(-1, num_features)
),標準化後再將其重塑回原始形狀。進行預測:
model.predict(new_data_scaled)
:模型會生成每個狀態的概率分佈(softmax 輸出),表示該斑馬魚屬於不同狀態的可能性。np.argmax(predicted_probs, axis=1)
:獲取概率最高的狀態的索引值,表示模型認為最有可能的斑馬魚狀態。label_encoder.inverse_transform()
:將數字化的預測標籤轉換回原始的狀態名稱。打印預測結果:
print(f"預測的斑馬魚狀態為: {predicted_state[0]}")
:顯示模型預測的斑馬魚身體狀態。import matplotlib.pyplot as plt
# 繪製訓練過程中的損失曲線
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Training and Validation Loss')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()
# 繪製訓練過程中的準確率曲線
plt.plot(history.history['accuracy'], label='Training Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.show()
損失和準確率可視化:
matplotlib
繪製訓練過程中的損失和準確率曲線。plt.plot(history.history['loss'])
和 plt.plot(history.history['val_loss'])
:分別繪製訓練集和驗證集的損失隨 epoch 變化的曲線,以觀察模型的收斂情況。plt.plot(history.history['accuracy'])
和 plt.plot(history.history['val_accuracy'])
:分別繪製訓練集和驗證集的準確率隨 epoch 變化的曲線。顯示圖表:
plt.show()
:在螢幕上顯示圖表,幫助你可視化模型的訓練過程,檢查是否存在過擬合(訓練損失顯著低於驗證損失)等問題。這段程式碼通過以下步驟來分析並預測多隻斑馬魚的行為狀態: