Reputation: 1087
Please see gist here for the full code. In this question I've pasted what I regard the important part of the code at the bottom.
First I generate a dataset as shown in [2], which consists of 2 features (x
and y
) and 3 labels (grey
, blue
and orange
). Then I make 4 keras sequential models with identical layer structure, optimizer, loss function, etc. Lastly, I call fit
on each model and plot the resulting metrics shown in [3]. As you can see the models all perform differently and I'm wondering why? I've locked the random seed value so each time I run this script I get the exact same result.
In this example the models have identical structures, so I would expect the metric plots to be identical. Eventually I would like to vary the number of layers, layer size, loss function, etc. between the models to see its effects, but that does not seem feasible in this setup. Am I approaching this incorrectly?
An interesting thing to note is that by setting the batch_size
to 32 this effect is not as prominent, but it is still present and reproducible (See [4]).
# ---- MAKE MODELS ---- #
NUMBER_OF_MODELS = 4
models = []
for i in range(NUMBER_OF_MODELS):
model = keras.models.Sequential(name=f'{i}')
model.add(keras.layers.Dense(8, activation='relu', input_shape=df_train['features'].values.shape[-1:]))
model.add(keras.layers.Dense(3, activation='softmax'))
model.compile(optimizer=keras.optimizers.Adam(),
loss=keras.losses.CategoricalCrossentropy(),
metrics=[keras.metrics.CategoricalAccuracy()])
model.summary()
models.append(model)
# --------------------- #
# ---- TRAIN MODELS ---- #
histories = []
for model in models:
with tf.device('/cpu:0'):
history = model.fit(x=df_train['features'].values, y=df_train['labels'].values,
validation_data=(df_val['features'].values, df_val['labels'].values),
batch_size=512, epochs=100, verbose=0)
histories.append(history)
# ---------------------- #
Upvotes: 1
Views: 313
Reputation: 22031
you simply need to set the seed every time you define and fit the model
following your code I collapse all in these lines:
NUMBER_OF_MODELS = 4
models = []
histories = []
for i in range(NUMBER_OF_MODELS):
set_seed_TF2(33)
model = keras.models.Sequential(name=f'{i}')
model.add(keras.layers.Dense(8, activation='relu', input_shape=df_train['features'].values.shape[-1:]))
model.add(keras.layers.Dense(3, activation='softmax'))
model.compile(optimizer=keras.optimizers.Adam(),
loss=keras.losses.CategoricalCrossentropy(),
metrics=[keras.metrics.CategoricalAccuracy()])
with tf.device('/cpu:0'):
history = model.fit(x=df_train['features'].values, y=df_train['labels'].values,
validation_data=(df_val['features'].values, df_val['labels'].values),
batch_size=512, epochs=100, verbose=0)
histories.append(history)
models.append(model)
the magic function is set_seed_TF2
def set_seed_TF2(seed):
tf.random.set_seed(seed)
os.environ['PYTHONHASHSEED'] = str(seed)
np.random.seed(seed)
random.seed(seed)
that must be call every time you initialize the model and fit
with this in mind, you can produce every time the same metrics/predictions:
here the running notebook: https://colab.research.google.com/drive/1nHEDI6d3LsRPQUXGiTOYfNOfw954Pu-H?usp=sharing
this works for CPU only
Upvotes: 1