网站样式有哪些风格网站搜索优化方案
网站样式有哪些风格,网站搜索优化方案,洛阳网站制作,一键建网站首先#xff0c;利用短时傅里叶变换将原始振动信号转换为时频图像#xff0c;并通过动态阈值增强故障特征#xff1b;然后#xff0c;采用预训练的VGG16网络进行迁移学习#xff0c;在保留通用视觉特征的基础上微调分类层#xff0c;实现对10种健康状态的高精度识别。为了…首先利用短时傅里叶变换将原始振动信号转换为时频图像并通过动态阈值增强故障特征然后采用预训练的VGG16网络进行迁移学习在保留通用视觉特征的基础上微调分类层实现对10种健康状态的高精度识别。为了增强模型的可信度算法引入Grad-CAM热力图可视化模型的决策依据并设计Faithfulness指标量化解释的忠实性。此外结合故障机理知识和大语言模型自动生成符合专家习惯的诊断报告并在检测到严重故障时通过邮件实时告警。该方法在CWRU轴承数据集上表现出优异的分类性能同时为工业场景下的智能运维提供了透明、可解释的决策支持。算法步骤数据加载与类别映射遍历指定目录下的所有.mat文件根据文件名中的关键词如Normal、B007、IR014、OR021等将样本分为10类正常、三种尺寸的滚动体故障、三种尺寸的内圈故障、三种尺寸的外圈故障。提取每个文件中的驱动端振动信号DE_time并存储。信号预处理下采样将原始采样率12000 Hz降为6000 Hz减少数据量并保留故障特征频段。滑动窗口分割对每段下采样后的长信号以1024点长度、512点步长切分为多个短样本增加训练样本数量。时频变换STFT对每个短样本计算短时傅里叶变换得到时频谱图窗长128点、重叠64点兼顾时间和频率分辨率。图像增强对幅值谱取dB值对数变换然后通过动态阈值裁剪底部35%噪声增强故障冲击成分的对比度。归一化与尺寸调整将谱图线性归一化至[0,1]再缩放到224×224像素最后堆叠为三通道灰度图满足ImageNet预训练模型的输入要求。数据集划分将生成的时频图像及对应标签按照类别分层抽样划分为训练集70%、验证集15%和测试集15%确保各类别分布均衡。迁移学习模型构建加载在ImageNet上预训练的VGG16模型去除顶部分类层保留卷积基。冻结所有卷积层参数避免微调初期破坏通用特征。在卷积基后添加全局平均池化层、256维全连接层ReLU激活、Dropout0.1以及10维Softmax输出层。使用Adam优化器学习率0.001、分类交叉熵损失函数编译模型。模型训练与验证使用训练集训练模型25个轮次每批32个样本并在验证集上监控准确率和损失保存最佳模型。训练过程中保持卷积基冻结仅更新新增的全连接层参数。模型评估在测试集上计算整体分类准确率。输出每个类别的精确率、召回率、F1-score生成分类报告。绘制混淆矩阵、多类别ROC曲线及AUC值直观评估各类别的区分能力。可解释性分析Grad-CAM可视化针对测试样本计算最后一个卷积层block5_conv3的梯度生成热力图高亮模型决策时关注的时频区域。Faithfulness指标计算随机选取50个高置信度样本删除热力图中最关键的20%像素置零重新预测并计算置信度下降百分比量化解释的忠实度。专家级报告生成结合Grad-CAM提取的显著频率、模型预测的故障类别及预定义的物理知识如不同故障对应的特征频率构建结构化提示调用本地大语言模型LLaMA 3.2生成包含诊断结论、严重等级、维护建议的文本报告。自动告警通知当诊断出严重故障如尺寸021或模型置信度极高时通过SendGrid API将生成的报告以邮件形式发送给指定维护人员实现实时预警。# 1. 导入所需库 import os import numpy as np import scipy.io from scipy import signal import matplotlib.pyplot as plt import cv2 from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report, confusion_matrix, roc_curve, auc import seaborn as sns import tensorflow as tf from tensorflow.keras.applications import VGG16 from tensorflow.keras.models import Model from tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout from tensorflow.keras.optimizers import Adam from tensorflow.keras.utils import to_categorical import copy from tqdm import tqdm import ollama # 用于调用本地大语言模型生成报告 from datetime import datetime import sendgrid # 用于发送邮件通知 from sendgrid.helpers.mail import Mail, Email, To, Content # 设置随机种子以保证结果可重复 np.random.seed(42) tf.random.set_seed(42) # 2. 数据加载与标签映射 data_dir ../data # 数据存放目录请根据实际情况修改 file_list [f for f in os.listdir(data_dir) if f.endswith(.mat)] raw_signals [] # 原始振动信号列表 labels [] # 对应的标签整数 0-9 print(f找到 {len(file_list)} 个 .mat 文件) # 定义标签映射字典根据文件名中的关键词确定类别 def get_label_from_filename(filename): if Normal in filename or Time in filename: return 0 elif B007 in filename: return 1 elif B014 in filename: return 2 elif B021 in filename: return 3 elif IR007 in filename: return 4 elif IR014 in filename: return 5 elif IR021 in filename: return 6 elif OR007 in filename: return 7 elif OR014 in filename: return 8 elif OR021 in filename: return 9 else: return None # 未知类别 for file_name in file_list: label get_label_from_filename(file_name) if label is None: print(f跳过未定义类别的文件: {file_name}) continue # 加载 .mat 文件 file_path os.path.join(data_dir, file_name) mat_data scipy.io.loadmat(file_path) # 查找驱动端振动信号变量通常为 DE_time signal_key [key for key in mat_data.keys() if DE_time in key] if len(signal_key) 0: print(f跳过 {file_name} (未找到 DE_time 变量)) continue sig mat_data[signal_key[0]].flatten() # 展平为一维数组 raw_signals.append(sig) labels.append(label) print(f已加载 {file_name} - 类别 {label}) print(f\n数据加载完成。共 {len(labels)} 个样本) # 3. 信号预处理下采样 STFT 生成时频图像 ORIGINAL_FS 12000 # 原始采样频率 (Hz)CWRU 驱动端数据通常为 12k target_fs 6000 # 目标采样频率 (Hz)下采样至 6k 以减少计算量 # 3.1 下采样 downsampled_signals [] for sig in raw_signals: num_samples int(len(sig) * (target_fs / ORIGINAL_FS)) resampled signal.resample(sig, num_samples) downsampled_signals.append(resampled) print(f信号已下采样至 {target_fs/ORIGINAL_FS*100:.1f}%) # 3.2 滑动窗口参数 segment_length 1024 # 每个片段的长度点数 step_size 512 # 滑动步长点数 target_image_size (224, 224) # VGG16 要求的输入尺寸 nperseg 128 # STFT 每段点数 noverlap 64 # STFT 重叠点数50% 重叠 stft_images [] # 存储生成的 RGB 图像 stft_labels [] # 对应的标签 print(开始生成 STFT 时频图像...) for idx, sig in enumerate(downsampled_signals): current_label labels[idx] # 对每段长信号进行滑动窗口切片 for i in range(0, len(sig) - segment_length, step_size): segment sig[i : i segment_length] # 计算 STFT f, t, Zxx signal.stft(segment, fstarget_fs, npersegnperseg, noverlapnoverlap) magnitude np.abs(Zxx) # 幅值谱 magnitude_db 20 * np.log10(magnitude 1e-6) # 转换为 dB 单位增强对比度 # 动态阈值抑制底部 35% 的噪声区域 range_db magnitude_db.max() - magnitude_db.min() threshold magnitude_db.min() 0.35 * range_db magnitude_db[magnitude_db threshold] threshold # 归一化到 [0,1] mag_norm (magnitude_db - magnitude_db.min()) / (magnitude_db.max() - magnitude_db.min()) # 缩放到 VGG16 输入尺寸 (224,224) resized cv2.resize(mag_norm, target_image_size) # 堆叠为三通道灰度图满足 ImageNet 预训练模型输入要求 img_rgb np.stack((resized,) * 3, axis-1) stft_images.append(img_rgb) stft_labels.append(current_label) X np.array(stft_images) # 特征数组形状 (N, 224, 224, 3) y np.array(stft_labels) # 标签数组 print(f特征提取完成。输入形状: {X.shape}) # 4. 数据集划分 # 将标签转换为 one-hot 编码 y_encoded to_categorical(y, num_classes10) # 先划分 70% 训练30% 临时再平分验证和测试 X_train, X_temp, y_train, y_temp train_test_split( X, y_encoded, test_size0.3, random_state42, stratifyy ) # 从临时集中划分 15% 验证15% 测试 stratify_labels np.argmax(y_temp, axis1) # 用于分层抽样 X_val, X_test, y_val, y_test train_test_split( X_temp, y_temp, test_size0.5, random_state42, stratifystratify_labels ) print(f训练集形状: {X_train.shape}) print(f验证集形状: {X_val.shape}) print(f测试集形状: {X_test.shape}) # 5. 构建迁移学习模型 (VGG16) # 加载预训练的 VGG16不含顶层 base_model VGG16(weightsimagenet, include_topFalse, input_shape(224, 224, 3)) # 冻结所有卷积层初期不更新这些权重 for layer in base_model.layers: layer.trainable False # 添加自定义分类头 x base_model.output x GlobalAveragePooling2D()(x) # 全局平均池化减少参数量 x Dense(256, activationrelu)(x) x Dropout(0.1)(x) predictions Dense(10, activationsoftmax)(x) # 10 个输出类别 model Model(inputsbase_model.input, outputspredictions) # 编译模型 model.compile(optimizerAdam(learning_rate0.001), losscategorical_crossentropy, metrics[accuracy]) model.summary() # 6. 模型训练 history model.fit( X_train, y_train, epochs25, batch_size32, validation_data(X_val, y_val), verbose1 ) # 7. 模型评估 # 绘制训练曲线 plt.figure(figsize(12, 4)) plt.subplot(1, 2, 1) plt.plot(history.history[accuracy], label训练集) plt.plot(history.history[val_accuracy], label验证集) plt.title(准确率) plt.legend() plt.subplot(1, 2, 2) plt.plot(history.history[loss], label训练集) plt.plot(history.history[val_loss], label验证集) plt.title(损失) plt.legend() plt.show() # 在测试集上评估 y_pred_probs model.predict(X_test) y_pred_classes np.argmax(y_pred_probs, axis1) y_true_classes np.argmax(y_test, axis1) # 类别名称 target_names [ Normal, Ball_007, Ball_014, Ball_021, IR_007, IR_014, IR_021, OR_007, OR_014, OR_021 ] print(分类报告:) print(classification_report(y_true_classes, y_pred_classes, target_namestarget_names)) # 混淆矩阵 cm confusion_matrix(y_true_classes, y_pred_classes) plt.figure(figsize(12, 10)) sns.heatmap(cm, annotTrue, fmtd, cmapBlues, xticklabelstarget_names, yticklabelstarget_names) plt.title(混淆矩阵) plt.ylabel(真实类别) plt.xlabel(预测类别) plt.xticks(rotation45, haright) plt.tight_layout() plt.show() # ROC 曲线 fpr dict() tpr dict() roc_auc dict() n_classes 10 for i in range(n_classes): fpr[i], tpr[i], _ roc_curve(y_test[:, i], y_pred_probs[:, i]) roc_auc[i] auc(fpr[i], tpr[i]) plt.figure(figsize(12, 8)) colors plt.cm.tab10(np.linspace(0, 1, 10)) for i, color in zip(range(n_classes), colors): plt.plot(fpr[i], tpr[i], colorcolor, lw2, labelf{target_names[i]} (AUC {roc_auc[i]:0.2f})) plt.plot([0, 1], [0, 1], k--, lw2) plt.xlim([0.0, 1.0]) plt.ylim([0.0, 1.05]) plt.xlabel(假阳性率) plt.ylabel(真阳性率) plt.title(多类别 ROC 曲线) plt.legend(loclower right) plt.show() # 8. 可解释性分析 (Grad-CAM) def make_gradcam_heatmap(img_array, model, last_conv_layer_name, pred_indexNone): 计算 Grad-CAM 热力图 img_array: 输入图像 (已扩展 batch 维度形状 (1,224,224,3)) model: Keras 模型 last_conv_layer_name: 最后一层卷积层的名称 pred_index: 要解释的类别索引若为 None 则使用预测概率最高的类别 # 构建一个从输入到目标卷积层输出及模型输出的新模型 grad_model tf.keras.models.Model( [model.inputs], [model.get_layer(last_conv_layer_name).output, model.output] ) with tf.GradientTape() as tape: last_conv_output, preds grad_model(img_array) if pred_index is None: pred_index tf.argmax(preds[0]) class_channel preds[:, pred_index] # 计算梯度 grads tape.gradient(class_channel, last_conv_output) pooled_grads tf.reduce_mean(grads, axis(0, 1, 2)) # 全局平均池化 # 加权求和 last_conv_output last_conv_output[0] heatmap last_conv_output pooled_grads[..., tf.newaxis] heatmap tf.squeeze(heatmap) # 归一化到 [0,1] heatmap tf.maximum(heatmap, 0) / tf.math.reduce_max(heatmap) return heatmap.numpy() def display_gradcam(img, heatmap, titleGrad-CAM, alpha0.4): 显示原始图像、热力图及叠加后的图像 # 将图像从 [0,1] 转换回 [0,255] 整数 img_uint8 np.uint8(255 * img) # 热力图转伪彩色 heatmap_uint8 np.uint8(255 * heatmap) jet plt.get_cmap(jet) jet_colors jet(np.arange(256))[:, :3] jet_heatmap jet_colors[heatmap_uint8] jet_heatmap cv2.resize(jet_heatmap, (img.shape[1], img.shape[0])) jet_heatmap np.uint8(255 * jet_heatmap) # 叠加 superimposed jet_heatmap * alpha img_uint8 superimposed np.clip(superimposed, 0, 255).astype(uint8) # 绘图 plt.figure(figsize(12, 4)) plt.subplot(1, 3, 1) plt.imshow(img_uint8) plt.title(原始时频图) plt.axis(off) plt.subplot(1, 3, 2) plt.imshow(heatmap, cmapjet) plt.title(热力图) plt.axis(off) plt.subplot(1, 3, 3) plt.imshow(superimposed) plt.title(f叠加: {title}) plt.axis(off) plt.show() # 选择一个测试样本进行 Grad-CAM 可视化 last_conv_layer block5_conv3 # VGG16 最后一层卷积的名称 sample_idx 42 # 可根据需要修改 img_sample X_test[sample_idx] true_label_idx np.argmax(y_test[sample_idx]) true_label_name target_names[true_label_idx] img_batch np.expand_dims(img_sample, axis0) heatmap make_gradcam_heatmap(img_batch, model, last_conv_layer) display_gradcam(img_sample, heatmap, titletrue_label_name) # 9. Faithfulness 指标计算 def calculate_faithfulness(model, X_data, y_data, layer_name, num_samples50, mask_top_percent20): 计算 Faithfulness删除最显著像素后置信度下降百分比 print(f\n--- 开始 Faithfulness 评估随机选取 {num_samples} 个样本 ---) drops [] conf_after [] max_samples len(X_data) actual_samples min(num_samples, max_samples) indices np.random.choice(max_samples, sizeactual_samples, replaceFalse) for idx in tqdm(indices): img X_data[idx] img_batch np.expand_dims(img, axis0) true_label np.argmax(y_data[idx]) # 原始预测置信度 pred_orig model.predict(img_batch, verbose0)[0] conf_orig pred_orig[true_label] if conf_orig 0.5: # 只考虑模型原本就有把握的样本 continue # 生成热力图针对真实类别 heat make_gradcam_heatmap(img_batch, model, layer_name, pred_indextrue_label) heat_resized cv2.resize(heat, (img.shape[1], img.shape[0])) # 生成掩膜取热力值最高的 mask_top_percent% 像素 threshold np.percentile(heat_resized, 100 - mask_top_percent) mask heat_resized threshold # 遮挡这些像素置零 masked_img copy.deepcopy(img) for c in range(3): masked_img[:, :, c][mask] 0.0 # 重新预测 masked_batch np.expand_dims(masked_img, axis0) pred_new model.predict(masked_batch, verbose0)[0] conf_new pred_new[true_label] # 计算相对下降百分比 drop max(0, (conf_orig - conf_new) / conf_orig) * 100 drops.append(drop) conf_after.append(conf_new * 100) if len(drops) 0: print(没有满足置信度要求的样本) return avg_drop np.mean(drops) avg_conf_after np.mean(conf_after) print(\n *40) print(Faithfulness 评估结果) print(*40) print(f平均置信度下降: {avg_drop:.2f}%) print(f遮挡后平均置信度: {avg_conf_after:.2f}%) print(*40) # 执行 Faithfulness 评估 calculate_faithfulness(model, X_test, y_test, layer_namelast_conv_layer, num_samples50) # 10. 专家级报告生成 (LLaMA 邮件通知) def extract_heatmap_evidence(heatmap, target_fs6000): 从热力图中提取显著频率信息 # 沿时间轴求和得到频率能量分布 freq_profile np.sum(heatmap, axis1) peak_freq_idx np.argmax(freq_profile) nyquist target_fs / 2 dominant_freq (peak_freq_idx / heatmap.shape[0]) * nyquist avg_intensity np.mean(heatmap) * 100 peak_intensity np.max(heatmap) * 100 return { dominant_freq: round(dominant_freq, 1), peak_confidence: round(peak_intensity, 1), avg_activation: round(avg_intensity, 1) } def generate_llm_report(predicted_label, evidence): 利用本地 LLaMA 模型生成诊断报告 # 根据预测标签确定故障类型和物理描述 if Normal in predicted_label: fault_type 健康状态 severity 无 physics 旋转平稳未检测到冲击。 action 继续正常运行30天后重新评估。 elif Ball in predicted_label: fault_type 滚动体故障 physics 滚动体表面出现剥落或点蚀产生以滚动体自转频率为特征的冲击。 if 007 in predicted_label: severity 早期0.007英寸 action 密切监视可在下次维护窗口安排检查。 elif 014 in predicted_label: severity 发展期0.014英寸 action 计划维护建议两周内更换轴承。 elif 021 in predicted_label: severity 严重0.021英寸 action 立即停机更换存在失效风险。 elif IR in predicted_label: fault_type 内圈故障 physics 内圈滚道出现损伤球体通过缺陷时产生以BPFI为特征的冲击。 if 007 in predicted_label: severity 早期0.007英寸 action 密切监视可在下次维护窗口安排检查。 elif 014 in predicted_label: severity 发展期0.014英寸 action 计划维护建议两周内更换轴承。 elif 021 in predicted_label: severity 严重0.021英寸 action 立即停机更换存在失效风险。 elif OR in predicted_label: fault_type 外圈故障 physics 外圈滚道出现损伤产生以BPFO为特征的冲击。 if 007 in predicted_label: severity 早期0.007英寸 action 密切监视可在下次维护窗口安排检查。 elif 014 in predicted_label: severity 发展期0.014英寸 action 计划维护建议两周内更换轴承。 elif 021 in predicted_label: severity 严重0.021英寸 action 立即停机更换存在失效风险。 else: fault_type 未知异常 physics 无法确定具体故障类型。 severity 未知 action 立即进行详细检测。 current_date datetime.now().strftime(%Y-%m-%d) prompt f 你是一名资深振动分析师。请根据以下信息撰写一份诊断报告。 元数据 - 日期{current_date} - 分析系统DeepBear-Health AI 输入数据 - 故障类型{fault_type} - 严重程度{severity} - 显著频率~{evidence[dominant_freq]} Hz - 模型置信度{evidence[peak_confidence]}% 物理背景 {physics} 请撰写一份包含“诊断结论”和“维护建议”两部分的报告。 维护建议请严格遵循{action} response ollama.chat(modelllama3.2, messages[{role: user, content: prompt}]) return response[message][content] def send_plain_text_email(subject, body, api_key, from_email, to_email): 通过 SendGrid 发送纯文本邮件 sg sendgrid.SendGridAPIClient(api_keyapi_key) from_email Email(from_email) to_email To(to_email) content Content(text/plain, body) mail Mail(from_email, to_email, subject, content).get() try: response sg.client.mail.send.post(request_bodymail) if response.status_code 202: print(✅ 邮件发送成功) else: print(❌ 邮件发送失败) except Exception as e: print(f❌ 发送邮件异常: {e}) # 使用之前 Grad-CAM 的样本生成报告也可另选样本 evidence extract_heatmap_evidence(heatmap, target_fs6000) report generate_llm_report(true_label_name, evidence) print(-*50) print(自动生成的诊断报告) print(-*50) print(report) print(-*50) # 如果检测到严重故障如 021 级别则发送邮件通知 if 严重 in report or Critical in report: # 请替换为您的 SendGrid 信息 SENDGRID_API_KEY YOUR_SENDGRID_API_KEY FROM_EMAIL senderexample.com TO_EMAIL recipientexample.com send_plain_text_email(【轴承故障告警】严重故障需立即处理, report, SENDGRID_API_KEY, FROM_EMAIL, TO_EMAIL) else: print(未检测到严重故障不发送邮件)担任《Mechanical System and Signal Processing》《中国电机工程学报》《宇航学报》《控制与决策》等期刊审稿专家擅长领域信号滤波/降噪机器学习/深度学习时间序列预分析/预测设备故障诊断/缺陷检测/异常检测参考文章DeepBear-Health基于迁移学习和可解释时频分析的滚动轴承故障诊断Python - 哥廷根数学学派的文章https://zhuanlan.zhihu.com/p/2006621128815294039