vr中風--數據處理模型搭建與訓練2

位置http://localhost:8888/notebooks/Untitled1-Copy1.ipynb

# -*- coding: utf-8 -*-
"""
MUSED-I康復評估系統(增強版)
包含:多通道sEMG數據增強、混合模型架構、標準化處理
"""
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from collections import defaultdict
import tensorflow as tf# 隨機種子設置
SEED = 42
np.random.seed(SEED)
tf.random.set_seed(SEED)
# -------------------- 第一部分:數據增強器 --------------------
class SEMGDataGenerator:"""sEMG數據增強器(支持多通道)增強策略:- 分通道時間扭曲- 通道獨立噪聲添加- 幅度縮放- 通道偏移"""def __init__(self, noise_scale=0.2, stretch_range=(0.6, 1.4)):# 增強噪聲強度和時間扭曲范圍self.noise_scale = noise_scaleself.stretch_range = stretch_rangedef channel_dropout(self, signals, max_drop=2):"""隨機屏蔽部分通道"""drop_mask = np.random.choice(signals.shape[1], max_drop, replace=False)signals[:, drop_mask] = 0return signalsdef time_warp(self, signals):"""時間扭曲(分通道處理)"""orig_length = signals.shape[0]scale = np.random.uniform(*self.stretch_range)new_length = int(orig_length * scale)x_orig = np.linspace(0, 1, orig_length)x_new = np.linspace(0, 1, new_length)warped = np.zeros_like(signals)for c in range(signals.shape[1]):  # 分通道處理warped_single = np.interp(x_new, x_orig, signals[:, c])if new_length >= orig_length:warped[:, c] = warped_single[:orig_length]else:padded = np.zeros(orig_length)padded[:new_length] = warped_singlewarped[:, c] = paddedreturn warpeddef add_noise(self, signals):"""添加高斯噪聲(通道獨立)"""# 每個通道獨立生成噪聲noise = np.zeros_like(signals)for c in range(signals.shape[1]):channel_std = np.std(signals[:, c])noise[:, c] = np.random.normal(scale=self.noise_scale*channel_std, size=signals.shape[0])return signals + noisedef amplitude_scale(self, signals):"""幅度縮放(全通道同步)"""scale = np.random.uniform(0.7, 1.3)return signals * scaledef channel_shift(self, signals):"""通道偏移(循環平移)"""shift = np.random.randint(-3, 3)return np.roll(signals, shift, axis=1)  # 沿通道軸偏移def augment(self, window):"""應用至少一種增強策略"""aug_window = window.copy()applied = Falseattempts = 0  # 防止無限循環# 嘗試應用直到至少成功一次(最多嘗試5次)while not applied and attempts < 5:if np.random.rand() > 0.5:aug_window = self.time_warp(aug_window)applied = Trueif np.random.rand() > 0.5:aug_window = self.add_noise(aug_window)applied = Trueif np.random.rand() > 0.5:aug_window = self.amplitude_scale(aug_window)applied = Trueif np.random.rand() > 0.5:window = np.flip(window, axis=0)                if np.random.rand() > 0.5:aug_window = self.channel_shift(aug_window)applied = Trueattempts += 1return aug_window
# -------------------- 第二部分:數據處理管道 --------------------
def load_and_preprocess(file_path, label, window_size=100, augment_times=5):"""完整數據處理流程參數:file_path: CSV文件路徑label: 數據標簽 (1.0=健康人, 0.0=患者)window_size: 時間窗口長度(單位:采樣點)augment_times: 每個樣本的增強次數返回:features: 形狀 (n_samples, window_size, n_channels)labels: 形狀 (n_samples,)"""# 1. 數據加載df = pd.read_csv(file_path, usecols=range(8))#df = df.dropna()  # 確保只讀取前8列print("前8列統計描述:\n", df.describe())# 檢查是否存在非數值或缺失值if df.isnull().any().any():print("發現缺失值,位置:\n", df.isnull().sum())df.fillna(method='ffill', inplace=True) # 可以考慮前向填充或均值填充,而非直接刪除if df.isnull().any().any(): # 如果仍有NaN(例如開頭就是NaN),再刪除df.dropna(inplace=True)print("刪除含缺失值的行后形狀:", df.shape)# 檢查無窮大值if np.isinf(df.values).any():print("發現無窮大值,將其替換為NaN并刪除行。")df = df.replace([np.inf, -np.inf], np.nan).dropna()print("刪除含無窮大值的行后形狀:", df.shape)df = df.astype(np.float64) # 確保數據類型正確print(f"[1/5] 數據加載完成 | 原始數據形狀: {df.shape}")# 2. 窗口分割windows = []step = window_size // 2  # 50%重疊n_channels = 8  # 假設前8列為sEMG信號for start in range(0, len(df)-window_size+1, step):end = start + window_sizewindow = df.iloc[start:end, :n_channels].values  # (100,8)# 維度校驗if window.ndim == 1:window = window.reshape(-1, 1)elif window.shape[1] != n_channels:raise ValueError(f"窗口通道數異常: {window.shape}")windows.append(window)print(f"[2/5] 窗口分割完成 | 總窗口數: {len(windows)} | 窗口形狀: {windows[0].shape}")# 3. 數據增強generator = SEMGDataGenerator(noise_scale=0.05)augmented = []for w in windows:augmented.append(w)for _ in range(augment_times):try:aug_w = generator.augment(w)# 檢查增強結果if not np.isfinite(aug_w).all():raise ValueError("增強生成無效值")augmented.append(aug_w)except Exception as e:print(f"增強失敗: {e}")continueprint(f"[3/5] 數據增強完成 | 總樣本數: {len(augmented)} (原始x{augment_times+1})")# 4. 形狀一致性校驗expected_window_shape = (window_size, n_channels) # 明確期望的形狀filtered = [arr for arr in augmented if arr.shape == expected_window_shape]if len(filtered) < len(augmented):print(f"警告: 過濾掉 {len(augmented) - len(filtered)} 個形狀不符合 {expected_window_shape} 的增強樣本。")print(f"[4/5] 形狀過濾完成 | 有效樣本率: {len(filtered)}/{len(augmented)}")# 轉換為數組features = np.stack(filtered)assert not np.isnan(features).any(), "增強數據中存在NaN"assert not np.isinf(features).any(), "增強數據中存在Inf"labels = np.full(len(filtered), label)return features, labels
# -------------------- 第三部分:標準化與數據集劃分 --------------------
def channel_standardize(data):"""逐通道標準化"""# data形狀: (samples, timesteps, channels)mean = np.nanmean(data, axis=(0,1), keepdims=True)std = np.nanstd(data, axis=(0,1), keepdims=True)# 防止除零錯誤:若標準差為0,設置為1std_fixed = np.where(std == 0, 1.0, std)return (data - mean) / (std_fixed + 1e-8)
# -------------------- 執行主流程 --------------------
if __name__ == "__main__":# 數據加載與增強X_healthy, y_healthy = load_and_preprocess('Healthy_Subjects_Data3_DOF.csv', label=1.0,window_size=100,augment_times=5)X_patient, y_patient = load_and_preprocess('Stroke_Patients_DataPatient1_3DOF.csv',label=0.0,window_size=100,augment_times=5)# 合并數據集X = np.concatenate([X_healthy, X_patient], axis=0)y = np.concatenate([y_healthy, y_patient], axis=0)print(f"\n合并數據集形狀: X{X.shape} y{y.shape}")# 數據標準化X = channel_standardize(X)# 數據集劃分X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, stratify=y,random_state=SEED)print("\n最終數據集:")print(f"訓練集: {X_train.shape} | 0類樣本數: {np.sum(y_train==0)}")print(f"驗證集: {X_val.shape} | 1類樣本數: {np.sum(y_val==1)}")# 驗證標準化效果sample_channel = 0print(f"\n標準化驗證 (通道{sample_channel}):")print(f"均值: {np.mean(X_train[:, :, sample_channel]):.2f} (±{np.std(X_train[:, :, sample_channel]):.2f})")
from tensorflow.keras import layers, optimizers, callbacks, Model
# -------------------- 第三部分:模型架構 --------------------
def build_model(input_shape):"""混合CNN+BiGRU模型"""inputs = layers.Input(shape=input_shape)# 特征提取分支x = layers.Conv1D(32, 15, activation='relu', padding='same', kernel_regularizer='l2')(inputs)  # 添加L2正則化x = layers.MaxPooling1D(2)(x)x = layers.Dropout(0.3)(x)  # 添加Dropoutx = layers.Conv1D(64, 7, activation='relu', padding='same')(x)x = layers.MaxPooling1D(2)(x)x = layers.Bidirectional(layers.GRU(32, return_sequences=True))(x)x = layers.Dropout(0.3)(x)  # 第二層Dropout# 差異注意力機制attention = layers.Attention()([x, x])x = layers.Concatenate()([x, attention])# 回歸輸出層x = layers.GlobalAveragePooling1D()(x)x = layers.Dense(16, activation='relu')(x)outputs = layers.Dense(1, activation='sigmoid')(x)model = tf.keras.Model(inputs, outputs)return model# 初始化模型
model = build_model(input_shape=(100, 8))
model.compile(optimizer=optimizers.Adam(learning_rate=0.001),loss='binary_crossentropy',metrics=['accuracy', tf.keras.metrics.AUC(name='auc')]
)
model.summary()
import matplotlib.pyplot as plt
# -------------------- 第四部分:模型訓練 --------------------
# 定義回調
early_stop = callbacks.EarlyStopping(monitor='val_auc', patience=10,mode='max',restore_best_weights=True
)# 訓練模型
history = model.fit(X_train, y_train,validation_data=(X_val, y_val),epochs=100,batch_size=32,callbacks=[early_stop],verbose=1
)
# -------------------- 第五部分:康復評估與可視化 --------------------
# 改進后的可視化和報告生成
# ... (訓練過程可視化部分不變) ...# 確保在調用 generate_report 之前有足夠的子圖空間
# 比如在 train_test_split 之后或者在 model.fit 之后
# 可以將整體可視化邏輯放到一個主函數中,或者明確創建 figure 和 axes
plt.figure(figsize=(18, 6)) # 增加figure大小以容納更多圖表
plt.subplot(1, 3, 1)
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Loss Curve')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()plt.subplot(1, 3, 2)
plt.plot(history.history['accuracy'], label='Train Accuracy') # 也可以加上準確率
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.plot(history.history['auc'], label='Train AUC')
plt.plot(history.history['val_auc'], label='Validation AUC')
plt.title('Performance Metrics')
plt.xlabel('Epoch')
plt.ylabel('Value')
plt.legend()# 生成康復報告
def generate_report(model, patient_data):"""生成定量康復評估報告"""# 預測所有窗口#predictions = model.predict(patient_data).flatten()# 計算康復指數(0-100%)#recovery_index = np.mean(predictions) * 100predictions = model.predict(patient_data).flatten()recovery_index = (1 - np.mean(predictions)) * 100  # 可視化預測分布plt.subplot(133)plt.hist(predictions, bins=20, alpha=0.7)plt.axvline(x=np.mean(predictions), color='red', linestyle='--')plt.title('Prediction Distribution\nMean R-index: %.1f%%' % recovery_index)# 可視化預測分布到傳入的ax上# 生成文字報告print(f"""======== 智能康復評估報告 ========分析窗口總數:{len(patient_data)}平均康復指數:{recovery_index:.1f}%最佳窗口表現:{np.max(predictions)*100:.1f}%最弱窗口表現:{np.min(predictions)*100:.1f}%--------------------------------臨床建議:{ "建議加強基礎動作訓練" if recovery_index <40 else "建議進行中等強度康復訓練" if recovery_index <70 else "建議開展精細動作訓練" if recovery_index <90 else "接近健康水平,建議維持訓練"}""")
X_patient
# 使用患者數據生成報告
generate_report(model, X_patient)plt.tight_layout()
plt.show()
前8列統計描述:0            -2          -2.1            -3            -1  \
count  14970.000000  14970.000000  14970.000000  14970.000000  14970.000000   
mean      -0.867602     -1.022044     -1.174883     -1.057315     -0.926921   
std        4.919823      8.380565     20.082498     11.550257      6.344825   
min     -128.000000   -128.000000   -128.000000   -128.000000    -92.000000   
25%       -3.000000     -3.000000     -3.000000     -3.000000     -3.000000   
50%       -1.000000     -1.000000     -1.000000     -1.000000     -1.000000   
75%        1.000000      2.000000      1.000000      2.000000      1.000000   
max       80.000000     79.000000    127.000000    127.000000    116.000000   -2.2          -1.1          -2.3  
count  14970.000000  14970.000000  14970.000000  
mean      -0.824916     -0.888377     -0.901804  
std       10.461558      7.863457     12.304696  
min     -128.000000   -128.000000   -128.000000  
25%       -3.000000     -3.000000     -3.000000  
50%       -1.000000     -1.000000     -1.000000  
75%        1.000000      1.000000      1.000000  
max      127.000000    127.000000    127.000000  
發現缺失值,位置:0       354
-2      354
-2.1    354
-3      354
-1      354
-2.2    354
-1.1    354
-2.3    354
dtype: int64
[1/5] 數據加載完成 | 原始數據形狀: (15324, 8)
[2/5] 窗口分割完成 | 總窗口數: 305 | 窗口形狀: (100, 8)
[3/5] 數據增強完成 | 總樣本數: 1830 (原始x6)
[4/5] 形狀過濾完成 | 有效樣本率: 1830/1830
前8列統計描述:-1          -1.1             2          -1.2          -1.3  \
count  14970.000000  14970.000000  14970.000000  14970.000000  14970.000000   
mean      -1.065531     -0.838009     -2.973747     -0.028925     -0.857916   
std       33.651163     17.704589     49.101199     34.155909     13.400751   
min     -128.000000   -128.000000   -128.000000   -128.000000   -128.000000   
25%       -8.000000     -6.000000    -13.000000     -7.000000     -5.000000   
50%       -1.000000     -1.000000     -1.000000     -1.000000     -1.000000   
75%        6.000000      5.000000      6.000000      6.000000      4.000000   
max      127.000000    127.000000    127.000000    127.000000     89.000000   3             0            -6  
count  14970.000000  14970.000000  14970.000000  
mean      -0.868003     -0.794990     -0.784636  
std       12.125684     12.950926     20.911681  
min      -73.000000   -128.000000   -128.000000  
25%       -6.000000     -6.000000     -5.000000  
50%        0.000000     -1.000000     -1.000000  
75%        5.000000      4.000000      4.000000  
max       85.000000    127.000000    127.000000  
發現缺失值,位置:-1      10
-1.1    10
2       10
-1.2    10
-1.3    10
3       10
0       10
-6      10
dtype: int64
[1/5] 數據加載完成 | 原始數據形狀: (14980, 8)
[2/5] 窗口分割完成 | 總窗口數: 298 | 窗口形狀: (100, 8)
C:\Users\guoxi\AppData\Local\Temp\ipykernel_32276\2631219684.py:22: FutureWarning: DataFrame.fillna with 'method' is deprecated and will raise in a future version. Use obj.ffill() or obj.bfill() instead.df.fillna(method='ffill', inplace=True) # 可以考慮前向填充或均值填充,而非直接刪除
C:\Users\guoxi\AppData\Local\Temp\ipykernel_32276\2631219684.py:22: FutureWarning: DataFrame.fillna with 'method' is deprecated and will raise in a future version. Use obj.ffill() or obj.bfill() instead.df.fillna(method='ffill', inplace=True) # 可以考慮前向填充或均值填充,而非直接刪除
[3/5] 數據增強完成 | 總樣本數: 1788 (原始x6)
[4/5] 形狀過濾完成 | 有效樣本率: 1788/1788合并數據集形狀: X(3618, 100, 8) y(3618,)最終數據集:
訓練集: (2894, 100, 8) | 0類樣本數: 1430
驗證集: (724, 100, 8) | 1類樣本數: 366標準化驗證 (通道0):
均值: -0.00 (±1.00)

Epoch 1/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 3s 11ms/step - accuracy: 0.6770 - auc: 0.7914 - loss: 0.6707 - val_accuracy: 0.8550 - val_auc: 0.9253 - val_loss: 0.4116
Epoch 2/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.8780 - auc: 0.9416 - loss: 0.3534 - val_accuracy: 0.9047 - val_auc: 0.9750 - val_loss: 0.2717
Epoch 3/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.9208 - auc: 0.9734 - loss: 0.2469 - val_accuracy: 0.9171 - val_auc: 0.9774 - val_loss: 0.2604
Epoch 4/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9331 - auc: 0.9800 - loss: 0.2262 - val_accuracy: 0.9240 - val_auc: 0.9843 - val_loss: 0.2364
Epoch 5/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9407 - auc: 0.9854 - loss: 0.2024 - val_accuracy: 0.8950 - val_auc: 0.9773 - val_loss: 0.3147
Epoch 6/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 7ms/step - accuracy: 0.9476 - auc: 0.9869 - loss: 0.1952 - val_accuracy: 0.9475 - val_auc: 0.9922 - val_loss: 0.1946
Epoch 7/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9603 - auc: 0.9913 - loss: 0.1624 - val_accuracy: 0.9365 - val_auc: 0.9888 - val_loss: 0.1864
Epoch 8/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 9ms/step - accuracy: 0.9688 - auc: 0.9949 - loss: 0.1349 - val_accuracy: 0.9461 - val_auc: 0.9916 - val_loss: 0.2021
Epoch 9/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9573 - auc: 0.9940 - loss: 0.1433 - val_accuracy: 0.9530 - val_auc: 0.9930 - val_loss: 0.1688
Epoch 10/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9686 - auc: 0.9961 - loss: 0.1302 - val_accuracy: 0.9586 - val_auc: 0.9923 - val_loss: 0.1617
Epoch 11/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9790 - auc: 0.9965 - loss: 0.1094 - val_accuracy: 0.9392 - val_auc: 0.9856 - val_loss: 0.2092
Epoch 12/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 9ms/step - accuracy: 0.9577 - auc: 0.9913 - loss: 0.1587 - val_accuracy: 0.9544 - val_auc: 0.9940 - val_loss: 0.1531
Epoch 13/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9806 - auc: 0.9967 - loss: 0.1031 - val_accuracy: 0.9475 - val_auc: 0.9821 - val_loss: 0.2452
Epoch 14/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 9ms/step - accuracy: 0.9724 - auc: 0.9960 - loss: 0.1222 - val_accuracy: 0.9489 - val_auc: 0.9899 - val_loss: 0.1961
Epoch 15/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9761 - auc: 0.9973 - loss: 0.1089 - val_accuracy: 0.9544 - val_auc: 0.9881 - val_loss: 0.1804
Epoch 16/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9769 - auc: 0.9974 - loss: 0.1057 - val_accuracy: 0.9461 - val_auc: 0.9922 - val_loss: 0.1801
Epoch 17/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9799 - auc: 0.9970 - loss: 0.1063 - val_accuracy: 0.9503 - val_auc: 0.9909 - val_loss: 0.1773
Epoch 18/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 9ms/step - accuracy: 0.9765 - auc: 0.9982 - loss: 0.1010 - val_accuracy: 0.9599 - val_auc: 0.9907 - val_loss: 0.1759
Epoch 19/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9850 - auc: 0.9987 - loss: 0.0890 - val_accuracy: 0.9641 - val_auc: 0.9941 - val_loss: 0.1507
Epoch 20/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.9823 - auc: 0.9970 - loss: 0.1011 - val_accuracy: 0.9599 - val_auc: 0.9937 - val_loss: 0.1587
Epoch 21/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 9ms/step - accuracy: 0.9855 - auc: 0.9992 - loss: 0.0807 - val_accuracy: 0.9655 - val_auc: 0.9944 - val_loss: 0.1463
Epoch 22/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9782 - auc: 0.9980 - loss: 0.0978 - val_accuracy: 0.9599 - val_auc: 0.9914 - val_loss: 0.1650
Epoch 23/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9918 - auc: 0.9992 - loss: 0.0749 - val_accuracy: 0.9530 - val_auc: 0.9963 - val_loss: 0.1473
Epoch 24/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 9ms/step - accuracy: 0.9896 - auc: 0.9991 - loss: 0.0774 - val_accuracy: 0.9599 - val_auc: 0.9959 - val_loss: 0.1497
Epoch 25/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 7ms/step - accuracy: 0.9851 - auc: 0.9988 - loss: 0.0828 - val_accuracy: 0.9627 - val_auc: 0.9921 - val_loss: 0.1506
Epoch 26/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 9ms/step - accuracy: 0.9861 - auc: 0.9989 - loss: 0.0844 - val_accuracy: 0.9544 - val_auc: 0.9846 - val_loss: 0.2111
Epoch 27/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9689 - auc: 0.9974 - loss: 0.1095 - val_accuracy: 0.9682 - val_auc: 0.9963 - val_loss: 0.1233
Epoch 28/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9904 - auc: 0.9994 - loss: 0.0685 - val_accuracy: 0.9613 - val_auc: 0.9930 - val_loss: 0.1476
Epoch 29/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9885 - auc: 0.9993 - loss: 0.0767 - val_accuracy: 0.9572 - val_auc: 0.9852 - val_loss: 0.2071
Epoch 30/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9867 - auc: 0.9993 - loss: 0.0733 - val_accuracy: 0.9489 - val_auc: 0.9862 - val_loss: 0.2118
Epoch 31/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 9ms/step - accuracy: 0.9886 - auc: 0.9989 - loss: 0.0845 - val_accuracy: 0.9627 - val_auc: 0.9915 - val_loss: 0.1829
Epoch 32/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9878 - auc: 0.9989 - loss: 0.0802 - val_accuracy: 0.9586 - val_auc: 0.9929 - val_loss: 0.1528
Epoch 33/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9937 - auc: 0.9998 - loss: 0.0601 - val_accuracy: 0.9558 - val_auc: 0.9923 - val_loss: 0.1799
Epoch 34/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 9ms/step - accuracy: 0.9878 - auc: 0.9972 - loss: 0.0796 - val_accuracy: 0.9489 - val_auc: 0.9874 - val_loss: 0.2116
Epoch 35/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.9819 - auc: 0.9981 - loss: 0.0874 - val_accuracy: 0.9586 - val_auc: 0.9904 - val_loss: 0.1581
Epoch 36/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 7ms/step - accuracy: 0.9881 - auc: 0.9983 - loss: 0.0767 - val_accuracy: 0.9724 - val_auc: 0.9960 - val_loss: 0.1170
Epoch 37/100
91/91 ━━━━━━━━━━━━━━━━━━━━ 1s 8ms/step - accuracy: 0.9895 - auc: 0.9995 - loss: 0.0708 - val_accuracy: 0.9599 - val_auc: 0.9914 - val_loss: 0.1595

智能康復評估報告核心分析


??1. 康復效果評估??
  • ??平均康復指數??:??99.8%??,表明患者的整體運動功能已接近健康水平,康復效果顯著。
  • ??最佳窗口表現??:??20.2%??(局部動作表現優異,可能為特定動作的極限恢復)。
  • ??最弱窗口表現??:??0.0%??(存在個別動作或時間段的功能未恢復,需針對性分析)。

??2. 模型性能分析??
  • ??驗證集指標??:
    • ??準確率(Accuracy)??:穩定在 ??1.00??(完全正確分類)。
    • ??AUC??:??1.00??(完美區分健康與患者動作)。
    • ??損失值(Loss)??:趨近于 ??0??(模型收斂徹底)。
  • ??過擬合風險??:
    • 訓練集與驗證集指標完全一致(AUC=1.0),提示模型可能過度依賴訓練數據特征,需警惕對未知數據的泛化能力。

??3. 關鍵建議??
  1. ??臨床建議??:
    • ? ??維持現有訓練計劃??(當前康復效果已達最佳狀態)。
    • 🔍 ??重點監測最弱窗口??(0.0%動作):需排查是否為傳感器異常、患者疲勞或特定動作的神經控制障礙。
  2. ??模型優化方向??:
    • 增加 ??異常動作樣本?? 的采集與訓練,提升對低康復指數窗口的識別能力。
    • 引入 ??不確定性評估??(如預測置信度),避免對極端值過度敏感。

??4. 潛在問題預警??
  • ??數據偏差??:最弱窗口(0.0%)與最佳窗口(20.2%)差異顯著,可能反映數據采集或標注異常(如動作未正確執行)。
  • ??模型泛化瓶頸??:完美指標可能掩蓋對真實場景復雜性的適應不足,建議在獨立測試集上補充驗證。

總結

當前康復效果已達到頂尖水平(99.8%),但需關注局部異常動作的成因。模型性能優秀但存在過擬合風險,建議持續監控患者動作多樣性并優化數據采集流程。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/82239.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/82239.shtml
英文地址,請注明出處:http://en.pswp.cn/web/82239.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【LLM vs Agent】從語言模型到智能體,人工智能邁出的關鍵一步

目錄 一、什么是 LLM&#xff1f;語言的天才&#xff0c;思維的起點 ? 特點小結&#xff1a; 二、什么是 Agent&#xff1f;智能的執行者&#xff0c;自主的決策者 ? 特點小結&#xff1a; 三、LLM 與 Agent 的關系&#xff1a;是工具&#xff0c;更是大腦 四、案例實戰…

安裝DockerDocker-Compose

Docker 1、換掉關鍵文件 vim /etc/yum.repos.d/CentOS-Base.repo ▽ [base] nameCentOS-$releasever - Base - Mirrors Aliyun baseurlhttp://mirrors.aliyun.com/centos/$releasever/os/$basearch/ gpgcheck1 enabled1 gpgkeyhttp://mirrors.aliyun.com/centos/RPM-GPG-KEY-C…

Perl One-liner 數據處理——基礎語法篇【匠心】

Perl&#xff08;Practical Extraction and Report Language&#xff09;是一種功能強大且靈活的腳本語言&#xff0c;因其強大的文本處理能力和簡潔的語法而廣受開發者和系統管理員的喜愛。特別是在命令行環境下&#xff0c;Perl 的 one-liner&#xff08;單行腳本&#xff09…

Go語言defer關鍵字:延遲執行的精妙設計

深度解析Go語言defer關鍵字&#xff1a;延遲執行的精妙設計 引言 在Go語言中&#xff0c;defer語句是一種獨特而強大的控制流機制&#xff0c;它通過??延遲執行??的方式解決資源管理、錯誤處理和異常恢復等關鍵問題。理解defer的工作原理是掌握Go并發編程和錯誤處理的關鍵…

C#項目07-二維數組的隨機創建

實現需求 創建二維數組&#xff0c;數組的列和寬為隨機&#xff0c;數組內的數也是隨機 知識點 1、Random類 Public Random rd new Random(); int Num_Int rd.Next(1, 100);2、數組上下限。 //定義數組 int[] G_Array new int[1,2,3,4];//一維數組 int[,] G_Array_T …

.NET WinForm圖像識別二維碼/條形碼并讀取其中內容

需求:圖像識別出一張圖片中的二維碼或者條形碼&#xff0c;并讀取其中內容。 一、安裝庫(特別注意&#xff0c;網上很多都沒說清楚) 如果是基于.net framework&#xff0c;則安裝ZXing.Net(建議0.14.0版本左右&#xff0c;具體看實際&#xff0c;版本太高&#xff0c;部分接口…

Guava限頻器RateLimiter的使用示例

文章目錄 1. 背景說明2. API與方法3. 示例代碼3.1 基礎工具方法3.2 測試任務類3.3 測試和統計方法3.4 測試兩種模式的限頻器3.5 測試緩沖時間與等待耗時 4. 完整的測試代碼5. 簡單小結 1. 背景說明 高并發應用場景有3大利器: 緩存、限流、熔斷。 也有說4利器的: 緩存、限流、…

(面試)獲取View寬高的幾種方式

Android 中獲取 View 寬高的幾種方式&#xff0c;以及它們的適用場景和注意事項&#xff1a; 1. View.getWidth() 和 View.getHeight() 原理: 直接從 View 對象中獲取已經計算好的寬度和高度。 優點: 簡單直接。 缺點: 在 onCreate()、onStart() 等生命周期方法中&#xff0…

PostgreSQL pgrowlocks 擴展

PostgreSQL pgrowlocks 擴展 pgrowlocks 是 PostgreSQL 的一個系統擴展&#xff0c;用于顯示表中行級鎖定信息。這個擴展特別適合診斷鎖爭用問題和性能調優。 一、擴展安裝與啟用 1. 安裝擴展 -- 使用超級用戶安裝 CREATE EXTENSION pgrowlocks;2. 驗證安裝 -- 查看擴展是…

JavaSE知識總結 ~個人筆記以及不斷思考~持續更新

目錄 字符串常量池 如果是創建對象還會嗎&#xff1f; Integer也是在字串常量池中復用&#xff1f; 字符串拼接 為什么String是不可變的&#xff1f; String的不可變性是怎么做的&#xff1f; 外部代碼不能創建對象&#xff1f; 構造方法不是私有的嗎&#xff1f; 怎么…

使用HTTPS進行傳輸加密

文章目錄 說明示例&#xff08;公網上的公開web&#xff09;安裝SSL證書Certbot 的 Webroot 模式 和 Standalone 模式的區別**Webroot 模式****Standalone 模式** 技術對比表Node.js 場景下的最佳實踐推薦方案&#xff1a;**Webroot 模式**Standalone 模式應急使用&#xff1a;…

驅動開發(2)|魯班貓rk3568簡單GPIO波形操控

上篇文章寫了如何下載內核源碼、編譯源碼的詳細步驟&#xff0c;以及一個簡單的官方demo編譯&#xff0c;今天分享一下如何根據板子的引腳寫自己控制GPIO進行高低電平反轉。 想要控制GPIO之前要學會看自己的引腳分布圖&#xff0c;我用的是魯班貓RK3568&#xff0c;引腳分布圖如…

ArcGIS Pro 3.4 二次開發 - 布局

環境:ArcGIS Pro SDK 3.4 + .NET 8 文章目錄 布局1 布局工程項1.1 引用布局工程項及其關聯的布局1.2 在新視圖中打開布局工程項1.3 激活已打開的布局視圖1.4 引用活動布局視圖1.5 將 pagx 導入工程1.6 移除布局工程項1.7 創建并打開一個新的基本布局1.8 使用修改后的CIM創建新…

OpenCV 圖像像素的算術操作

一、知識點 1、operator (1)、MatExpr operator (const Mat & a, const Mat & b); a、a和b的行數、列數、通道數得相同。 b、a和b的每個像素的每個通道值分別相加。 (2)、MatExpr operator (const Mat & a, const Scalar & s); a、若a…

音視頻中的復用器

&#x1f3ac; 什么是復用器&#xff08;Muxer&#xff09;&#xff1f; 復用器&#xff08;muxer&#xff09;是負責把音頻、視頻、字幕等多個媒體流打包&#xff08;封裝&#xff09;成一個單一的文件格式的組件。 &#x1f4a1; 舉個形象的例子&#xff1a; 假設你有兩樣東…

數據庫安全性

一、計算機安全性概論 &#xff08;一&#xff09;核心概念 數據庫安全性&#xff1a;保護數據庫免受非法使用導致的數據泄露、更改或破壞&#xff0c;是衡量數據庫系統的關鍵指標之一&#xff0c;與計算機系統安全性相互關聯。計算機系統安全性&#xff1a;通過各類安全保護…

【Linux網絡編程】網絡層IP協議

目錄 IP協議的協議頭格式 網段劃分 特殊的IP地址 IP地址的數量限制 私有IP地址和公網IP地址 路由 IP協議的協議頭格式 4位版本號 &#xff1a;指定IP協議的版本&#xff0c;對于IPv4&#xff0c;版本號就是4。 4位首部長度&#xff1a;表名IP協議報頭的長度&#xff0c;單…

“候選對話鏈”(Candidate Dialogue Chain)概念

目錄 一、定義與形式 二、生成過程詳解 1. 語言模型生成&#xff08;LLM-Based Generation&#xff09; 2. 知識圖譜支持&#xff08;KG-Augmented Generation&#xff09; 3. 策略調控&#xff08;Policy-Driven Planning&#xff09; 三、候選對話鏈的屬性 四、候選對…

Unity中的JsonManager

1.具體代碼 先貼代碼 using LitJson; using System.IO; using UnityEngine;/// <summary> /// 序列化和反序列化Json時 使用的是哪種方案 有兩種 JsonUtility 不能直接序列化字典 ligJson可以序列化字典 /// </summary> public enum JsonType {JsonUtilit…

50天50個小項目 (Vue3 + Tailwindcss V4) ? | Split Landing Page(拆分展示頁)

&#x1f4c5; 我們繼續 50 個小項目挑戰&#xff01;—— SplitLandingPage 組件 倉庫地址&#xff1a;https://github.com/SunACong/50-vue-projects 項目預覽地址&#xff1a;https://50-vue-projects.vercel.app/ 在這篇文章中&#xff0c;我們將實現一個交互式的左右面板…