桥梁拉索索力异常识别【附代码】
✅博主简介:擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导,毕业论文、期刊论文经验交流。
✅ 如需沟通交流,扫描文章底部二维码。
(1)环境振动与磁通量传感器的多模态索力测量融合:
桥梁拉索的索力可以通过振动频率法和磁通量传感器分别测量,各有利弊。提出一种基于卡尔曼滤波的融合估计算法。振动频率法通过分析加速度信号的频谱提取前几阶频率,根据弦振动公式计算索力,但受边界条件影响。磁通量传感器直接测量磁导率变化得到绝对索力,但易受温度漂移。构建状态空间模型,将真实索力和温度漂移作为状态变量,振动法索力作为观测值,磁通量输出作为另一观测值,使用扩展卡尔曼滤波进行最优融合。在某斜拉桥的6根典型拉索上进行了为期3个月的监测试验,融合后的索力测量标准差为0.8%FS,比单独振动法(1.4%FS)和单独磁通量法(1.2%FS)都更优。
(2)基于长短期记忆网络的索力时变趋势预测:
环境温度、车辆荷载会导致索力日波动和长期松弛。构建一个堆叠LSTM网络,输入为过去24小时的索力、温度、桥上交通流量(通过监控获得)三个时间序列(采样间隔10分钟),输出未来6小时的索力预测值。网络包含两层LSTM和dropout正则化。根据历史数据训练后,模型能够预测出由于温度升高导致的索力增长趋势,预测误差的均方根为5.2kN,而基准ARIMA模型为8.7kN。当预测索力超出设计允许范围的95%时发出预警。
(3)基于图注意力网络的多根拉索异常模式检测:
相邻拉索的索力变化存在空间相关性,一根拉索异常会导致相邻索力重新分配。将全桥梁拉索视为图节点,节点特征为当前索力与理论值的偏差百分比和温度修正后的索力变化率。边连接空间相邻的拉索,使用图注意力网络GAT进行信息传播。GAT的输出经过全连接层得到每个节点的异常评分。同时设计了一个对比损失,使正常状态下相邻节点特征相似,异常时被分离。在实际桥梁检测中,该方法成功识别了3次因锚头松动导致的索力异常,比单根拉索独立阈值法提前2~3天发现征兆。,"import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
from scipy.linalg import solve_lyapunov
class ExtendedKalmanFilter:
def __init__(self, F, H1, H2, Q, R1, R2, P0):
self.F = F # 状态转移矩阵
self.H1 = H1 # 振动法观测矩阵
self.H2 = H2 # 磁通量观测矩阵
self.Q = Q
self.R1 = R1
self.R2 = R2
self.P = P0
self.x = np.zeros((F.shape[0], 1))
def predict(self):
self.x = self.F @ self.x
self.P = self.F @ self.P @ self.F.T + self.Q
def update_vibration(self, z1):
K = self.P @ self.H1.T @ np.linalg.inv(self.H1 @ self.P @ self.H1.T + self.R1)
self.x = self.x + K @ (z1 - self.H1 @ self.x)
self.P = (np.eye(len(self.P)) - K @ self.H1) @ self.P
def update_magnetic(self, z2):
K = self.P @ self.H2.T @ np.linalg.inv(self.H2 @ self.P @ self.H2.T + self.R2)
self.x = self.x + K @ (z2 - self.H2 @ self.x)
self.P = (np.eye(len(self.P)) - K @ self.H2) @ self.P
def get_force(self):
return self.x[0,0]
class LSTMForcePredictor(nn.Module):
def __init__(self, input_dim=3, hidden_dim=64, num_layers=2, output_dim=1):
super().__init__()
self.lstm = nn.LSTM(input_dim, hidden_dim, num_layers, batch_first=True, dropout=0.2)
self.fc = nn.Linear(hidden_dim, output_dim)
def forward(self, x):
out, _ = self.lstm(x)
out = self.fc(out[:, -1, :])
return out
class GraphAttentionLayer(nn.Module):
def __init__(self, in_dim, out_dim, alpha=0.2):
super().__init__()
self.W = nn.Linear(in_dim, out_dim, bias=False)
self.a = nn.Parameter(torch.zeros(2*out_dim, 1))
nn.init.xavier_uniform_(self.a)
self.leaky_relu = nn.LeakyReLU(alpha)
def forward(self, H, adj):
# H: (B, N, in_dim)
Wh = self.W(H) # (B, N, out_dim)
N = Wh.shape[1]
a_input = torch.cat([Wh.unsqueeze(2).repeat(1,1,N,1), Wh.unsqueeze(1).repeat(1,N,1,1)], dim=-1) # (B,N,N,2*out)
e = self.leaky_relu(torch.matmul(a_input, self.a).squeeze(-1)) # (B,N,N)
# 掩码,只保留邻接边
e = e.masked_fill(adj == 0, -1e9)
attn = F.softmax(e, dim=-1)
out = torch.matmul(attn, Wh)
return out
class CableGAT(nn.Module):
def __init__(self, node_dim=2, hid_dim=32, num_classes=2):
super().__init__()
self.gat1 = GraphAttentionLayer(node_dim, hid_dim)
self.gat2 = GraphAttentionLayer(hid_dim, hid_dim)
self.fc = nn.Linear(hid_dim, num_classes)
def forward(self, H, adj):
x = self.gat1(H, adj)
x = F.elu(x)
x = self.gat2(x, adj)
anomaly_score = torch.softmax(self.fc(x), dim=-1)[:,:,1] # 异常概率
return anomaly_score
def contrastive_loss(embeddings, adj, temperature=0.5):
# 正样本:相邻节点对,负样本:非相邻节点对
embeddings = F.normalize(embeddings, dim=-1)
sim = torch.matmul(embeddings, embeddings.T) / temperature
pos_mask = adj > 0
pos_sim = sim[pos_mask].mean()
neg_mask = (adj == 0) & (~torch.eye(adj.shape[0], dtype=bool, device=adj.device))
neg_sim = sim[neg_mask].mean()
loss = -torch.log(torch.exp(pos_sim) / (torch.exp(pos_sim) + torch.exp(neg_sim)))
return loss
如有问题,可以直接沟通
👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇👇
