lululxvi/deepxde

ValueError: all the input array dimensions except for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 4 and the array at index 1 has size 1

CarecrYang opened this issue · 0 comments

I am working on a project that involves predicting battery temperature using time, current, voltage, and ambient temperature as inputs. I have collected experimental data for these parameters. Currently, I am attempting to use Physics-Informed Neural Networks (PINN) to train the model and incorporate the physics equations. However, when I ran the code, I encountered the following errors:

File C:\ProgramData\anaconda3\envs\BatteryAI\lib\site-packages\spyder_kernels\py3compat.py:356 in compat_exec
exec(code, globals, locals)

File d:\changrong yang\python project\spyder\project1\batterypinn_v1.py:79
data = dde.data.TimePDE(

File C:\ProgramData\anaconda3\envs\BatteryAI\lib\site-packages\deepxde\data\pde.py:322 in init
super().init(

File C:\ProgramData\anaconda3\envs\BatteryAI\lib\site-packages\deepxde\data\pde.py:127 in init
self.train_next_batch()

File C:\ProgramData\anaconda3\envs\BatteryAI\lib\site-packages\deepxde\utils\internal.py:38 in wrapper
return func(self, *args, **kwargs)

File C:\ProgramData\anaconda3\envs\BatteryAI\lib\site-packages\deepxde\data\pde.py:175 in train_next_batch
self.train_x_all = self.train_points()

File C:\ProgramData\anaconda3\envs\BatteryAI\lib\site-packages\deepxde\utils\internal.py:38 in wrapper
return func(self, *args, **kwargs)

File C:\ProgramData\anaconda3\envs\BatteryAI\lib\site-packages\deepxde\data\pde.py:338 in train_points
X = super().train_points()

File C:\ProgramData\anaconda3\envs\BatteryAI\lib\site-packages\deepxde\utils\internal.py:38 in wrapper
return func(self, *args, **kwargs)

File C:\ProgramData\anaconda3\envs\BatteryAI\lib\site-packages\deepxde\data\pde.py:270 in train_points
X = np.hstack((self.anchors, X))

File <array_function internals>:200 in vstack

File C:\ProgramData\anaconda3\envs\BatteryAI\lib\site-packages\numpy\core\shape_base.py:296 in vstack
return _nx.concatenate(arrs, 0, dtype=dtype, casting=casting)

File <array_function internals>:200 in concatenate

ValueError: all the input array dimensions except for the concatenation axis must match exactly, but along dimension 1, the array at index 0 has size 4 and the array at index 1 has size 1

It has been bothering me for quite some time, and I would greatly appreciate it if someone could help me resolve this issue. Here is my code:

import deepxde as dde
from deepxde.backend import tf
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scipy.io
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

#Define trainable parameters
C1 = tf.Variable(1.0, name='C1', trainable=True)
C2 = tf.Variable(1.0, name='C2', trainable=True)
Vocv = 1.0

Define the ODE

def coupled_thermal_electrical_ode(x, y):
"""PDE for the coupled thermal-electrical model."""
# Extracting time, I(t), and T_amb(t) from the input x
# t, It, T_amb = x[:, 0:1], x[:, 1:2], x[:, 2:3]
print("Entering into PDE")
It, T_amb, V= x[:, 1:2], x[:, 2:3], x[:, 3:4]
T = y[:, 0:1] # Output
# dy/dt
dT_dt = dde.grad.jacobian(y, x, i=0, j=0)

# Equation residual
residual = dT_dt - C1*(V - Vocv) * It - C2* (T - T_amb)
return residual

Load data from CSV change your file name.

file_path = r'1c 15du new.xlsx'
df = pd.read_excel(file_path)
data = df.to_numpy()
X_data, y_data = data[:, :-1], data[:, -1:] # Assign t I Tamb, V and t

Normalize the data

scaler_X = StandardScaler().fit(X_data)
scaler_y = StandardScaler().fit(y_data.reshape(-1, 1))
X_data_normalized = scaler_X.transform(X_data)
y_data_normalized = scaler_y.transform(y_data.reshape(-1, 1))

Split the data into training and testing sets

X_train, X_test, y_train, y_test = train_test_split(
X_data_normalized, y_data_normalized, test_size=0.2, random_state=42)

Print the size of these parameters

print(X_train.shape, y_train.shape, X_test.shape, y_test.shape)
print("Data extraction ok !")

Return the input array (X) and the corresponding output (Tt)

Define the PDE, computational domain, initial condition, and neural network as before

geom = dde.geometry.TimeDomain(0, 1)

Data for the PDE

data = dde.data.TimePDE(
geom,
coupled_thermal_electrical_ode,
[],
num_domain=500,
num_test=100,
train_distribution="uniform",
anchors = X_train
#anchors=gen_traindata()[0],
)

Neural network

layer_size = [4] + [20]*3 + [2] # Adjusted for 3 input dimensions (t, I(t), T_amb)
activation = "tanh"
initializer = "Glorot uniform"
net = dde.nn.FNN(layer_size, activation, initializer)

Model

model = dde.Model(data, net)

Compile and train

model.compile("adam", lr=0.001)

Add callbacks for saving the best model and tracking the learning of C1 and C2

ckpt_path = "./model_ckpts/model"
model_checkpoint_callback = dde.callbacks.ModelCheckpoint(ckpt_path, verbose=1, save_better_only=True, period=1000)
variable = dde.callbacks.VariableValue([C1, C2], period=100, filename="variables.dat")

model.train(epochs=10000)

losshistory, train_state = model.train(iterations=42000, display_every=100, callbacks=[model_checkpoint_callback, variable])

Post-training: Retrieve the learned values of C1 and C2

learned_C1, learned_C2 = model.sess.run([C1, C2])
print(f"Learned C1: {learned_C1}, Learned C2: {learned_C2}")

Save the model and training results

dde.saveplot(losshistory, train_state, issave=True, isplot=True)

X, y_true = gen_traindata()

Predict on test data

X_test = scaler_X.inverse_transform(X_test)
y_pred = model.predict(X_test)

Inverse transform the predicted data to the original scale

y_pred_inverse = scaler_y.inverse_transform(y_pred)
y_test_inverse = scaler_y.inverse_transform(y_test)

Evaluate the model on test data

mse = tf.keras.losses.MeanSquaredError()
print(f"MSE on test data: {mse(y_test_inverse, y_pred_inverse).numpy()}")

plt.figure()
plt.plot(y_test_inverse, label="True")
plt.plot(y_pred_inverse, label="Predicted")
plt.xlabel("Sample")
plt.ylabel("Temperature")
plt.title("True vs Predicted Temperature")
plt.legend()
plt.show()