vr中风--数据处理模型搭建与训练
# -*- 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# 随机种子设置
SEED = 42
np.random.seed(SEED)# -------------------- 第一部分:数据增强器 --------------------
class SEMGDataGenerator:"""sEMG数据增强器(支持多通道)增强策略:- 分通道时间扭曲- 通道独立噪声添加- 幅度缩放- 通道偏移"""def __init__(self, noise_scale=0.1, stretch_range=(0.8, 1.2)):"""参数:noise_scale: 噪声强度系数 (默认0.1)stretch_range: 时间扭曲范围元组 (默认0.8~1.2倍)"""self.noise_scale = noise_scaleself.stretch_range = stretch_rangedef 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: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), dtype=np.float64)df = df.dropna() # 确保只读取前8列print("前8列统计描述:\n", df.describe())# 检查是否存在非数值或缺失值if df.isnull().any().any():print("发现缺失值,位置:\n", df.isnull().sum())df = df.dropna() # 删除含缺失值的行# 检查无穷大值if np.isinf(df.values).any():print("发现无穷大值")df = df.replace([np.inf, -np.inf], np.nan).dropna()#print("前8列数据类型:\n", df.iloc[:, :8].dtypes)#print("首行数据示例:\n", df.iloc[0, :8])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. 形状一致性校验shape_counts = defaultdict(int)for arr in augmented:shape_counts[arr.shape] += 1target_shape = max(shape_counts, key=shape_counts.get)filtered = [arr for arr in augmented if arr.shape == target_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})")
# -------------------- 第三部分:模型架构 --------------------
def build_model(input_shape):"""混合CNN+BiGRU模型"""inputs = layers.Input(shape=input_shape)# 特征提取分支x = layers.Conv1D(32, 15, activation='relu', padding='same')(inputs)x = layers.MaxPooling1D(2)(x)x = layers.Conv1D(64, 7, activation='relu', padding='same')(x)x = layers.MaxPooling1D(2)(x)x = layers.Bidirectional(layers.GRU(32, return_sequences=True))(x)# 差异注意力机制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()
# -------------------- 第四部分:模型训练 --------------------
# 定义回调
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
)
# -------------------- 第五部分:康复评估与可视化 --------------------
# 训练过程可视化
plt.figure(figsize=(12,4))
plt.subplot(131)
plt.plot(history.history['loss'], label='Train Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Loss Curve')
plt.legend()plt.subplot(132)
plt.plot(history.history['auc'], label='Train AUC')
plt.plot(history.history['val_auc'], label='Validation AUC')
plt.title('AUC Curve')
plt.legend()# 生成康复报告
def generate_report(model, patient_data):"""生成定量康复评估报告"""# 预测所有窗口predictions = model.predict(patient_data).flatten()# 计算康复指数(0-100%)recovery_index = 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)# 生成文字报告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 "接近健康水平,建议维持训练"}""")# 使用患者数据生成报告
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 [1/5] 数据加载完成 | 原始数据形状: (14970, 8) [2/5] 窗口分割完成 | 总窗口数: 298 | 窗口形状: (100, 8) [3/5] 数据增强完成 | 总样本数: 1788 (原始x6) [4/5] 形状过滤完成 | 有效样本率: 1788/1788 前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/5] 数据加载完成 | 原始数据形状: (14970, 8) [2/5] 窗口分割完成 | 总窗口数: 298 | 窗口形状: (100, 8) [3/5] 数据增强完成 | 总样本数: 1788 (原始x6) [4/5] 形状过滤完成 | 有效样本率: 1788/1788合并数据集形状: X(3576, 100, 8) y(3576,)最终数据集: 训练集: (2860, 100, 8) | 0类样本数: 1430 验证集: (716, 100, 8) | 1类样本数: 358标准化验证 (通道0): 均值: 0.00 (±0.99)
Epoch 1/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 3s 14ms/step - accuracy: 0.6373 - auc: 0.8087 - loss: 0.5779 - val_accuracy: 0.8575 - val_auc: 0.9439 - val_loss: 0.3450 Epoch 2/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.8715 - auc: 0.9368 - loss: 0.3158 - val_accuracy: 0.9232 - val_auc: 0.9812 - val_loss: 0.1800 Epoch 3/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.9382 - auc: 0.9836 - loss: 0.1598 - val_accuracy: 0.9469 - val_auc: 0.9909 - val_loss: 0.1401 Epoch 4/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.9529 - auc: 0.9877 - loss: 0.1329 - val_accuracy: 0.9413 - val_auc: 0.9927 - val_loss: 0.1423 Epoch 5/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.9609 - auc: 0.9934 - loss: 0.1030 - val_accuracy: 0.9553 - val_auc: 0.9935 - val_loss: 0.1235 Epoch 6/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.9760 - auc: 0.9955 - loss: 0.0785 - val_accuracy: 0.9567 - val_auc: 0.9938 - val_loss: 0.1308 Epoch 7/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 11ms/step - accuracy: 0.9798 - auc: 0.9962 - loss: 0.0720 - val_accuracy: 0.9609 - val_auc: 0.9937 - val_loss: 0.1027 Epoch 8/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 11ms/step - accuracy: 0.9830 - auc: 0.9974 - loss: 0.0595 - val_accuracy: 0.9316 - val_auc: 0.9883 - val_loss: 0.2068 Epoch 9/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.9699 - auc: 0.9958 - loss: 0.0740 - val_accuracy: 0.9358 - val_auc: 0.9901 - val_loss: 0.1772 Epoch 10/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.9717 - auc: 0.9961 - loss: 0.0688 - val_accuracy: 0.9679 - val_auc: 0.9923 - val_loss: 0.1051 Epoch 11/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.9827 - auc: 0.9984 - loss: 0.0492 - val_accuracy: 0.9525 - val_auc: 0.9889 - val_loss: 0.1531 Epoch 12/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.9910 - auc: 0.9992 - loss: 0.0342 - val_accuracy: 0.9651 - val_auc: 0.9919 - val_loss: 0.1138 Epoch 13/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.9875 - auc: 0.9992 - loss: 0.0325 - val_accuracy: 0.9749 - val_auc: 0.9950 - val_loss: 0.0939 Epoch 14/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.9935 - auc: 0.9997 - loss: 0.0166 - val_accuracy: 0.9721 - val_auc: 0.9890 - val_loss: 0.1144 Epoch 15/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.9907 - auc: 0.9994 - loss: 0.0223 - val_accuracy: 0.9637 - val_auc: 0.9866 - val_loss: 0.1359 Epoch 16/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 11ms/step - accuracy: 0.9902 - auc: 0.9995 - loss: 0.0294 - val_accuracy: 0.9553 - val_auc: 0.9874 - val_loss: 0.1561 Epoch 17/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 11ms/step - accuracy: 0.9885 - auc: 0.9992 - loss: 0.0358 - val_accuracy: 0.9777 - val_auc: 0.9914 - val_loss: 0.0963 Epoch 18/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.9980 - auc: 1.0000 - loss: 0.0068 - val_accuracy: 0.9609 - val_auc: 0.9877 - val_loss: 0.1386 Epoch 19/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.9897 - auc: 0.9997 - loss: 0.0230 - val_accuracy: 0.9651 - val_auc: 0.9880 - val_loss: 0.1363 Epoch 20/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 0.9994 - auc: 1.0000 - loss: 0.0029 - val_accuracy: 0.9693 - val_auc: 0.9858 - val_loss: 0.1438 Epoch 21/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 1.0000 - auc: 1.0000 - loss: 0.0018 - val_accuracy: 0.9721 - val_auc: 0.9860 - val_loss: 0.1456 Epoch 22/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 1.0000 - auc: 1.0000 - loss: 3.3242e-04 - val_accuracy: 0.9735 - val_auc: 0.9835 - val_loss: 0.1461 Epoch 23/100 90/90 ━━━━━━━━━━━━━━━━━━━━ 1s 10ms/step - accuracy: 1.0000 - auc: 1.0000 - loss: 2.1834e-04 - val_accuracy: 0.9721 - val_auc: 0.9836 - val_loss: 0.1492[ ]:
结果分析:
一、性能亮点
-
极高的训练指标
- 训练准确率(Accuracy):从第1轮的63.73%快速提升到第22轮的100%,说明模型完全拟合了训练数据。
- 训练AUC:从0.8087上升到1.0,表明模型对训练数据的分类能力达到完美。
-
验证集表现优秀
- 验证准确率:最终稳定在 97.35%(第23轮),说明模型泛化能力较强。
- 验证AUC:最高达到 0.995(第13轮),接近完美分类(AUC=1.0)。
-
快速收敛
- 模型在前5轮内就达到了90%以上的验证准确率,表明架构设计合理且数据质量较高。
二、潜在问题
1. 严重过拟合
- 训练 vs 验证差距:
- 训练准确率最终为100%,而验证准确率最高97.35%(差距2.65%)。
- 训练AUC为1.0,验证AUC最高0.995(差距0.5%)。
- 验证损失波动:
- 验证损失(
val_loss
)在第8轮后出现明显波动(如第8轮0.2068 → 第17轮0.0963 → 第23轮0.1492),表明模型对验证集的泛化能力不稳定。
- 验证损失(
2. 过拟合的直接证据
- 训练指标饱和:
- 从第15轮开始,训练准确率和AUC均达到100%,但验证指标未同步提升,甚至出现下降(如第22轮验证AUC从0.995降到0.9835)。
- 极端损失值:
- 训练损失(
loss
)在第22轮降至0.00033,而验证损失(val_loss
)维持在0.1461,差距显著。
- 训练损失(
3. 可能的过拟合原因
- 模型复杂度过高:
LSTM层可能过于复杂(如神经元过多或层数过深),导致模型记住了训练数据噪声。 - 数据增强不足:
尽管使用了时间扭曲等增强策略,可能仍不足以模拟真实场景的多样性。 - 类别不平衡:
验证集正样本数(358)远少于负样本(1430),可能导致模型偏向多数类。
三、改进建议
1. 抑制过拟合
- 增加正则化:
python
复制
model.add(layers.Dropout(0.5)) # 在LSTM层后添加Dropout model.add(layers.LSTM(64, kernel_regularizer='l2')) # L2正则化
- 简化模型:
减少LSTM层神经元数量(如从64→32)或层数(如移除一层LSTM)。 - 早停策略优化:
设置更严格的早停耐心值(如patience=5
),防止在验证损失波动时继续训练。
2. 数据增强优化
- 增强强度调整:
增大时间扭曲范围(如stretch_range=(0.5, 1.5)
)或噪声强度(noise_scale=0.2
)。 - 引入更多增强:
添加通道随机丢弃(Channel Dropout)或时间反转(Time Reverse)。
3. 类别不平衡处理
- 损失函数加权:
python
复制
model.compile(loss=BinaryFocalLoss(gamma=2), ...) # 使用Focal Loss # 或 class_weight = {0: 1.0, 1: 5.0} # 增加少数类权重 model.fit(..., class_weight=class_weight)
4. 验证集扩展
- 增大验证集比例:
从test_size=0.2
调整为test_size=0.3
,提高验证结果可信度。
四、性能总结
指标 | 训练集 | 验证集 | 结论 |
---|---|---|---|
最终准确率 | 100% | 97.35% | 优秀但需警惕过拟合 |
最终AUC | 1.0 | 0.9836 | 接近完美分类,泛化能力较强 |
训练/验证损失 | 0.0002 | 0.1492 | 过拟合明显,需优化正则化策略 |
五、下一步行动
- 可视化学习曲线
python
复制
plt.plot(history.history['accuracy'], label='Train Accuracy') plt.plot(history.history['val_accuracy'], label='Val Accuracy') plt.legend(); plt.show()
- 混淆矩阵分析
python
复制
from sklearn.metrics import confusion_matrix y_pred = model.predict(X_val) > 0.5 print(confusion_matrix(y_val, y_pred))
- 错误样本分析
检查验证集中被错误分类的样本,识别模型盲区(如特定运动模式或传感器异常)。
通过以上改进,模型可进一步提升鲁棒性和泛化能力,适应真实场景需求。
相关文章:

vr中风--数据处理模型搭建与训练
# -*- coding: utf-8 -*- """ MUSED-I康复评估系统(增强版) 包含:多通道sEMG数据增强、混合模型架构、标准化处理 """ import numpy as np import pandas as pd from sklearn.model_selection import train_te…...
Socket网络编程之UDP套件字
基于的UDP套件字编程流程 UDP传输层的协议,面向无连接,数据报的传输层协议。 “ 无连接 ”:不可靠 在网络环境较好的情况下,UDP效率较高在网络环境较差的情况下,UDP可能存在丢包的情况同时一些“ 实时应用 ” 采用UD…...

前端学习(7)—— HTML + CSS实现博客系统页面
目录 一,效果展示 二,实现博客列表页 2.1 实现导航栏 2.2 实现个人信息 2.3 实现博客列表 三,实现博客正文页 3.2 复用 3.4 实现博客正文 四,实现博客登录页 4.1 版心 4.2 登录框 五,实现博客编辑页 5.1 …...
Bert和GPT区别
BERT(Bidirectional Encoder Representations from Transformers)和 GPT(Generative Pre-trained Transformer)都基于 Transformer 架构,但在设计目标、预训练任务和应用场景上有很大区别: 1. 架构方向性 B…...
聊一聊接口测试中缓存处理策略
目录 一、强制绕过缓存 添加时间戳参数 修改请求头 二、主动清除缓存 清除本地缓存 清除服务端缓存(需权限) 清除CDN缓存 三、测试缓存逻辑 首次请求获取数据 记录响应头中的缓存标识 验证缓存生效 测试缓存过期 四…...

RuoYi前后端分离框架实现前后端数据传输加密(二)之前端篇
一、背景 本文是RuoYi前后端分离框架实现前后端数据传输加密(一)之后端篇文章配套的,主要介绍前端对自定义字段传输加密的实现,两篇文章结合可以完整的完成RuoYi前后端分离框架对API通信过程中实现自定义字段加密传输。前端的加解密实现,不涉及到界面的修改,仅仅是方法的…...
如何使用.Net Reactor 批量加密 DLL
若在日常工作中加密操作的使用频率较高,每次启动程序并执行选择 DLL 文件等操作均会显得较为繁琐。在此,分享一种可提升操作效率的方法:通过命令行方式调用脚本,即可实现 DLL 或 Exe 文件的批量加密处理。具体操作如下:…...
基于视觉的车道线检测完整代码:让驾驶更安全的开源解决方案
基于视觉的车道线检测完整代码:让驾驶更安全的开源解决方案 【下载地址】基于视觉的车道线检测完整代码 这是一个基于视觉的车道线检测开源项目,提供完整的代码示例,采用滑动窗口算法实现。项目通过逐行扫描图像,精准识别曲线车道…...
Intellij IDEA 查找接口实现类的快捷键
快捷键是 IntelliJ IDEA(包括 PyCharm、WebStorm 等 JetBrains 家族 IDE) 中非常常用的代码导航功能。下面是对你提到的两个快捷键的详细解释和用途说明: 🔍 1. 查找接口的实现类(或方法的实现) …...

鸿蒙仓颉开发语言实战教程:自定义tabbar
大家周末好呀,今天继续分享仓颉语言开发商城应用的实战教程,今天要做的是tabbar。 大家都知道ArkTs有Tabs和TabContent容器,能够实现上图的样式,满足基本的使用需求。而仓颉就不同了,它虽然也有这两个组件,…...
03.MySQL表的操作详解
MySQL表的操作详解 MySQL 表的操作概述创建表 2.1 创建表的基本语法查看表结构修改表 4.1 新增列 4.2 修改列属性 4.3 修改列名 4.4 修改表名 4.5 删除列删除表 1. MySQL表的操作概述 MySQL表的操作是数据库开发和管理中的核心内容,主要涉及**数据定义语言&#…...

28 C 语言作用域详解:作用域特性(全局、局部、块级)、应用场景、注意事项
1 作用域简介 作用域定义了代码中标识符(如变量、常量、数组、函数等)的可见性与可访问范围,即标识符在程序的哪些位置能够被引用或访问。在 C 语言中,作用域主要分为三类: 全局作用域局部作用域块级作用域 需注意&am…...

MySQL 事务解析
1. 事务简介 事务(Transaction) 是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。 经典案例࿱…...

题海拾贝:压缩字符串
Hello大家好!很高兴我们又见面啦!给生活添点passion,开始今天的编程之路! 我的博客:<但凡. 我的专栏:《编程之路》、《数据结构与算法之美》、《题海拾贝》、《C修炼之路》 欢迎点赞,关注&am…...
【Hive 运维实战】一键管理 Hive 服务:Metastore 与 HiveServer2 控制脚本开发与实践
一、引言 在大数据开发中,Hive 作为重要的数据仓库工具,其核心服务metastore(元数据服务)和hiveserver2(查询服务)的启停管理是日常运维的基础操作。手动执行命令启停服务不仅效率低下,还容易因…...

振动力学的三类基本问题
振动问题的分类依赖于分类的出发点,本文从系统论的角度来分析振动问题的分类。如图1,一个振动系统,包括三个方面:输入、系统特性(或称为系统模型)、输出。其中,输入指外界载荷,包括力…...
04.MySQL数据类型详解
MySQL数据类型详解 文章目录 MySQL数据类型数据类型分类数值类型 tinyint类型bit类型float类型decimal类型 字符串类型 char类型varchar类型char和varchar比较 时间日期类型enum和set类型数据类型选择的进阶技巧常见误区与解决方案性能优化与最佳实践 MySQL数据类型 数据类型…...

移动端 UI自动化测试学习之Appium框架(包含adb调试工具介绍)
文章目录 前言adb调试工具adb组成常用命令获取程序的包名和界面名文件传输发送文件到手机从手机中拉取文件 获取app启动时间获取手机日志其他命令 Appium 简介工作原理图 环境搭建安装客户端库(appium lib)安装Appium Server安装JDK(自行下载…...

CS144 - Lecture 2
CS144 - Lecture 1 TCP 这里就简单讲了一下它的基本性质,没啥好说的 UDP 提供不可靠的传输服务,我们的 DNS 服务和 DHCP 都是用的 UDP 协议。 对于 DNS 我们只是单纯地向 DNS 服务器发送域名,然后返回一个 IP,如果还需要建立…...

B站视频下载器 v1.0.4|免登录下载1080P视频
核心亮点 ✅ 无需登录下载1080P高清视频✅ 支持Windows/macOS双平台✅ 纯净无广告完全免费✅ 可单独下载视频/音频/弹幕/字幕/封面 三步极简操作 粘贴B站视频链接选择保存位置点击「开始下载」 特色功能 独立下载选项(视频/音频/弹幕/字幕/封面)登录…...

AIGC学习笔记(8)——AI大模型开发工程师
文章目录 AI大模型开发工程师007 LangChain之Model IO模块1 Model IO核心概念2 Model IO代码实战什么是LCEL?ModelModel的分类LLMsChatModel PromptPrompt templatesExample selectorsOutput parsers AI大模型开发工程师 007 LangChain之Model IO模块 1 Model IO核…...

[蓝桥杯]剪格子
剪格子 题目描述 如下图所示,3 x 3 的格子中填写了一些整数。 我们沿着图中的红色线剪开,得到两个部分,每个部分的数字和都是 60。 本题的要求就是请你编程判定:对给定的 mnmn 的格子中的整数,是否可以分割为两个部…...

明远智睿SSD2351开发板:语音机器人领域的变革力量
在人工智能快速发展的今天,语音机器人逐渐成为人们生活和工作中的得力助手。明远智睿SSD2351开发板凭借强大性能与丰富功能,为语音机器人的发展注入新动力,成为该领域的变革力量。 SSD2351开发板的四核1.4GHz处理器具备强劲的运算性能&#x…...
Mybtais框架各配置文件主要内容详解(一)
前言: Mybatis由ibatis框架演变而来——2010 年,iBATIS 框架正式更名为 MyBatis,并捐赠给 Apache 软件基金会,开启了开源社区驱动的发展之路。 Mybatis处于MVC三层架构的Model层,是一款优秀的半自动orm框架ÿ…...

Co-IP—验证蛋白互作的不二之选
蛋白互作在细胞生命活动中起着至关重要的作用,并在不同的时空层面上参与多种细胞活动,因此研究蛋白互作对于理解分子调控网络至关重要。而在植物中筛选到潜在的互作蛋白后,大多数情况下,获得表达两种蛋白的稳定转化植株费时又费力…...

数据可视化(第4、5、6次课)
Matplotlib 折线图 import numpy as np import matplotlib.pyplot as plt import matplotlib # 配置中文格式——保证图中出现中文的时候不会乱码 matplotlib.rcParams[font.sans-serif][SimHei] matplotlib.rcParams[axes.unicode_minus]False # 绘图 x np.linspace(0,2*np…...

DAY 18 推断聚类后簇的类型
目录 DAY 18 推断聚类后簇的类型1.推断簇含义的2个思路:先选特征和后选特征2.通过可视化图形借助ai定义簇的含义3.科研逻辑闭环:通过精度判断特征工程价值作业:参考示例代码对心脏病数据集采取类似操作,并且评估特征工程后模型效果有无提升。…...

结合源码分析Redis的内存回收和内存淘汰机制,LRU和LFU是如何进行计算的?
Redis 内存回收 1. 过期 key 处理 Redis 之所以性能强,最主要的原因就是基于内存存储。然而单节点的 Redis 其内存大小不宜过大,会影响持久化或主从同步性能。我们可以通过修改配置文件来设置Redis的最大内存: 当内存使用达到上限时&#…...

ESG体系
文字来自腾讯元宝 ESG是什么? ESG体系是一套综合评估企业在环境(Environmental)、社会(Social)和治理(Governance) 三个维度表现的非财务绩效标准,旨在衡量企业可持续发展能力和长期…...
基于 KubeKey 3.1.9,快速部署 K8s 1.33.0 高可用集群
作者:丁鑫磊,云原生运维工程师,专注于 KubeSphere 与 K8s 的深度应用,致力于自动化方向的探索与实践。热衷于挖掘 KubeSphere 的运维潜力,借助其简化 K8s 操作,提升运维效率,为企业云原生转型推…...