[PYTHON] J'ai essayé de prédire la détérioration de la batterie lithium-ion en utilisant le SDK Qore

introduction

Bonjour, c'est kon2: sunny :: sunny: Je suis un étudiant qui étudie généralement les matériaux négatifs pour les batteries au lithium à l'université.

Les batteries lithium-ion sont largement utilisées dans la vie quotidienne comme les téléphones portables et les véhicules électriques. Ayant récemment remporté le prix Nobel, vous entendez beaucoup votre nom.

Bien que les batteries lithium-ion soient commercialisées depuis plus de 40 ans, elles constituent toujours un domaine de recherche actif et l'utilisation de l'apprentissage automatique a récemment attiré l'attention. Par exemple, développement de nouveaux matériaux d'électrodes et d'électrolytes, optimisation de la configuration de la batterie (épaisseur du film d'électrode, concentration d'électrolyte, additifs ...), prédiction de la durée de vie de la batterie, etc.

Cette fois, j'utiliserai le SDK Qore fourni par Quantum Core Co., Ltd. pendant une durée limitée pour prédire la capacité de décharge des batteries lithium-ion au fil du temps: v :: v :: v:

L'introduction et l'utilisation du SDK Qore sont expliquées dans l'article suivant. Le monde du calcul des réservoirs ~ avec Qore ~ Introduction du SDK Qore et détection de l'arythmie avec Qore

Comme c'était un gros problème, j'ai fait le même apprentissage en utilisant LSTM, qui est une sorte d'apprentissage en profondeur, et j'ai comparé les résultats.

Acquisition des données de charge / décharge

Les données de charge / décharge utilisent les données publiées sur la page suivante par CALCE (Center for Advanced Life Cycle Engineering) de l'Université du Maryland.

https://calce.umd.edu/data#CS2

Dans cette analyse, les données de charge / décharge de la batterie CS2 (CS2-35, CS2-36, CS2-37, CS2-38) sont utilisées. Après le téléchargement au format Zip, le fichier xlsx dans le dossier décompressé correspond aux données de charge / décharge.

Puisqu'elles sont divisées en plusieurs données et que le nombre de cycles est également différent, les données sont correctement formatées et prétraitées.

Je n'expliquerai pas le prétraitement dans cet article, mais je l'ai posté sur GitHub au format Jupyter-Notebook, veuillez donc vous y référer: point_down :: point_down :: point_down:

https://github.com/konkon3249/BatteryDatasetPreprocessing/blob/master/Preprocessing_CS2_35.ipynb

Voici la courbe de charge / décharge de la batterie CS2-35 après prétraitement. Le nombre total de cycles était de 887.

ダウンロード.png

La courbe de charge s'étend en haut à droite et la courbe de décharge s'étend en bas à gauche. Lorsque la couleur passe du bleu au violet, cela indique que le cycle progresse.

Ce que vous voulez savoir ici, c'est la capacité de décharge maximale de chaque cycle de batterie. La figure ci-dessous montre cela par rapport au nombre de cycles.

ダウンロード (1).png

Vous pouvez voir que la capacité de décharge devient de plus en plus petite avec le cycle. Généralement, la durée de vie standard est lorsque la capacité est réduite de 20% (1,1 x 0,8 = 0,88 Ah cette fois), donc cette batterie a une durée de vie utile d'environ 580 cycles.

Analyse de séries chronologiques à l'aide de Qore

Puisque la relation entre la capacité de décharge de la batterie secondaire et le nombre de cycles peut être considérée comme des données chronologiques, des prédictions ont été faites par ARIMA (pas d'apprentissage en profondeur) ou LSTM (apprentissage en profondeur).

Prédiction de la durée de vie utile restante des batteries au lithium-ion basée sur un mélange de décomposition en mode empirique et de modèle ARIMA (Article utilisant ARIMA ) Réseau neuronal récurrent de mémoire à long terme pour la prédiction de la durée de vie utile restante des batteries au lithium-ion (article utilisant LSTM) Assessing the Health of LiFePO4 Traction Batteries through Monotonic Echo State Networks (Article utilisant Echo State Network)

Le dernier article est un article qui utilise Echo State Networks, un type de calcul de réservoir, pour la prédiction. Je ne pensais pas que quiconque le faisait déjà.

Quoi qu'il en soit, on dit que le calcul des réservoirs fourni par Qore SDK est bon pour l'analyse des séries chronologiques, je vais donc l'utiliser pour effectuer une analyse de séries chronologiques similaire.

Cliquez ici pour une liste des données d'entraînement utilisées cette fois.

ダウンロード (2).png

À partir des données de charge / décharge de ces quatre batteries lithium-ion, trois types (# 35, 37, 38) seront utilisés comme données de l'enseignant et un type (# 36) sera utilisé comme données de test pour l'analyse des séries chronologiques.

L'analyse des séries chronologiques est également publiée sur Jupyter-notebook, alors jetez un œil.

https://github.com/konkon3249/BatteryLifePrediction

Voici une brève explication.

Lire des données et créer des données sur les enseignants

Tout d'abord, lisez les données au format csv. Je traiterai également les valeurs manquantes au cas où.

df_35 = pd.read_csv('CS2_35.csv',index_col=0).dropna()
df_36 = pd.read_csv('CS2_36.csv',index_col=0).dropna()
df_37 = pd.read_csv('CS2_37.csv',index_col=0).dropna()
df_38 = pd.read_csv('CS2_38.csv',index_col=0).dropna()

Créez des données d'enseignant pour l'analyse de séries chronologiques à l'aide de la fonction suivante. J'ai également fait référence à l'article ci-dessous qui utilise le SDK Qore: thumbsup :: thumbsup :: thumbsup:

Retourner la tâche à l'aide du SDK Qore

def ConvertData(dataset,t_width):
    
    X_trains = []
    y_trains = []
    
    for df in dataset:
        t_length = len(df)

        train_x = np.arange(t_length)
        capacity = np.array(df['capacity'])
        train_y = capacity
        
        for i in range(t_length - t_width):
            X_trains.append(train_y[i:i + t_width])
            y_trains.append(train_y[i + t_width])

    X_trains = np.array(X_trains)
    y_trains = np.array(y_trains)
    
    return X_trains,y_trains

X_train,y_train = ConvertData([df_35,df_37,df_38],50)
X_test,y_test = ConvertData([df_36],50)

Vérifiez les dimensions des données de l'enseignant obtenues par ce processus.

print(X_train.shape,X_test.shape,y_train.shape,y_test.shape)
>> (2588, 50) (873, 50) (2588,) (873,)

Il y a trop de données à jeter dans l'API, alors réduisez le nombre de données d'enseignant à 500. Les données seront sélectionnées au hasard.

idx = np.arange(0,X_train.shape[0],1)
idx = np.random.permutation(idx)
idx_lim = idx[:500]

X_train = X_train[idx_lim]
y_train = y_train[idx_lim]

Enfin, transformez les données de l'enseignant en dimensions (nombre de données, temps, données réelles). Cependant, la dernière dimension est 1 car elle n'est pas multivariée.

X_train = X_train.reshape([X_train.shape[0], X_train.shape[1], 1])
X_test = X_test.reshape([X_test.shape[0], X_test.shape[1], 1])
print(X_train.shape,X_test.shape,y_train.shape,y_test.shape)
>> (500, 50, 1) (873, 50, 1) (500,) (873,)

Je me sens comme cela.

Apprentissage des données de séries chronologiques à l'aide du SDK Qore

L'apprentissage ne nécessite pas d'optimiser la structure ou les paramètres du réseau, c'est très facile car il est simplement jeté dans l'API.

%%time
client = WebQoreClient(username, password, endpoint=endpoint)
time_ = client.regression_train(X_train, y_train)
print('Time:', time_['train_time'], 's')

>> Time: 1.784491777420044 s
>> Wall time: 2.26 s

De plus, le résultat sera renvoyé immédiatement. C'est tellement rapide que je m'inquiète si j'apprends vraiment.

Allons vérifier. Tout d'abord, à partir des données d'entraînement.

#inférence
res = client.regression_predict(X_train)

#terrain
fig=plt.figure(figsize=(12, 4),dpi=150)
plt.plot(res['Y'],alpha=0.7,label='Prediction')
plt.plot(y_train,alpha=0.7,label='True')
plt.legend(loc='upper right',fontsize=12)

ダウンロード (6).png

En regardant les valeurs prédites des données d'entraînement, il semble que l'apprentissage se fasse correctement. Ensuite, le résultat de prédiction de la capacité de décharge de la batterie (# 36) pour 300 à 800 cycles, qui sont les données de test, est affiché.

ダウンロード (7).png

Le bleu est la valeur prédite et l'orange est la valeur expérimentale. N'est-ce pas assez bon à prévoir?

J'ai utilisé scikit-learn pour afficher l'erreur (MSE) (pour une comparaison ultérieure avec LSTM).

from sklearn.metrics import mean_squared_error
print(mean_squared_error(y_test[300:800], res['Y']))
>> 0.00025365167122575003

Maintenant, prédisons en fait la capacité de décharge de 500 à 550 cycles comme suit.


#Prévision future de la capacité de décharge
initial = X_test[500]
results = []
for i in tqdm(range(50)):
    if(i == 0):
        res = client.regression_predict([initial])['Y']
        results.append(res[0])
        time.sleep(1)
    else:
        initial = np.vstack((initial[1:],np.array(res)))
        res = client.regression_predict([initial])['Y']
        results.append(res[0])
        time.sleep(1)

#terrain
fig=plt.figure(figsize=(12,4),dpi=150)
plt.plot(np.linspace(501,550,50),results,'o-',ms=4,lw=1,label='predict')
plt.plot(np.linspace(401,550,150),y_test[400:550],'o-',lw=1,ms=4,label='true')
plt.legend(loc='upper right',fontsize=12)
plt.xlabel('Number of Cycle',fontsize=13)
plt.ylabel('Discharge Capacity (Ah)',fontsize=13)

Le résultat est le suivant.

ダウンロード (18).png

Je peux le prédire avec un bon feeling!

Apprendre avec LSTM

Comme c'est un gros problème, je vais le comparer avec LSTM. Commencez par changer la dimension des données de réponse correctes de (N,) à (N, 1).

X_train = X_train.reshape([X_train.shape[0], X_train.shape[1], 1])
X_test = X_test.reshape([X_test.shape[0], X_test.shape[1], 1])
y_train = y_train.reshape([y_train.shape[0], 1])
y_test = y_test.reshape([y_test.shape[0], 1])
print(X_train.shape,X_test.shape,y_train.shape,y_test.shape)
>> (500, 50, 1) (873, 50, 1) (500, 1) (873, 1)

Les paramètres de LSTM sont les suivants.

hidden layer:3 optimizer:rmsprop loss function:mean squared error batch size:50 epochs:100

Construire et apprendre le modèle, c'est comme ça.

#Construction du modèle LSTM
length_of_sequence = X_train.shape[1]
in_out_neurons = 1
n_hidden = 3

model = Sequential()
model.add(LSTM(n_hidden, batch_input_shape=(None, length_of_sequence, in_out_neurons), 
               return_sequences=False))
model.add(Dense(1))
model.add(Activation("linear"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")

#Apprentissage de modèle
%%time
early_stopping = EarlyStopping(monitor='val_loss', mode='auto', patience=20)
history = model.fit(X_train, y_train,
          batch_size=50,
          epochs=100,
          validation_split=0.1,
          callbacks=[early_stopping,PlotLossesKeras()]
          )

En utilisant un GPU (GTX1070), le temps de calcul était de 1 min 27 s. La transition de la perte pendant l'apprentissage est la suivante.

ダウンロード (15).png

Cliquez ici pour le résultat de la prédiction de la capacité de décharge des données de test (CS2-36) à l'aide de ce modèle comme dans le cas de Qore.

ダウンロード (17).png

Vous pouvez prédire de la même manière. Le MSE est 0,00021017. Maintenant, comme auparavant, prévoyez la capacité de décharge de 500 à 550 cycles comme suit.

initial = X_test[500]
results = []
for i in tqdm(range(50)):
    if(i == 0):
        initial = initial.reshape(1,50,1)
        res = model.predict(initial)
        results.append(res[0][0])
    else:
        initial = initial.reshape(50,1)
        initial = np.vstack((initial[1:],np.array(res)))
        initial = initial.reshape(1,50,1)
        res = model.predict([initial])
        results.append(res[0][0])

ダウンロード (16).png

Il semble que cela ait été fait, mais il semble que ce soit mieux prévisible lors de l'utilisation de Qore.

Enfin, voici un diagramme illustrant les résultats de la prévision des séries chronologiques avec le cas Qore.

ダウンロード (19).png

Résumé

Dans cet article, nous avons fait une prédiction chronologique du processus de détérioration (diminution de la capacité de décharge) d'une batterie lithium-ion à l'aide du SDK Qore, et l'avons comparée au cas de l'utilisation du LSTM couramment utilisé.

En conséquence, l'erreur (mse) des données de test et le temps de calcul sont les suivants.

QoreSDK LSTM
MSE 2.5365e-4 2.1017e-4
Temps d'étude 1.78 s 87 s

L'erreur est légèrement plus petite dans LSTM, mais le temps d'apprentissage est extrêmement plus rapide dans Qore. C'est incroyable que vous puissiez apprendre jusqu'à présent sans ajuster les paramètres d'apprentissage.

finalement

La prévision de détérioration de la batterie faite cette fois est encore insuffisante. Cela semble être dû au fait que seule la capacité de décharge est utilisée pour la prévision des séries chronologiques.

En fait, il existe de nombreux autres paramètres liés à la capacité de la batterie. Par exemple, les données suivantes peuvent être obtenues à partir de cet ensemble de données.

ダウンロード (20).png

En haut à gauche, la relation entre la capacité de décharge, la résistance interne, le temps de charge à courant constant, le temps de charge à tension constante et le cycle de charge / décharge. Si vous effectuez une analyse de séries chronologiques à plusieurs variables, y compris les données ici, vous devriez être en mesure de prédire la détérioration avec plus de précision. (Je n'étais pas fort cette fois ...)

Quantum Core, merci d'avoir fourni une telle API cette fois. L'analyse des séries chronologiques était un amateur, mais c'était très intéressant! Pour un temps limité, si vous voulez jouer: point_down :: point_down :: point_down:

Apprentissage automatique et technologies appliquées autres que l'apprentissage en profondeur par QuantumCore Advent Calendar 2019

Eh bien alors ~~.

Recommended Posts

J'ai essayé de prédire la détérioration de la batterie lithium-ion en utilisant le SDK Qore
J'ai essayé de prédire la victoire ou la défaite de la Premier League en utilisant le SDK Qore
Je veux prédire le succès des joueurs NBA utilisant le SDK Qore
J'ai essayé l'histoire courante de l'utilisation du Deep Learning pour prédire la moyenne Nikkei
J'ai essayé d'obtenir l'index de la liste en utilisant la fonction énumérer
J'ai essayé de prédire l'infection d'une nouvelle pneumonie en utilisant le modèle SIR: ☓ Wuhan edition ○ Hubei province edition
Utilisez le SDK Qore pour prédire les augmentations et les baisses de prix BTC
J'ai essayé de prédire les hauts et les bas du cours de clôture du cours de l'action de Guru Navi en utilisant TensorFlow (progression)
J'ai essayé de transformer l'image du visage en utilisant sparse_image_warp de TensorFlow Addons
J'ai essayé d'obtenir les résultats de Hachinai en utilisant le traitement d'image
J'ai essayé d'estimer la similitude de l'intention de la question en utilisant Doc2Vec de gensim
J'ai essayé d'extraire et d'illustrer l'étape de l'histoire à l'aide de COTOHA
En utilisant COTOHA, j'ai essayé de suivre le cours émotionnel de la course aux meros.
J'ai essayé de prédire le comportement du nouveau virus corona avec le modèle SEIR.
J'ai essayé de corriger la forme trapézoïdale de l'image
J'ai essayé d'utiliser le filtre d'image d'OpenCV
J'ai essayé de vectoriser les paroles de Hinatazaka 46!
J'ai essayé de notifier la mise à jour de "Hameln" en utilisant "Beautiful Soup" et "IFTTT"
[Python] J'ai essayé de juger l'image du membre du groupe d'idols en utilisant Keras
J'ai essayé de prédire la présence ou l'absence de neige par apprentissage automatique.
J'ai essayé de résumer la forme de base de GPLVM
J'ai essayé de prédire le match de la J League (analyse des données)
J'ai essayé d'approcher la fonction sin en utilisant le chainer
J'ai essayé d'utiliser l'API de Sakenowa Data Project
J'ai essayé de visualiser les informations spacha de VTuber
J'ai essayé d'effacer la partie négative de Meros
J'ai essayé d'identifier la langue en utilisant CNN + Melspectogram
J'ai essayé de compléter le graphe de connaissances en utilisant OpenKE
J'ai essayé de classer les voix des acteurs de la voix
J'ai essayé de compresser l'image en utilisant l'apprentissage automatique
J'ai essayé de résumer les opérations de chaîne de Python
J'ai essayé de notifier la mise à jour de "Devenir romancier" en utilisant "IFTTT" et "Devenir un romancier API"
Python pratique 100 coups J'ai essayé de visualiser l'arbre de décision du chapitre 5 en utilisant graphviz
J'ai essayé d'extraire le texte du fichier image en utilisant Tesseract du moteur OCR
J'ai essayé de trouver l'entropie de l'image avec python
[Courses de chevaux] J'ai essayé de quantifier la force du cheval de course
J'ai essayé d'obtenir les informations de localisation du bus Odakyu
J'ai essayé de trouver la moyenne de plusieurs colonnes avec TensorFlow
J'ai essayé de refactoriser le modèle CNN de TensorFlow en utilisant TF-Slim
J'ai essayé de simuler l'optimisation des publicités à l'aide de l'algorithme Bandit
J'ai essayé la reconnaissance faciale du problème du rire en utilisant Keras.
[Python] J'ai essayé de visualiser la relation de suivi de Twitter
[TF] J'ai essayé de visualiser le résultat de l'apprentissage en utilisant Tensorboard
[Apprentissage automatique] J'ai essayé de résumer la théorie d'Adaboost
[Python] J'ai essayé de collecter des données en utilisant l'API de wikipedia
J'ai essayé de combattre le minimum local de la fonction Goldstein-Price
J'ai essayé d'approcher la fonction sin en utilisant chainer (re-challenge)
J'ai essayé de sortir le journal d'accès au serveur en utilisant Node.js
J'ai essayé de comparer la précision des modèles d'apprentissage automatique en utilisant kaggle comme thème.
J'ai essayé de prédire le genre de musique à partir du titre de la chanson sur le réseau neuronal récurrent
J'ai essayé d'automatiser la construction d'un environnement pratique à l'aide de l'API SoftLayer d'IBM Cloud
J'ai essayé de prédire les ventes de logiciels de jeux avec VARISTA en me référant à l'article du Codexa
J'ai essayé d'utiliser GrabCut d'OpenCV
J'ai essayé de déplacer le ballon
J'ai essayé d'utiliser l'API checkio