I have two datasets: force plate data and plantar pressure data. The force plate data consists of 6 data points, while the plantar pressure data consists of 90 data points. Both datasets have a sampling rate of 50 data points per second. Therefore, within one second, the force plate can generate a data array of 50x6, and the plantar pressure data can generate 50x90 data points. In this project, I will collect data for 5 minutes. So, the total data of force plate data is (15000,6), and the total data of plantar pressure data is (15000,90). I am using CNN to develop a regression model to predict force plate data using plantar pressure data. Before training, I preprocess the two datasets using a min-max scaler.

below is format of the plantar pressure data: enter image description here

below is the format of the force plate data:

enter image description here The training results I obtained are quite good. However, for some reason, the model has difficulty predicting 0.

plot of the model loss:

enter image description here

history of training process:

enter image description here

below is for comparing real data and prediction results: enter image description here

If you look at the comparison table between the real data and the predicted results above, you can see that the predicted values for FzPred, MxPred, MyPred, and MzPred cannot predict the value of 0, even though the real data has a value of 0. How can we overcome this issue so that the model can predict the value of 0 accurately?

Below is the full code of my project:

## Load Data
Insole = pd.read_csv('1225_Rwalk10min1_list.txt', header=None, low_memory=False)
SIData =  np.array(Insole)

df = pd.read_csv('1225_Rwalk10min.csv', low_memory=False)
columns = ['Fx','Fy','Fz','Mx','My','Mz']
selected_df = df[columns]
FPDatas = selected_df[:15000]

label = pd.read_csv('label.txt', header=None, low_memory=False)
labelData =  np.array(label)

SmartInsole = np.array(SIData[:15000]).astype('int')
FPData = np.array(FPDatas).astype('int')
Label = np.array(labelData[:15000]).astype('int')

SIlabeled = np.concatenate((Label, SmartInsole), axis=1)
SIlabeled = np.array(SIlabeled).astype('int')
## End Load Data

# Data Normalization
SImin = SIlabeled.min()
SImax = SIlabeled.max()
SIscaled = (SIlabeled - SImin) / ( SImax - SImin )

FPmax = []
FPmin = []
FPscaled = []
# LogFP = np.log10(newFPData)

for i in range(0,6):
    minFP = FPData[:,i].min()
    maxFP = FPData[:,i].max()

FPmin = np.array(FPmin)
FPmax = np.array(FPmax)

for i in range(0,6):
  scale = (FPData[:,i] - FPmin[i]) / ( FPmax[i] - FPmin[i] )
FPscaled = np.array(FPscaled)
FPscaled = FPscaled.transpose()
#End Data Normalization

#Spliting Data
sample_size = SIscaled.shape[0] # number of samples in train set
time_steps  = SIscaled.shape[1] # number of features in train set
input_dimension = 1               # each feature is represented by 1 number

train_data_reshaped = SIscaled.reshape(sample_size,time_steps,input_dimension)

X_train, X_test, y_train, y_test = train_test_split(train_data_reshaped, FPscaled, test_size=0.2, random_state=42)
#End Spliting Data

#Model Structure
model = Sequential(name="model_conv1D")

n_timesteps = train_data_reshaped.shape[1] #13
n_features  = train_data_reshaped.shape[2] #1 

model.add(Reshape((90, 1, 1), input_shape=(n_timesteps, n_features))) # add missing dimension

model.add(Conv2D(64, kernel_size=(5, 5), activation='relu',padding='same'))
model.add(Conv2D(128, kernel_size=(5, 5), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
model.add(Conv2D(256, kernel_size=(5, 5), activation='relu', padding='same'))
model.add(MaxPooling2D(pool_size=(2, 2), padding='same'))
model.add(Dense(512, activation='relu'))
model.add(Dense(6, activation='linear'))

model.compile(loss='mse', optimizer=Adam(learning_rate=0.0009), metrics=['mse'])

history = model.fit(X_train, y_train, batch_size=64, epochs=200,
                    validation_data=(X_test, y_test), verbose=2)
#End Model Structure

#Evaluate Model
model.evaluate(train_data_reshaped, FPscaled)
FPpred = model.predict(train_data_reshaped

y_inverse = []
y_pred_inverse = []

for i in range(0,6):
  Y_inver =  FPscaled[0:15000, i]*( FPmax[i] - FPmin[i] )+FPmin[i]
  Pred_inver = FPpred[0:15000, i]*( FPmax[i] - FPmin[i] )+FPmin[i]
y_inverse = np.array(y_inverse)
y_inverse = y_inverse.transpose()
y_pred_inverse = np.array(y_pred_inverse)
y_pred_inverse = y_pred_inverse.transpose()
#End ScaleBack
  • $\begingroup$ You can try mae (mean absolute error) as loss function instead of mse (mean squared error). MAE penalizes more the error values that are lower than 1, because when you square a number less than 1, the result is lower than the number itself. $\endgroup$
    – noe
    Mar 3, 2023 at 15:13
  • $\begingroup$ I've try using mae also, but it still same. $\endgroup$ Mar 3, 2023 at 15:51


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.