基于LSTM深度学习的电动汽车电池荷电状态(SOC)预测

摘要

电动汽车(EV)的普及对电池管理系统(BMS)提出了极高的要求。电池荷电状态(State of Charge, SOC)作为BMS最核心的参数之一,其精确估算对于提高电池利用率、防止过充过放、保障安全性和延长电池寿命至关重要。由于电池是一个复杂的非线性系统,其SOC受温度、负载电流、内阻、老化程度等多种因素影响,传统估算方法如安时积分法和开路电压法存在累积误差和实时性差等问题。本文深入探讨了基于长短期记忆网络(LSTM)的深度学习模型在电动汽车电池SOC预测中的应用。文章详细阐述了SOC预测的挑战、LSTM模型的原理、数据预处理、特征工程、模型构建、训练与超参数调优,以及模型评估的完整流程,并提供了完整的Python代码实现。实验结果表明,LSTM模型能够有效捕捉电池数据中的时序动态特性,实现高精度的SOC预测,为下一代智能BMS提供了有效的解决方案。

关键词: 电动汽车;电池管理系统;荷电状态;SOC预测;深度学习;长短期记忆网络;LSTM;Python


1. 引言

1.1 研究背景与意义

随着全球能源危机和环境污染问题日益严峻,电动汽车作为替代传统燃油车的重要解决方案,迎来了飞速发展。动力电池是电动汽车的“心脏”,其性能直接决定了车辆的续航里程、安全性和可靠性。然而,电池是一个复杂的电化学系统,其内部状态无法直接测量,只能通过外部特性(如电压、电流、温度)进行间接估算。

荷电状态(SOC)定义为当前电池剩余容量与额定容量的百分比,是驾驶者了解剩余续航里程的主要依据,更是BMS进行能量分配、热管理、均衡控制等功能的基础。不准确的SOC估算可能导致:

  1. 续航焦虑: 驾驶员无法信任仪表盘显示的剩余里程。
  2. 电池损伤: 可能导致电池过充或过放,加速电池老化,甚至引发热失控等安全事故。
  3. 能量效率低下: BMS无法在最佳工作区间调度电池能量。

因此,开发一种高精度、高鲁棒性且能适应复杂多变工况的SOC估算方法,具有重大的理论价值和现实意义。

1.2 传统SOC估算方法及其局限性

  1. 开路电压法(OCV):电池静置足够长时间后,其开路电压与SOC存在一一对应的关系。该方法简单且精度较高,但需要电池长时间静置,在车辆行驶过程中无法使用,通常仅用于校准或车辆启动时的初始SOC估计。
  2. 安时积分法(Ah-Counting):通过实时积分电流来计算充入或放出的电量。公式为:SOCt=SOC0−1Cn∫0tηi(τ)dτSOC_t = SOC_0 - \frac{1}{C_n} \int_0^t \eta i(\tau) d\tauSOCt=SOC0Cn10tηi(τ)dτ,其中CnC_nCn为额定容量,η\etaη为库伦效率。该方法原理简单,但严重依赖电流传感器的精度,且存在累积误差,需要定期用其他方法(如OCV法)进行校正。
  3. 等效电路模型(ECM)滤波法:建立电池的等效电路模型(如Rint、RC、Thevenin模型),结合卡尔曼滤波(KF)、扩展卡尔曼滤波(EKF)或无迹卡尔曼滤波(UKF)等算法进行状态估计。该方法能有效处理噪声和累积误差,但精度高度依赖于所建立的电池模型的准确性。电池模型参数(如内阻、电容)会随温度、SOC、老化程度(SOH)而变化,在线辨识这些参数计算复杂,对BMS的算力要求高。

1.3 深度学习方法的优势

近年来,深度学习在时序数据预测领域取得了巨大成功。基于数据驱动的方法,如LSTM,不需要精确的物理模型,而是通过大量历史数据自动学习电池的动态特性与SOC之间的复杂非线性映射关系。其优势在于:

  • 非线性映射能力强:能够捕捉电压、电流、温度等外部测量值与SOC之间复杂的非线性关系。
  • 时序依赖性建模:LSTM天生为处理时序数据而设计,能够记忆长期的依赖关系,这对于理解电池的弛豫效应和 hysteresis 效应至关重要。
  • 强鲁棒性:对测量噪声有一定的容忍度,且可以通过学习来自动适应不同工况和电池老化程度。
  • 端到端学习:无需复杂的特征工程和参数辨识,直接从原始数据或简单处理后的数据中学习。

本文将聚焦于使用LSTM这一强大的深度学习模型来解决电动汽车电池SOC的实时预测问题。

2. 理论基础

2.1 循环神经网络(RNN)与梯度消失问题

循环神经网络(RNN)是专门用于处理序列数据的神经网络。它通过循环单元将之前步的信息传递到当前步,理论上可以捕捉任意长度的历史信息。

其隐藏状态更新公式为:ht=tanh⁡(Wxhxt+Whhht−1+bh)h_t = \tanh(W_{xh}x_t + W_{hh}h_{t-1} + b_h)ht=tanh(Wxhxt+Whhht1+bh)

然而,传统的RNN在训练过程中会遇到著名的梯度消失/爆炸问题。当序列较长时,误差反向传播时梯度会指数级地减小或增大,导致网络无法学习到长距离的依赖关系。这对于需要长期记忆的电池SOC预测来说是致命的缺陷。

2.2 长短期记忆网络(LSTM)

长短期记忆网络(LSTM)是RNN的一种特殊变体,由Hochreiter & Schmidhuber于1997年提出,并被广泛改进和普及。它通过引入精巧的“门控机制”来解决梯度消失问题,从而有效地学习长期依赖关系。

一个LSTM单元的核心是细胞状态(Cell State) CtC_tCt,它像一个传送带,在整个链上运行,只有一些轻微的线性交互,信息很容易不加改变地流过。LSTM通过三个门来精确控制细胞状态:

  1. 遗忘门(Forget Gate):决定从细胞状态中丢弃哪些信息。它查看当前输入xtx_txt和上一隐藏状态ht−1h_{t-1}ht1,并输出一个0到1之间的数给细胞状态Ct−1C_{t-1}Ct1。1表示“完全保留”,0表示“完全丢弃”。
    ft=σ(Wf⋅[ht−1,xt]+bf)f_t = \sigma(W_f \cdot [h_{t-1}, x_t] + b_f)ft=σ(Wf[ht1,xt]+bf)

  2. 输入门(Input Gate):决定将哪些新信息存入细胞状态。它包含一个sigmoid层和一个tanh层。sigmoid层决定更新哪些值,tanh层创建一个新的候选值向量C~t\tilde{C}_tC~t,这些值可能会被加入到细胞状态中。
    it=σ(Wi⋅[ht−1,xt]+bi)i_t = \sigma(W_i \cdot [h_{t-1}, x_t] + b_i)it=σ(Wi[ht1,xt]+bi)
    C~t=tanh⁡(WC⋅[ht−1,xt]+bC)\tilde{C}_t = \tanh(W_C \cdot [h_{t-1}, x_t] + b_C)C~t=tanh(WC[ht1,xt]+bC)

  3. 更新细胞状态:将旧的细胞状态Ct−1C_{t-1}Ct1更新为新的细胞状态CtC_tCt。我们将旧状态与ftf_tft相乘,丢弃掉我们决定忘记的信息。然后加上it∗C~ti_t * \tilde{C}_titC~t,这是新的候选值,按我们决定更新的程度来缩放。
    Ct=ft∗Ct−1+it∗C~tC_t = f_t * C_{t-1} + i_t * \tilde{C}_tCt=ftCt1+itC~t

  4. 输出门(Output Gate):基于细胞状态,决定输出什么。首先运行一个sigmoid层来决定细胞状态的哪些部分将输出。然后,让细胞状态通过tanh(将值规范到-1和1之间)并将其与sigm门的输出相乘,最终得到该单元的隐藏状态输出hth_tht
    ot=σ(Wo⋅[ht−1,xt]+bo)o_t = \sigma(W_o \cdot [h_{t-1}, x_t] + b_o)ot=σ(Wo[ht1,xt]+bo)
    ht=ot∗tanh⁡(Ct)h_t = o_t * \tanh(C_t)ht=ottanh(Ct)

这种门控机制使得LSTM能够有选择地记住或忘记信息,从而有效地捕获时间序列中的长期模式,非常适合用于电池SOC的时序预测。

3. 数据准备与预处理

本项目使用NASA Ames预测中心提供的公开电池数据集(Battery Data Set - B0005、B0006、B0007等)。该数据集记录了18650锂离子电池在多种温度、不同工作 profiles(充放电电流变化)下的循环老化实验数据。测量参数包括电压、电流、温度等,并通过专业设备记录了真实的SOC值作为标签。

3.1 数据加载与探索性分析(EDA)

首先,我们加载数据并查看其基本结构和统计信息。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout, Input
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau
import warnings
warnings.filterwarnings('ignore')# 假设数据已加载到DataFrame `df` 中
# 这里我们用模拟数据的代码来代替,实际应用中需要从CSV等文件加载
print("Simulating battery data structure...")
# 实际数据列可能包括:cycle, time, voltage, current, temperature, capacity, soc
np.random.seed(42)
time_steps = 1000
simulated_data = {'time': np.arange(time_steps),'voltage_measured': 3.7 + 0.3 * np.sin(np.arange(time_steps)/100) + np.random.normal(0, 0.01, time_steps),'current_measured': np.random.choice([-4, 0, 2], size=time_steps, p=[0.4, 0.2, 0.4]), # 放电为负,充电为正,零为静置'temperature_measured': 25 + 5 * np.sin(np.arange(time_steps)/200) + np.random.normal(0, 0.2, time_steps),'soc': np.linspace(100, 20, time_steps) + np.random.normal(0, 0.5, time_steps) # 模拟SOC从100%线性下降到20%,带有噪声
}
df = pd.DataFrame(simulated_data)
df['soc'] = np.clip(df['soc'], 0, 100) # 确保SOC在0-100之间print("Simulated Data Overview:")
print(df.head())
print("\nData Info:")
print(df.info())
print("\nDescriptive Statistics:")
print(df.describe())# 绘制关键参数时序图
plt.figure(figsize=(12, 10))
plt.subplot(3, 1, 1)
plt.plot(df['time'], df['voltage_measured'], label='Voltage (V)')
plt.ylabel('Voltage (V)')
plt.legend()plt.subplot(3, 1, 2)
plt.plot(df['time'], df['current_measured'], label='Current (A)', color='orange')
plt.ylabel('Current (A)')
plt.legend()plt.subplot(3, 1, 3)
plt.plot(df['time'], df['soc'], label='SOC (%)', color='green')
plt.xlabel('Time')
plt.ylabel('SOC (%)')
plt.legend()
plt.tight_layout()
plt.show()# 绘制相关性热力图
plt.figure(figsize=(8, 6))
corr_matrix = df[['voltage_measured', 'current_measured', 'temperature_measured', 'soc']].corr()
sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0)
plt.title('Feature Correlation Heatmap')
plt.show()

3.2 数据清洗与特征工程

  1. 处理缺失值:检查并处理数据中的缺失值(NASA数据集通常很完整,但实际数据可能需要插值或删除)。
  2. 处理异常值:基于领域知识(如电压超出正常范围)或统计方法(如3σ原则)识别并处理异常值。
  3. 特征工程
    • 计算差分特征:例如,计算电压和电流的变化率 dv/dt, di/dt,可以反映电池的动态响应。
    • 滑动窗口统计特征:例如,过去N个时间点的电流均值、方差等。
    • SOC变化量:有时将SOC的绝对值的预测改为SOC变化的预测会更稳定。
    • 时间相关特征:如自循环开始的时间,可能反映老化效应(但本示例暂不涉及老化)。
    • 库伦计数:虽然安时积分法有缺陷,但其短期变化量作为一个输入特征可能对模型有帮助。
# 示例:简单的特征工程
df['current_chg'] = df['current_measured'].diff() # 电流变化率
df['voltage_chg'] = df['voltage_measured'].diff() # 电压变化率
# 填充第一个值的NaN
df.fillna(method='bfill', inplace=True) # 定义特征和目标变量
features = ['voltage_measured', 'current_measured', 'temperature_measured', 'current_chg', 'voltage_chg']
target = 'soc'X = df[features].values
y = df[target].valuesprint(f"Feature matrix shape: {X.shape}")
print(f"Target vector shape: {y.shape}")

3.3 数据标准化与序列构建

深度学习模型对输入数据的尺度非常敏感。我们将特征标准化为均值为0,方差为1。目标变量SOC在0-100之间,通常进行归一化到[0,1]或[-1,1]区间。

最关键的一步是构建适用于LSTM的监督学习序列。LSTM的输入是一个三维数组:[samples, timesteps, features]

  • samples:序列的数量。
  • timesteps:一个序列包含的时间步数(回溯窗口大小)。
  • features:在每个时间步上观察到的特征数量。

我们使用滑动窗口方法将时间序列数据重构为样本和对应的标签。

# 数据标准化
scaler_X = StandardScaler()
scaler_y = MinMaxScaler(feature_range=(0, 1)) # 将SOC缩放到0-1之间X_scaled = scaler_X.fit_transform(X)
y_scaled = scaler_y.fit_transform(y.reshape(-1, 1)).flatten() # Flatten for later use# 定义时间窗口参数
lookback = 50  # 使用过去50个时间步来预测下一个时间步的SOC
forecast = 1   # 预测下一步(也可以预测多步,但SOC预测通常为一步预测)# 构建序列的函数
def create_dataset(X, y, lookback=1, forecast=1):Xs, ys = [], []for i in range(len(X) - lookback - forecast + 1):v = X[i:i+lookback]Xs.append(v)ys.append(y[i+lookback]) # 预测的是第i+lookback个点的SOCreturn np.array(Xs), np.array(ys)# 创建序列
X_seq, y_seq = create_dataset(X_scaled, y_scaled, lookback, forecast)# 检查形状
print(f"LSTM Input Shape (samples, timesteps, features): {X_seq.shape}")
print(f"Target Shape: {y_seq.shape}")# 划分训练集、验证集和测试集 (e.g., 70%-15%-15%)
train_size = int(0.7 * len(X_seq))
val_size = int(0.15 * len(X_seq))X_train, X_val, X_test = X_seq[:train_size], X_seq[train_size:train_size+val_size], X_seq[train_size+val_size:]
y_train, y_val, y_test = y_seq[:train_size], y_seq[train_size:train_size+val_size], y_seq[train_size+val_size:]print(f"Train set: X={X_train.shape}, y={y_train.shape}")
print(f"Validation set: X={X_val.shape}, y={y_val.shape}")
print(f"Test set: X={X_test.shape}, y={y_test.shape}")

4. LSTM模型构建与训练

4.1 模型架构设计

我们将构建一个序列模型。常见的结构是堆叠多个LSTM层,中间加入Dropout层以防止过拟合,最后通过全连接层(Dense)输出预测值。

# 清除之前的会话,保证模型从头开始训练
tf.keras.backend.clear_session()# 定义模型
model = Sequential()
# 第一层LSTM,需要指定input_shape并return_sequences=True以连接下一层LSTM
model.add(Input(shape=(X_train.shape[1], X_train.shape[2]))) # (lookback, n_features)
model.add(LSTM(units=64, return_sequences=True))
model.add(Dropout(0.2)) # 丢弃20%的单元# 第二层LSTM
model.add(LSTM(units=32, return_sequences=False)) # 最后一层LSTM不需要return_sequences
model.add(Dropout(0.2))# 全连接层
model.add(Dense(16, activation='relu'))
model.add(Dense(units=1)) # 输出层,线性激活,预测一个连续的SOC值# 编译模型
model.compile(optimizer='adam', loss='mse', metrics=['mae']) # 使用均方误差损失和平均绝对误差指标# 显示模型结构
model.summary()

4.2 模型训练与超参数调优

我们使用Early Stopping和Learning Rate Reduction回调来防止过拟合并优化训练过程。

# 定义回调函数
early_stopper = EarlyStopping(monitor='val_loss', patience=15, verbose=1, restore_best_weights=True)
lr_reducer = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=5, verbose=1, min_lr=1e-6)callbacks = [early_stopper, lr_reducer]# 训练模型
history = model.fit(X_train, y_train,epochs=100,batch_size=32,validation_data=(X_val, y_val),callbacks=callbacks,verbose=1,shuffle=False # 对于时序数据,通常不打乱顺序
)# 绘制训练历史
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Model Loss')
plt.ylabel('Loss (MSE)')
plt.xlabel('Epoch')
plt.legend()plt.subplot(1, 2, 2)
plt.plot(history.history['mae'], label='Training MAE')
plt.plot(history.history['val_mae'], label='Validation MAE')
plt.title('Model Mean Absolute Error')
plt.ylabel('MAE')
plt.xlabel('Epoch')
plt.legend()
plt.tight_layout()
plt.show()

4.3 模型评估与预测

在测试集上评估模型的最终性能,并使用各种指标来衡量预测精度。

# 在测试集上进行预测
y_pred_scaled = model.predict(X_test)# 将预测值和真实值反标准化/反归一化回原始尺度
y_pred = scaler_y.inverse_transform(y_pred_scaled).flatten()
# 注意:y_test本身就是归一化后的,也需要反归一化
y_test_orig = scaler_y.inverse_transform(y_test.reshape(-1, 1)).flatten()# 计算评估指标
mae = mean_absolute_error(y_test_orig, y_pred)
rmse = np.sqrt(mean_squared_error(y_test_orig, y_pred))
r2 = r2_score(y_test_orig, y_pred)print(f'Test MAE: {mae:.3f}%')
print(f'Test RMSE: {rmse:.3f}%')
print(f'Test R²: {r2:.4f}')# 绘制预测结果与真实值的对比图
plt.figure(figsize=(12, 6))
plt.plot(y_test_orig, label='True SOC', color='blue', alpha=0.6)
plt.plot(y_pred, label='Predicted SOC', color='red', alpha=0.8, linestyle='--')
plt.title('SOC Prediction on Test Set')
plt.ylabel('SOC (%)')
plt.xlabel('Time Step')
plt.legend()
plt.grid(True)
plt.show()# 绘制误差分布图
errors = y_test_orig - y_pred
plt.figure(figsize=(10, 4))
plt.hist(errors, bins=50, edgecolor='black')
plt.title('Distribution of Prediction Errors')
plt.xlabel('Prediction Error (%)')
plt.ylabel('Frequency')
plt.axvline(x=0, color='r', linestyle='--')
plt.show()# 绘制散点图:真实值 vs 预测值
plt.figure(figsize=(8, 8))
plt.scatter(y_test_orig, y_pred, alpha=0.5)
plt.plot([y_test_orig.min(), y_test_orig.max()], [y_test_orig.min(), y_test_orig.max()], 'r--', lw=2)
plt.xlabel('True SOC (%)')
plt.ylabel('Predicted SOC (%)')
plt.title(f'True vs Predicted SOC (R² = {r2:.4f})')
plt.grid(True)
plt.show()

5. 高级主题与优化方向

5.1 超参数优化(HPO)

上述模型使用的是手动设置的超参数(如LSTM层数、单元数、lookback、dropout率等)。为了获得最佳性能,可以使用自动化超参数优化技术:

  • Grid Search / Random Search:在预定义的超参数空间中进行搜索。
  • Bayesian Optimization:更高效的搜索方法,如使用Hyperopt、Optuna或Keras Tuner库。
# 示例:使用Keras Tuner进行随机搜索(伪代码框架)
# import kerastuner as kt
# def build_model(hp):
#     model = Sequential()
#     model.add(Input(shape=(lookback, len(features))))
#     model.add(LSTM(units=hp.Int('units_1', min_value=32, max_value=128, step=32), return_sequences=True))
#     model.add(Dropout(hp.Float('dropout_1', 0.1, 0.5, step=0.1)))
#     ...
#     model.compile(optimizer='adam', loss='mse')
#     return model
#
# tuner = kt.RandomSearch(build_model, objective='val_loss', max_trials=10, executions_per_trial=2)
# tuner.search(X_train, y_train, epochs=50, validation_data=(X_val, y_val), callbacks=[early_stopper])
# best_model = tuner.get_best_models(num_models=1)[0]

5.2 考虑电池老化(SOH)的模型

电池的容量会随着循环次数的增加而衰减(容量衰减)。这意味着同样充入/放出的电量,对应的SOC变化会不同。一个更强大的模型应该将电池的健康状态(State of Health, SOH)或循环次数作为额外输入特征,使模型能够自适应老化的影响。

5.3 seq2seq 与多步预测

本文实现的是“单步预测”,即用过去N个点预测下一个点的SOC。在某些应用场景下,可能需要预测未来多个时间步的SOC(多步预测)。这可以通过Seq2Seq架构(编码器-解码器)或直接多输出模型来实现。

5.4 在线学习与模型更新

电池特性会随时间变化。部署在真实车辆上的模型需要具备在线学习能力,能够利用新的驾驶数据持续微调模型参数,以适应特定车辆和驾驶员的独特使用模式以及电池的老化。

5.5 模型轻量化与部署

最终模型需要部署在资源受限的BMC硬件上。因此,需要进行模型剪枝量化等操作来减小模型体积和计算量,以满足实时性的要求。TensorFlow Lite是完成这项任务的优秀工具。

6. 结论与展望

本文系统地介绍了基于LSTM深度学习模型的电动汽车电池SOC预测方法。通过理论分析、数据预处理、模型构建、训练评估等一系列步骤,证明了LSTM模型能够高效地学习电池充放电过程中的复杂非线性时序 dynamics,实现了比传统方法更精确、更鲁棒的SOC估算。

实验结果表明,该模型在测试集上取得了较低的MAE和RMSE,以及较高的R²分数,预测曲线与真实值高度吻合。LSTM模型成功克服了安时积分法的累积误差问题,且无需像等效电路模型那样进行复杂的参数辨识。

展望未来,该领域的研究方向包括:

  1. 多物理量融合:引入更多传感器数据,如电池内部温度、阻抗谱等,构建更全面的健康状态画像。
  2. 迁移学习:将在实验室大量数据上训练好的模型,迁移到个体车辆上,用少量数据快速适配,解决电池个体差异问题。
  3. 不确定性量化:让模型不仅输出SOC预测值,还输出其置信区间,这对于安全攸关的BMS系统至关重要。
  4. 结合物理模型:开发混合模型,将数据驱动的深度学习与基于电化学原理的物理模型相结合,兼具两者的优势。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/96758.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/96758.shtml
英文地址,请注明出处:http://en.pswp.cn/web/96758.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Golang语言之数组、切片与子切片

一、数组先记住数组的核心特点:盒子大小一旦定了就改不了(长度固定),但盒子里的东西能换(元素值可变)。就像你买了个能装 3 个苹果的铁皮盒,想多装 1 个都不行,但里面的苹果可以换成…

速通ACM省铜第四天 赋源码(G-C-D, Unlucky!)

目录 引言: G-C-D, Unlucky! 题意分析 逻辑梳理 代码实现 结语: 引言: 因为今天打了个ICPC网络赛,导致坐牢了一下午,没什么时间打题目了,就打了一道题,所以,今天我们就只讲一题了&…

数据链路层总结

目录 (一)以太网(IEEE 802.3) (1)以太网的帧格式 (2)帧协议类型字段 ①ARP协议 (横跨网络层和数据链路层的协议) ②RARP协议 (二&#xff…

Scala 新手实战三案例:从循环到条件,搞定基础编程场景

Scala 新手实战三案例:从循环到条件,搞定基础编程场景 对 Scala 新手来说,单纯记语法容易 “学完就忘”,而通过小而精的实战案例巩固知识点,是掌握语言的关键。本文精选三个高频基础场景 ——9 乘 9 乘法口诀表、成绩等…

java学习笔记----标识符与变量

1.什么是标识符?Java中变量、方法、类等要素命名时使用的字符序列,称为标识符。 技巧:凡是自己可以起名字的地方都叫标识符。 比如:类名、方法名、变量名、包名、常量名等 2.标识符的命名规则由26个英文字母大小写,0-9,或$组成 数字不可以开…

AI产品经理面试宝典第93天:Embedding技术选型与场景化应用指南

1. Embedding技术演进全景解析 1.1 稀疏向量:关键词匹配的基石 1.1.1 问:请说明稀疏向量的适用场景及技术特点 答:稀疏向量适用于关键词精确匹配场景,典型实现包括TF-IDF、BM25和SPLADE。其技术特征表现为50,000+高维向量且95%以上位置为零值,通过余弦或点积计算相似度…

【Mermaid.js】从入门到精通:完美处理节点中的空格、括号和特殊字符

文章标签: Mermaid, Markdown, 前端开发, 数据可视化, 流程图 文章摘要: 你是否在使用 Mermaid.js 绘制流程图时,仅仅因为节点文本里加了一个空格或括号,整个图就渲染失败了?别担心,这几乎是每个 Mermaid 新…

多技术融合提升环境生态水文、土地土壤、农业大气等领域的数据分析与项目科研水平

一:空间数据获取与制图1.1 软件安装与应用1.2 空间数据介绍1.3海量空间数据下载1.4 ArcGIS软件快速入门1.5 Geodatabase地理数据库二:ArcGIS专题地图制作2.1专题地图制作规范2.2 空间数据的准备与处理2.3 空间数据可视化:地图符号与注记2.4 研…

【音视频】Android NDK 与.so库适配

一、名词解析 名词全称核心说明Android NDKNative Development Kit在SDK基础上增加“原生”开发能力,支持使用C/C编写代码,用于开发需要调用底层能力的模块(如音视频、加密算法等).so库Shared Object即共享库,由NDK编…

SpringBoot 轻量级一站式日志可视化与JVM监控

一、项目初衷Java 应用开发的同学都知道,项目上线后,日志的可视化查询与 JVM 的可视化监控是一件非常重要的事。 市面上成熟方案一般是采用 ELK/EFK 实现日志可视化,采用 Actuator Prometheus Grafana 实现 JVM 监控。 这两套都是非常优秀的…

【Leetcode hot 100】101.对称二叉树

问题链接 101.对称二叉树 问题描述 给你一个二叉树的根节点 root , 检查它是否轴对称。 示例 1: 输入:root [1,2,2,3,4,4,3] 输出:true 示例 2: 输入:root [1,2,2,null,3,null,3] 输出:…

Zynq开发实践(FPGA之选择开发板)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】我们之所以选用zynq开发板,就在于它支持arm软件开发,也支持fpga开发,甚至可以运行linux,这是之前没有…

Flutter Riverpod 3.0 发布,大规模重构下的全新状态管理框架

在之前的 《注解模式下的 Riverpod 有什么特别之处》我们聊过 Riverpod 2.x 的设计和使用原理,同时当时我们就聊到作者已经在开始探索 3.0 的重构方式,而现在随着 Riverpod 3.0 的发布,riverpod 带来了许多细节性的变化。 当然,这…

Xcode 上传 ipa 全流程详解 App Store 上架流程、uni-app 生成 ipa 文件上传与审核指南

对于 iOS 开发者而言,应用开发完成后最重要的一步就是将应用打包为 ipa 文件,并上传至 App Store Connect 进行分发或上架。 其中,Xcode 上传 ipa 是最常见的方法,但很多开发者在实际操作中常常遇到卡住、上传失败或签名错误等问题…

快速选中对象

图片要求 图片背景单纯,对象边缘比较清晰 对象选择工具 选择对象选择工具后,画出大致区域,系统将自动分析图片内容,从而实现快速选择图片中的一个惑多个对象他有两种模式,分别是举行与套索模式。使用时可以先选中对象的…

点到点链路上的OSPF动态路由(2025年9月10日)

一、前言前面我们已经分享过了静态路由、缺省路由、浮动静态路由这些静态路由的配置。接下来将会 陆陆续续开始分享动态路由以及其他路由配置。博主这里是一个新人,了解这些路由配置不是自上而下的,而是自下而上的,也就是说通过实验去理解原理…

技术视界 | 末端执行器:机器人的“手”,如何赋予机器以生命?

在现代自动化系统中,末端执行器(End Effector)作为机器人与物理世界交互的“手”,发挥着至关重要的作用。它直接安装在机械臂末端,不仅是机器人实现“抓取、感知和操作”三大核心功能的关键部件,更是整个自…

滑动窗口概述

滑动窗口算法简介滑动窗口是一种用于处理数组或字符串子区间问题的高效算法。它通过维护一个动态窗口(通常由两个指针表示)来避免重复计算,将时间复杂度从O(n)优化到O(n)。基本实现步骤初始化窗口指针:通常使用left和right指针表示…

AI 创建学生管理系统

使用腾讯元宝创建,整体效果不错。修正2个bug跑起来,达到了需要的功能先上效果图:按钮分类别配色,界面清爽。喜欢这布局创建过程:prompt: 使用最新稳定vue版,使用pinia存储,基于typescript, 样式…

ASP.NET Core 中的简单授权

ASP.NET Core 中的授权通过 [Authorize] 属性及其各种参数控制。 在其最基本的形式中,通过向控制器、操作或 [Authorize] Page 应用 Razor 属性,可限制为仅允许经过身份验证的用户访问该组件。 使用 [Authorize] 属性 以下代码限制为仅允许经过身份验证…