'model.fit in a for loop, for K-fold cross validation
I am trying to code a K-fold cross validation with LSTM architecture.
But I got an this error (edit):
Traceback (most recent call last):
File "/Users/me/Desktop/dynamicsoundtreatments/DST-features-RNN.py", line 58, in <module>
model.fit(training_data, training_label, epochs=100, batch_size=nbr_de_son)
File "/Users/me/miniforge3/lib/python3.9/site-packages/keras/utils/traceback_utils.py", line 67, in error_handler
raise e.with_traceback(filtered_tb) from None
File "/Users/me/miniforge3/lib/python3.9/site-packages/keras/engine/training.py", line 1395, in fit
raise ValueError('Unexpected result of `train_function` '
ValueError: Unexpected result of `train_function` (Empty logs). Please use `Model.compile(..., run_eagerly=True)`, or `tf.config.run_functions_eagerly(True)` for more information of where went wrong, or file a issue/bug to `tf.keras`.
I tried to add run_eagerly=True
but got the same error again.
I tried few alternatives such as def train(training_data, training_label): model.fit(training_data, training_label, epochs=100, batch_size=nbr_de_son)
outside of the for loop. Got same error.
I was wondering if I should use Functional API, but I am very new to datascience. I really don't why I got this error. Thanks for your help.
nbr_anal = int(6)
nbr_de_son = int(samples.shape[0]/nbr_anal)
sequence = int(samples.shape[1])
input_shape=(nbr_anal, sequence)
# ------------------------------------------------------------------------
# PREPROCESSING
# batch size, sequence length, features
samples = samples.reshape(nbr_de_son, nbr_anal, sequence)
labels_extrait = np.argmax(labels_extrait, axis=1)
print(labels_extrait.shape)
# ------------------------------------------------------------------------
# K-Fold
k = 4
num_validation_samples = len(samples) // k
num_validation_labels = len(labels_extrait) // k
validation_scores = []
model = Sequential()
model.add(LSTM(sequence,input_shape=input_shape))
model.add(Dropout(0.3))
model.add(Dense(8, activation='softmax'))
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics='sparse_categorical_accuracy', run_eagerly=True)
for fold in range(k):
rng_state = np.random.get_state()
np.random.shuffle(samples)
np.random.set_state(rng_state)
np.random.shuffle(labels_extrait)
validation_data = samples[num_validation_samples * fold:num_validation_samples * (fold + 1)]
print(validation_data.shape)
validation_label = labels_extrait[num_validation_labels * fold:num_validation_labels * (fold + 1)]
print(validation_label.shape)
training_data = samples[:num_validation_samples * (fold + 1)] + samples[num_validation_samples * (fold)]
training_label = labels_extrait[:num_validation_labels * (fold + 1)] + labels_extrait[num_validation_labels * (fold)]
model.fit(training_data, training_label, epochs=100, batch_size=nbr_de_son)
validation_score = evaluate(validation_data, validation_label)
validation_scores.append(validation_score)
validation_score = np.average(validation_scores)
print(validation_score)
Solution 1:[1]
You can use StratifiedKFold
from the sklearn package to do the cross validation. It is much clearer and is the standard way to do it. You should also reset the model weights at each fold before fitting the model, otherwise you will start with the weights initialized in the previous call of the fit method,
The modified code :
from sklearn.model_selection import StratifiedKFold
# K-Fold cross validation
k = 4
skf = StratifiedKFold(n_splits=k)
validation_scores = []
# store initial model's weights
weights_init = model.get_weights()
for train_index, test_index in skf.split(samples, labels_extrait):
training_data = samples[train_index]
training_label = labels_extrait[train_index]
validation_data = samples[test_index]
validation_label = labels_extrait[test_index]
# reset mdoel's weights
model.set_weights(weights_init)
# fit
model.fit(training_data, training_label, epochs=100, batch_size=nbr_de_son)
validation_score = model.evaluate(validation_data, validation_label)
validation_scores.append(validation_score)
validation_score = np.average(validation_scores)
print(validation_score)
I don't know exactly where your error comes from, but the above code works
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |