I am trying to develop a neural network that can estimate the stress concentration factor Kt of V-notched specimens based on scans from the notch profile. The scans have been interpolated to create regions of equidistant points, as I want to use a 1D CNN that can interpret the height values of the profile. I have approximately 150 samples. The mean Kt value of the samples is 2.27 with a std of 0.17.
An example of a array that is used as input, before normalization:
[4.7605 4.60461111 4.44872222 4.29283333 4.13694444 3.98105556
3.82516667 3.66927778 3.51338889 3.3575 3.3575 3.35472643
3.35195286 3.34917929 3.34635815 3.34346399 3.34056983 3.33767567
3.3351553 3.33265909 3.33016288 3.32763043 3.32502569 3.32242095
3.31981621 3.31755051 3.31533165 3.31311279 3.31102569 3.3092892
3.3075527 3.30581621 3.30391204 3.30197054 3.30002904 3.2985
3.2985 3.2985 3.2985 3.29807997 3.29752525 3.29697054
3.29641217 3.29583333 3.2952545 3.29467567 3.29353409 3.29214731
3.29076052 3.28931555 3.28728964 3.28526372 3.28323781 3.28126557
3.27932407 3.27738258 3.27544108 3.27349958 3.27155808 3.26961658
3.26763922 3.26561331 3.2635874 3.26156148 3.26123106 3.2609537
3.26067635 3.26081621 3.26168445 3.2625527 3.26342095 3.26551684
3.26773569 3.26995455 3.27229051 3.27489526 3.2775 3.28010474
3.28238215 3.28460101 3.28681987 3.28920268 3.29209684 3.294991
3.29788516 3.30002904 3.30197054 3.30391204 3.30592161 3.30823693
3.31055226 3.31286759 3.31531439 3.31781061 3.32030682 3.32281621
3.32542095 3.32802569 3.33063043 3.33316288 3.33565909 3.3381553
3.34067567 3.34356983 3.34646399 3.34935815 3.35201136 3.35450758
3.35700379 3.3595 3.3595 3.51516667 3.67083333 3.8265
3.98216667 4.13783333 4.2935 4.44916667 4.60483333 4.7605 ]
I performed a grid search to optimize my model, but I am not satisfied with the accuracy. Adding additional Convolutional layers didn’t affect the accuracy much, neither did including an LSTM layer. I also tried different scalers. The model always returns a Kt value of 2.11XXXXX, with only the last digits changing. The RMSE is equal to 0.17 and the MAE is equal to 0.13.
def preprocessing(specimens_list, scaler=Normalizer):
# fill data lists
X = []
y = []
for specimen in specimens_list:
scan = list(specimen.KeyenceScansValues)[0]
x_data, y_data = scan.format_for_ML(NUM1, NUM2) # creates the equidistant points
X.append(y_data) # only use height (y) values
y.append(specimen.Kt)
# Calculate the mean of y_train (ignoring NaN values)
mean_y = np.nanmean(y)
# Replace NaN values in y_train with the mean
y = np.where(np.isnan(y), mean_y, y)
# scaling
scaler_x = scaler().fit(X)
X_scaled = scaler_x.transform(X) # Normalizer
return np.asarray(X_scaled), np.asarray(y)
def create_model(filter1:int=32, filter2:int=64, kernel_size1:int=5, kernel_size2:int=5, learning_rate:float=0.001):
model = models.Sequential([
layers.Reshape((NUM, 1), input_shape=(NUM,)),
layers.Conv1D(filters=filter1, kernel_size=kernel_size1, activation='relu', padding='same'),
layers.MaxPooling1D(pool_size=2, strides=2),
layers.Conv1D(filter2, kernel_size=kernel_size2, activation='relu', padding='same'),
layers.MaxPooling1D(pool_size=2, strides=2),
#layers.LSTM(units=128),
layers.Flatten(),
layers.Dense(64, activation='relu'),
layers.Dense(1) # Output layer for regression
])
optimizer = keras.optimizers.Adam(learning_rate = learning_rate)
model.compile(optimizer=optimizer,
loss = keras.losses.MeanSquaredError(),
metrics = [keras.metrics.RootMeanSquaredError(),
keras.metrics.MeanSquaredLogarithmicError(),
keras.metrics.MeanAbsoluteError()])
return model
def training(model, x_train, y_train, x_test, y_test, batch_size=5, epochs=10):
### Train model ###
#model.save_weights(checkpoint_path.format(epoch=0))
train_history = model.fit(x_train, y_train,
epochs = epochs,
batch_size = batch_size,
#callbacks = [cp_callback],
validation_data = (x_test, y_test),
verbose = 0)
return train_history
def evaluate(model, train_history, x_train, y_train, x_test, y_test):
### Track performance ###
training_performance = model.evaluate(x_train, y_train, verbose = 0)
validation_performance = model.evaluate(x_test, y_test, verbose = 0)
#model.summary()
print(f'Training performance: RMSE = {training_performance[1]:.2f}, MSLE = {training_performance[2]:.2f}, MAE = {training_performance[3]:.2f}')
print(f'Validation performance: RMSE = {validation_performance[1]:.2f}, MSLE = {validation_performance[2]:.2f}, MAE = {validation_performance[3]:.2f}')
return [training_performance[1], training_performance[2], training_performance[3], validation_performance[1], validation_performance[2], validation_performance[3]]
Seppe Vanheulenberghe is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.