지난 전기화학임피던스 분광법(EIS) 시리즈동안 EIS 검사를통해 어떠한 원리로 배터리의 내부 파라미터를 추출해 내는 지 설명하였다.
이번 포스트에서는 해당 배터리 파라미터들을 통해 어떻게 배터리 진단(잔존수명:SOH, 잔존용량:SOC)을 할 수 있는 지에 관한 논문을 소개하고 사내 EIS 검사데이터를 통해 논문구현을 해보겠다.
우선 이전에 EIS에서 얻은 파라미터들을 SOC,SOH와 연결시키는 작업은 주로 SOC에대한 다항식으로 곡선맞춤 하는 방식으로 연구가 되어왔었다.
출처) Y. Xi, Y. Liu, Y. Xing, M. Dong and R. Chen, "SOC estimation for lithium-ion batteries based on electrochemical impedance spectroscopy and equivalent circuit model," 22nd International Symposium on High Voltage Engineering (ISH 2021), Hybrid Conference, Xi'an, China, 2021, pp. 2225-2229, doi: 10.1049/icp.2022.0209.
그러나 대략 18년도 이후부터 딥러닝이 각광받기 시작하면서 SOC, SOH분야에서도 이를 이용한 연구가 상당히 많이 진행되었다. 이번에 리뷰할 논문은 다음과 같다.
M. Messing, T. Shoa, R. Ahmed and S. Habibi, "Battery SoC Estimation from EIS using Neural Nets," 2020 IEEE Transportation Electrification Conference & Expo (ITEC), Chicago, IL, USA, 2020, pp. 588-593, doi: 10.1109/ITEC48692.2020.9161523.
간단히 요약하자면, 선정한 배터리 모델을 통해 EIS피팅으로 배터리 파라미터를 구하고, 파라미터들을 INPUT 값으로 넣은 DNN모델과 EIS 측정결과만을 INPUT값으로 넣은 DNN모델이 각각의 SOC구간에서 얼마나 정확히 추정하는 지 비교하는 내용이다.
우선 여러 soc, soh별로 eis를 진행한다. 데이터는 많을수록 좋다.
그 다음으로 배터리 모델을 선정한다. 보통 연구용 모델에서는 1,2차 테브난 등가회로정도로 선정하고 마는데 해당 논문에서는 파라미터가 무려10개나 되는 매우 정교한 모델을 선정하였다.
(물론 input 파라미터가 많아야 dnn학습이 디테일하게 이루어지는 것도 맞지만 아무래도 저자는 nyquist plot fitting에 자신이 있었나보다..)
파라미터 추출은 지난 포스트에서 구현했던것처럼 피팅을 통해 이루어진다.
해당 모델 내에서 가장 측정데이터와 맞는 파라미터 값들을 찾아내면 된다.(비선형곡선피팅)
그렇게 10개의 배터리 파라미터들을 얻었다면 이를 dnn에 학습시킨다.
a)는 25개의 주파수로 측정한 eis데이터를 그대로 학습시키는 것이고, b)는 해당 데이터를 바탕으로 배터리 파라미터 추출을 거친 후 학습을 시킨것이다. 이제 이 두 모델의 정확성을 검증하면 된다.
a)모델에서는 180개노드 은닉층3층, b)모델에서는 70노드 은닉층1층을 통해 soc를 추정해냈는데 당연히 가장 정확한 모델을 사용한 것이다.
아래 표를 통해 하이퍼파라미터 튜닝이 진행되었음을 알 수 있다.
soc구간별로 eis데이터가 나을 때도 있고, 파라미터 추출을 거친 데이터가 나을 떄도 있는데 도찐 개찐인거 같다..
사내 db에서 다음 데이터를 활용했다.
1,eis검사결과 데이터(voltage, temperature, rs, rp)
2.배터리 상태 데이터(soc,soh)
둘을 조인하여 학습 데이터셋을 만들고 csv로 변환하여 python으로 작업했다.(맨날 하는거죠)
모델은 다음과 같이 짰고
측정데이터가 많이 없어서(25행..)배치사이즈는 풀로 했고
200에포크정도 학습시켰더니 mse가 대충 10내외까지 떨어졌었다(근데 오버피팅일듯)
무튼 이렇게 간단한 구현 끗!
#%%
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow import keras
from sklearn.preprocessing import StandardScaler
#%%
df=pd.read_csv('deepeis.csv')
df=df[['insp_sq','insp_date','soc_value','rs','rp','temperature','voltage']]
# %%
input=df[['rs','rp','voltage']]
target=df['soc_value']
# %%
input=np.array(input)
target=np.array(target)
input=input[3:]
target=target[3:]
# %%
model = keras.Sequential()
model.add(keras.layers.Dense(100, activation='relu', input_shape=(3,),name='hid1'))
model.add(keras.layers.Dense(100, activation='relu',name='hid2'))
model.add(keras.layers.Dense(1, activation='linear',name='hid3'))
model.summary()
model.compile(loss='mse', metrics=['accuracy'])
history=model.fit(input, target,batch_size=25 ,epochs=200)
# %%
model.predict([[input]])
plt.plot(history.history['loss'])
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()
# %%
# %%