当前位置: 首页 > article >正文

深度学习 | 基于 LSTM 模型的多电池健康状态对比及预测

Hi,大家好,我是半亩花海。在电池管理系统(BMS)中,电池的健康状态(State of Health, SOH)是评估电池剩余寿命的重要指标,而准确预测电池的健康状态可以帮助实现电池的高效管理,延长电池的使用寿命并预防电池故障。本项目的目标是使用长短期记忆(LSTM)神经网络对多个电池进行健康状态对比及预测,并使用收集到的电池循环数据来训练模型并评估其性能。

目录

一、数据概述

二、数据可视化

1. 绘制容量与循环次数的关系

2. 绘制健康状态与循环次数的关系

3. 多电池的健康状态对比

三、数据预处理

四、LSTM模型构建

五、模型训练

六、模型评估

七、保存预测结果


一、数据概述

数据来自八个电池单元(B05, B07, B18, B33, B34, B46, B47, B48),每个电池包含多个充放电周期的数据。如下所示,数据存储在CSV文件中。经过初步数据处理之后,每个数据文件提取了包含以下字段的关键信息:

  • cycle:循环次数
  • capacity:容量
  • SOH:健康状态(State of Health)

以下是数据的读取和清洗过程。

import os
import pandas as pd

# 获取数据集目录
directory_main = os.listdir('D:\Soochow University\Battery Research\ML_Course_SOH\case_one\datasets')
directory_edited = [file for file in directory_main if file != '.ipynb_checkpoints']  # 排除.ipynb_checkpoints目录
print(directory_main)
print(directory_edited)
print("The numbers of datasets:", len(directory_main))
print("The numbers of datasets:", len(directory_edited))
  • os.listdir() 用于列出指定路径下的所有文件,返回一个文件名列表。

# 定义电池编号
num = ['B05', 'B07', 'B18', 'B33', 'B34', 'B46', 'B47', 'B48']
# 循环读取每个电池的数据文件
for i in range(len(directory_edited)):
    path = os.path.join('D:\Soochow University\Battery Research\ML_Course_SOH\case_one\datasets/', num[i] + '_discharge_soh.csv')
    csv = pd.read_csv(path)
    df = pd.DataFrame(csv)
    vec = df[['cycle', 'capacity', 'SOH']]
    globals()['data_{}'.format(num[i])] = vec

data = pd.read_csv('D:\Soochow University\Battery Research\ML_Course_SOH\case_one\datasets/B05_discharge_soh.csv')
df = pd.DataFrame(data)
df
  • 通过pandas.read_csv()读取每个电池单元的CSV文件,并提取其包含的循环次数、容量、SOH数据。
  • 使用globals()动态创建每个电池的数据框(data_B05data_B07等),便于后续的处理。

data_B05

以其中一个电池为例,展示其 'cycle', 'capacity', 'SOH' 部分的数据,如上所示。


二、数据可视化

我们通过可视化来分析电池数据的特点。以下图表展示了电池的容量、健康状态(SOH)与循环次数之间的关系,即电池退化曲线、健康状态分析曲线

1. 绘制容量与循环次数的关系

import seaborn as sns
import matplotlib.pyplot as plt

# 绘制每个电池的容量随循环次数变化的散点图
for i in range(len(directory_edited)):
    dff = globals()['data_{}'.format(num[i])]
    sns.set_style("darkgrid")
    plt.figure(figsize=(12, 8))
    plt.scatter(dff['cycle'], dff['capacity'])
    plt.ylabel('Capacity', fontsize=15)
    plt.xlabel('cycle', fontsize=15)
    plt.title('Discharge_' + num[i], fontsize=15)
    plt.show()
  • 使用seaborn.set_style()设置图表背景样式。
  • 使用matplotlib.pyplot.scatter()绘制每个电池的容量随循环次数的变化。
  • plt.show()显示每张图表。

2. 绘制健康状态与循环次数的关系

# 绘制每个电池的SOH随循环次数变化的散点图
for i in range(len(directory_edited)):
    dff = globals()['data_{}'.format(num[i])]
    sns.set_style("darkgrid")
    plt.figure(figsize=(12, 8))
    plt.scatter(dff['cycle'], dff['SOH'])
    plt.ylabel('SoH', fontsize=15)
    plt.xlabel('cycle', fontsize=15)
    plt.title('Discharge_' + num[i], fontsize=15)
    plt.show()
  • 通过同样的方式,我们可以查看电池的健康状态(SOH)与循环次数之间的关系。
  • 每个电池的健康状态随循环次数的变化趋势会有所不同。

3. 多电池的健康状态对比

  • 为了比较不同电池的健康状态,我们将多个电池的SOH变化绘制在同一张图上。
  • 通过plt.legend()添加图例,便于区分不同电池。
# 比较不同电池的SOH变化
sns.set_style("darkgrid")
plt.figure(figsize=(12, 8))
plt.scatter(data_B05['cycle'], data_B05['SOH'], label='B05')
plt.scatter(data_B07['cycle'], data_B07['SOH'], label='B07')
plt.scatter(data_B18['cycle'], data_B18['SOH'], label='B18')
plt.legend(prop={'size': 16})
plt.ylabel('SoH', fontsize=15)
plt.xlabel('Discharge cycle', fontsize=15)
plt.title('SoH of group A', fontsize=15)
plt.show()

    sns.set_style("darkgrid")
    plt.figure(figsize=(12, 8))
    
    plt.scatter(data_B33['cycle'], data_B33['SOH'],label='B33')
    plt.scatter(data_B34['cycle'], data_B34['SOH'],label='B34')
    
    plt.legend(prop={'size': 16})
    
    plt.ylabel('SoH', fontsize = 15)
    plt.xlabel('Discharge cycle', fontsize = 15)
    plt.title('SoH of group B', fontsize = 15)
    plt.show()

    sns.set_style("darkgrid")
    plt.figure(figsize=(12, 8))
    
    plt.scatter(data_B46['cycle'], data_B46['SOH'],label='B46')
    plt.scatter(data_B47['cycle'], data_B47['SOH'],label='B47')
    plt.scatter(data_B48['cycle'], data_B48['SOH'],label='B48')
    
    plt.legend(prop={'size': 16})
    
    plt.ylabel('SoH', fontsize = 15)
    plt.xlabel('Discharge cycle', fontsize = 15)
    plt.title('SoH of group C', fontsize = 15)
    plt.show()

     


    三、数据预处理

    LSTM模型需要以时间序列的形式输入数据,因此我们需要将电池健康状态的数据转化为适合LSTM的格式。以下是模型构建之前的数据集创建部分。

    • create_dataset():该函数将原始的时间序列数据切分成多个子序列,每个子序列的长度由look_back决定。每个子序列的目标值是该子序列之后的一个时间步的健康状态(SoH)。
    • 数据集被划分为50%的训练集和50%的测试集。
    import numpy as np
    
    # 划分训练集和测试集
    dataset = data_B48["SOH"]
    cycle = data_B48['cycle']
    
    dataset = np.array(dataset)
    dataset = dataset.reshape((len(dataset), 1))
    dataset.shape

      train_size = int(len(dataset) * 0.5)
      test_size = len(dataset) - train_size
      train, test = dataset[0:train_size,:], dataset[train_size:len(dataset),:]
      print(len(train), len(test))

      # 创建时间序列数据集
      def create_dataset(dataset, look_back=1):
          dataX, dataY = [], []
          for i in range(len(dataset) - look_back):
              a = dataset[i:(i + look_back), 0]
              dataX.append(a)
              dataY.append(dataset[i + look_back, 0])
          return np.array(dataX), np.array(dataY)
      
      look_back = 10
      trainX, trainY = create_dataset(train, look_back)
      testX, testY = create_dataset(test, look_back)

      trainX

      # 重塑数据以适应LSTM输入
      trainX = np.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1]))
      testX = np.reshape(testX, (testX.shape[0], 1, testX.shape[1]))
      
      print(trainX.shape)
      print(testX.shape)


      四、LSTM模型构建

      LSTM是一个处理时间序列数据的强大工具。我们将使用LSTM来预测电池的健康状态。以下是LSTM模型定义部分。

      import torch
      import torch.nn as nn
      import torch.optim as optim
      
      class MyLSTMModel(nn.Module):
          def __init__(self, input_size, hidden_size, output_size):
              super(MyLSTMModel, self).__init__()
              self.lstm = nn.LSTM(input_size, hidden_size, batch_first=True)
              self.fc = nn.Linear(hidden_size, output_size)
      
          def forward(self, x):
              lstm_out, _ = self.lstm(x)
              output = self.fc(lstm_out[:, -1, :])  # 使用最后一个时间步的输出
              return output
      
      • LSTM:LSTM层用于处理输入的时间序列数据,input_size为每个时间步的特征数量,hidden_size为LSTM层的隐藏单元数量。
      • Linear:全连接层,用于将LSTM层的输出映射到目标变量(电池健康状态)的预测值。

      五、模型训练

      我们使用PyTorch训练LSTM模型,采用Adam优化器和L1损失函数(Mean Absolute Error,MAE)来优化模型。

      # 定义训练循环
      model = MyLSTMModel(input_size=1, hidden_size=64, output_size=1)
      criterion = nn.L1Loss()  # L1损失函数(MAE)
      optimizer = optim.Adam(model.parameters())
      
      # 转换为PyTorch张量
      trainX_tensor = torch.tensor(trainX, dtype=torch.float32)
      trainY_tensor = torch.tensor(trainY, dtype=torch.float32)
      
      # 训练模型
      num_epochs = 566  # 训练566个epoch
      history = {'train_loss': [], 'val_loss': []}
      
      for epoch in range(num_epochs):
          model.train()
          optimizer.zero_grad()
      
          # 假设trainX_tensor是一个三维形状张量(batch_size,sequence_length,input_size)
          output = model(trainX_tensor)
      
          # 假设trainY_tensor是PyTorch张量
          loss = criterion(output.squeeze(), trainY_tensor)
      
          loss.backward()
          optimizer.step()
      
          history['train_loss'].append(loss.item())
      
          print(f'Epoch [{epoch + 1}/{num_epochs}], Train Loss: {loss.item():.4f}')
      • optimizer.zero_grad():在每个训练周期开始时清除梯度。
      • model.train():将模型设置为训练模式。
      • loss.backward():反向传播计算梯度。
      • optimizer.step():更新模型参数。

      plt.plot(history['train_loss'], label='train')
      plt.xlabel('Epoch')
      plt.ylabel('Loss')
      plt.legend()
      plt.show()


      六、模型评估

      训练完成后,我们使用测试集对模型进行评估,并计算其预测的RMSEMAE

      • model.eval():将模型设置为评估模式,关闭dropout等操作。
      • mean_absolute_errormean_squared_error:计算模型预测的平均绝对误差(MAE)均方根误差(RMSE),用来评估模型性能。
      from sklearn.metrics import mean_absolute_error, mean_squared_error
      import torch
      import math
      
      # 假设“model”是你训练的PyTorch模型
      # 假设'testX'、'trainX'、'testY'、'trainY'是您的数据
      
      # 将“testX”和“trainX”转换为PyTorch张量
      testX_tensor = torch.tensor(testX, dtype=torch.float32)
      testY_tensor = torch.tensor(testY, dtype=torch.float32)
      
      # 将模型设置为评估模式
      model.eval()
      
      # 使用PyTorch进行预测
      with torch.no_grad():
          yhat_test = model(testX_tensor)
          yhat_test_torch = yhat_test.numpy()
      
      # 假设'testY'和'yhat_test_torch'是numpy数组或PyTorch张量
      # 如果'testY'是PyTorch张量,则将其转换为numpy数组
      testY = testY.numpy() if torch.is_tensor(testY) else testY
      
      # 计算误差
      rmse = math.sqrt(mean_squared_error(testY, yhat_test_torch))
      mae = mean_absolute_error(testY, yhat_test_torch)
      
      print(f'Test RMSE: {rmse:.3f}')
      print(f'Test MAE: {mae:.3f}')
      

        七、保存预测结果

        我们将预测结果保存到Excel文件中,以便后续分析。

        • 使用pandas.DataFrame()创建一个包含真实值和预测值的表格,然后将其保存为Excel文件。
        import pandas as pd
        
        def save_to_excel(origin_y_true, origin_y_pred):
            data_dict = {'真实值': origin_y_true, '预测值': origin_y_pred}
            df = pd.DataFrame(data_dict)
            output_excel_path = "output_predictions.xlsx"
            with pd.ExcelWriter(output_excel_path) as writer:
                df.to_excel(writer)
        
        save_to_excel(testY, yhat_test_torch)
        

          结论:

          1. 本项目基于LSTM模型成功地对电池的健康状态进行了预测,验证了LSTM在时间序列预测中的有效性。

          2. 通过对不同电池单元的SOH进行比较,我们发现不同电池有不同的退化模式。

          3. 在未来的工作中,可以通过加入更多的特征和优化模型结构进一步提高预测准确性。


          http://www.kler.cn/a/512049.html

          相关文章:

        • iOS中的设计模式(三)- 工厂方法
        • STL--list(双向链表)
        • 在 Vue 3 项目中集成和使用 vue3-video-play
        • GraphRAG: Auto Prompt Tuning 实践
        • VUE3 vite下的axios跨域
        • 牛客----mysql
        • 【柱状图】——18
        • 【玩转全栈】----Django制作部门管理页面
        • 基于SpringBoot的智能家居系统的设计与实现(源码+SQL脚本+LW+部署讲解等)
        • XAMPP运行没有创建桌面图标
        • ChatGPT被曝存在爬虫漏洞,OpenAI未公开承认
        • 2025年美国大学生数学建模竞赛赛前准备计划
        • 【技术杂谈】Arcgis调用天地图和卫星影像
        • Spring Web MVC 探秘
        • Nginx location 和 proxy_pass 配置详解
        • 后端开发流程学习笔记
        • Linux 高级路由与流量控制-用 tc qdisc 管理 Linux 网络带宽
        • 【通信协议】TCP通信
        • 记录一个简单小需求,大屏组件的收缩与打开,无脑写法
        • 【日志篇】(7.6) ❀ 01. 在macOS下刷新FortiAnalyzer固件 ❀ FortiAnalyzer 日志分析
        • 【数据结构篇】顺序表 超详细!
        • AAAI2024论文解读|Towards Fairer Centroids in k-means Clustering面向更公平的 k 均值聚类中心
        • 【云原生布道系列】第三篇:“软”饭“硬”吃的计算
        • 在离线无管理员权限的情况下为Linux配置oh-my-zsh(zsh+oh my zsh+powerlevel10k)
        • 2025年免费量化交易软件——PTrade(含开通攻略)
        • .Net Core微服务入门全纪录(六)——EventBus-事件总线