今天是第二十六天我們可以寫一個lstm分析水溫對斑馬魚行為的影響,以下是程式碼
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout
import matplotlib.pyplot as plt
# 1. 加載數據
data = pd.read_csv('data.csv') # 假設有時間、溫度和行為的列
# 2. 數據預處理
# 假設 "Temperature" 是水溫列, "Behavior" 是行為數據
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(data[['Temperature', 'Behavior']])
# 3. 創建序列數據,設置時間步長
def create_sequences(data, seq_length):
xs, ys = [], []
for i in range(len(data) - seq_length):
x = data[i:i+seq_length]
y = data[i+seq_length][1] # 行為預測
xs.append(x)
ys.append(y)
return np.array(xs), np.array(ys)
SEQ_LENGTH = 50 # 設置LSTM的時間步長
X, y = create_sequences(scaled_data, SEQ_LENGTH)
# 4. 拆分訓練和測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 5. 構建LSTM模型
model = Sequential()
model.add(LSTM(units=100, return_sequences=True, input_shape=(SEQ_LENGTH, 2)))
model.add(Dropout(0.2))
model.add(LSTM(units=100))
model.add(Dropout(0.2))
model.add(Dense(units=1)) # 預測行為數據
model.compile(optimizer='adam', loss='mean_squared_error')
# 6. 訓練模型
history = model.fit(X_train, y_train, epochs=20, batch_size=32, validation_data=(X_test, y_test))
# 7. 評估模型
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.legend()
plt.show()
# 8. 預測測試集行為
predictions = model.predict(X_test)
# 9. 將預測結果反歸一化
predicted_behavior = scaler.inverse_transform(np.concatenate((np.zeros((predictions.shape[0], 1)), predictions), axis=1))[:, 1]
real_behavior = scaler.inverse_transform(np.concatenate((np.zeros((y_test.shape[0], 1)), y_test.reshape(-1, 1)), axis=1))[:, 1]
# 10. 繪製預測結果與實際結果對比圖
plt.plot(real_behavior, color='blue', label='Real Behavior')
plt.plot(predicted_behavior, color='red', label='Predicted Behavior')
plt.title('Real vs Predicted Zebrafish Behavior')
plt.xlabel('Time')
plt.ylabel('Behavior')
plt.legend()
plt.show()
data = pd.read_csv('data.csv') # 假設有時間、溫度和行為的列
這一步使用 pandas
讀取名為 data.csv
的數據文件。假設這個文件包含多個列,如 Temperature
(水溫)、Behavior
(斑馬魚的行為數據)以及 Time
(時間標記)。
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(data[['Temperature', 'Behavior']])
數據標準化是一個重要的步驟。MinMaxScaler
將數據縮放到 [0, 1]
之間,這樣能夠確保LSTM模型訓練過程中的穩定性,避免過大或過小的數據對模型訓練造成影響。fit_transform()
函數對數據進行標準化,並返回標準化後的數據。
這裡我們只對 Temperature
和 Behavior
兩個特徵進行縮放。
def create_sequences(data, seq_length):
xs, ys = []
for i in range(len(data) - seq_length):
x = data[i:i+seq_length]
y = data[i+seq_length][1] # 行為預測
xs.append(x)
ys.append(y)
return np.array(xs), np.array(ys)
SEQ_LENGTH = 50 # 設置LSTM的時間步長
X, y = create_sequences(scaled_data, SEQ_LENGTH)
LSTM是擅長處理序列數據的模型,因此需要將數據組織成序列。這段代碼的核心思想是:
seq_length
:定義每個輸入序列的長度。這裡設置為50,表示每次用前50個時間步的數據來預測下一個時間步的行為。create_sequences()
:這個函數將連續的數據轉換成多個序列。x
是一個長度為 seq_length
的數據片段,而 y
是對應的目標行為值。最終返回的是兩個numpy數組:X
(特徵序列) 和 y
(對應的標籤值)。X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
這裡使用 train_test_split
函數將數據分成訓練集和測試集。test_size=0.2
表示20%的數據用來做測試,其餘80%用來訓練模型。random_state
設置為42,以保證每次運行時劃分的數據集是一樣的(即使重新運行代碼)。
model = Sequential()
model.add(LSTM(units=100, return_sequences=True, input_shape=(SEQ_LENGTH, 2)))
model.add(Dropout(0.2))
model.add(LSTM(units=100))
model.add(Dropout(0.2))
model.add(Dense(units=1)) # 預測行為數據
model.compile(optimizer='adam', loss='mean_squared_error')
這段代碼構建了一個LSTM神經網絡模型,步驟如下:
Sequential()
是Keras中的一個模型容器,用來順序地堆疊各層神經網絡層。units=100
:LSTM層包含100個記憶單元。return_sequences=True
:因為我們有多層LSTM,因此需要返回整個序列。input_shape=(SEQ_LENGTH, 2)
:輸入數據的形狀,這裡是 (50, 2)
,表示每個序列包含50個時間步長,每個時間步有兩個特徵(溫度和行為)。mean_squared_error
(均方誤差),優化器為 adam
。history = model.fit(X_train, y_train, epochs=20, batch_size=32, validation_data=(X_test, y_test))
這一步是訓練模型的過程。參數如下:
這段代碼會返回一個 history
對象,包含了訓練過程中的損失和驗證損失等信息。
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.legend()
plt.show()
這裡通過繪製損失曲線來觀察訓練過程中的損失變化。這包括訓練損失(loss
)和驗證損失(val_loss
)。理想情況下,兩者應該都在隨著訓練過程的進行而減少。
predictions = model.predict(X_test)
使用訓練好的模型對測試集數據進行預測。predictions
是模型對測試集的行為預測結果。
predicted_behavior = scaler.inverse_transform(np.concatenate((np.zeros((predictions.shape[0], 1)), predictions), axis=1))[:, 1]
real_behavior = scaler.inverse_transform(np.concatenate((np.zeros((y_test.shape[0], 1)), y_test.reshape(-1, 1)), axis=1))[:, 1]
因為在數據預處理時,我們對數據進行了標準化,現在需要將預測結果和實際行為數據反歸一化回到原始數據範圍。
這裡將預測值和真實值與一個零列拼接,然後使用之前的 scaler
反歸一化,再取出我們關心的行為數據列(第1列)。
plt.plot(real_behavior, color='blue', label='Real Behavior')
plt.plot(predicted_behavior, color='red', label='Predicted Behavior')
plt.title('Real vs Predicted Zebrafish Behavior')
plt.xlabel('Time')
plt.ylabel('Behavior')
plt.legend()
plt.show()
最後,將預測結果和真實結果繪製出來,用來直觀地比較模型的預測效果。real_behavior
是測試集中真實的行為數據,而 predicted_behavior
是模型的預測結果。
這段代碼的主要流程包括: