Keras Sequential 和 Functional 在同一個資料集上的同一個模型的實作顯示了不同的結果。
序列的代碼:
import random
import glob, os
import numpy as np
from sklearn.utils import shuffle
from sklearn.model_selection import KFold, StratifiedKFold
import tensorflow as tf
import tensorflow.keras as keras
from tensorflow.keras import models
from tensorflow.keras import layers
from sklearn.preprocessing import LabelEncoder
from tensorflow.keras.models import Sequential
from tensorflow import keras
from tensorflow.keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import cross_val_score
SEED = 42
os.environ['PYTHONHASHSEED']=str(SEED)
np.random.seed(SEED)
tf.random.set_seed(SEED)
random.seed(SEED)
dataset = np.load("/content/drive/MyDrive/Test_Performance/dataset.npz")
x = dataset['x']
y = dataset['y']
encoder = LabelEncoder()
encoder.fit(y)
label = encoder.transform(y)
model_1 = Sequential([
layers.Dense(256, activation='relu'),
layers.Dense(128, activation='relu'),
layers.Dense(64, activation='relu'),
layers.Dense(32, activation='relu'),
layers.Dense(16, activation='relu'),
layers.Dense(1)
])
def get_model_2():
inputs1 = layers.Input(256)
x1 = layers.Dense(units=256, activation="relu")(inputs1)
x2 = layers.Dense(units=128, activation="relu")(x1)
x3 = layers.Dense(units=64, activation="relu")(x2)
x4 = layers.Dense(units=32, activation="relu")(x3)
x5 = layers.Dense(units=16, activation="relu")(x4)
outputs = layers.Dense(1)(x5)
model = models.Model(inputs=inputs1, outputs=outputs, name="mymodel")
optimizer2 = keras.optimizers.Adam(learning_rate=0.0001)
model.compile(loss='binary_crossentropy',
optimizer=optimizer2,
metrics=['accuracy'])
return model
print(y)
print(y.shape)
np.savez_compressed("dataset.npz",x=x, y=y)
x, y = shuffle(x, y, random_state=SEED)
# ========= Model 1 ==========
optimizer2 = keras.optimizers.Adam(learning_rate=0.0001)
model_1.compile(loss='binary_crossentropy',
optimizer=optimizer2,
metrics=['accuracy'])
estimator = KerasClassifier(build_fn=lambda: model_1, epochs=200, batch_size=100,verbose=1)
# =============================
kfold = StratifiedKFold(n_splits=10, random_state=SEED,shuffle=True)
results = cross_val_score(estimator, x, y, scoring='accuracy', cv=kfold, verbose=2)
print("Baseline: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
函式式代碼:
import random
import glob, os
import numpy as np
from sklearn.utils import shuffle
from sklearn.model_selection import KFold, StratifiedKFold
import tensorflow as tf
import tensorflow.keras as keras
from tensorflow.keras import models
from tensorflow.keras import layers
from sklearn.preprocessing import LabelEncoder
from tensorflow.keras.models import Sequential
from tensorflow import keras
from tensorflow.keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import cross_val_score
SEED = 42
os.environ['PYTHONHASHSEED']=str(SEED)
np.random.seed(SEED)
tf.random.set_seed(SEED)
random.seed(SEED)
dataset = np.load("/content/drive/MyDrive/Test_Performance/dataset.npz")
x = dataset['x']
y = dataset['y']
encoder = LabelEncoder()
encoder.fit(y)
label = encoder.transform(y)
model_1 = Sequential([
layers.Dense(256, activation='relu'),
layers.Dense(128, activation='relu'),
layers.Dense(64, activation='relu'),
layers.Dense(32, activation='relu'),
layers.Dense(16, activation='relu'),
layers.Dense(1)
])
def get_model_2():
inputs1 = layers.Input(256)
x1 = layers.Dense(units=256, activation="relu")(inputs1)
x2 = layers.Dense(units=128, activation="relu")(x1)
x3 = layers.Dense(units=64, activation="relu")(x2)
x4 = layers.Dense(units=32, activation="relu")(x3)
x5 = layers.Dense(units=16, activation="relu")(x4)
outputs = layers.Dense(1)(x5)
model = models.Model(inputs=inputs1, outputs=outputs, name="mymodel")
optimizer2 = keras.optimizers.Adam(learning_rate=0.0001)
model.compile(loss='binary_crossentropy',
optimizer=optimizer2,
metrics=['accuracy'])
return model
print(y)
print(y.shape)
np.savez_compressed("dataset.npz",x=x, y=y)
x, y = shuffle(x, y, random_state=SEED)
# ====== Model 2 ========
estimator = KerasClassifier(build_fn=lambda: get_model_2(), epochs=200, batch_size=100,verbose=1)
# =======================
kfold = StratifiedKFold(n_splits=10, random_state=SEED,shuffle=True)
results = cross_val_score(estimator, x, y, scoring='accuracy', cv=kfold, verbose=2)
print("Baseline: %.2f%% (%.2f%%)" % (results.mean()*100, results.std()*100))
我已經為兩個代碼設定了一個固定的種子號。另外,還可以在代碼中查找此谷歌colab和這里是資料集。
連續結果幾乎總是高于 0.9,而泛函總是在 0.5 左右!
uj5u.com熱心網友回復:
這些層具有默認的初始化權重,這些權重取決于當前的亂數生成器 (RNG) 狀態,該狀態隨著每次亂數生成而不斷變化。因此,模型 1 和模型 2 的層(在您的情況下為 Dense)的默認(初始化)權重不同,因為它們的 RNG 狀態不同。一種簡單的修復方法是在創建模型之前為 RNG 設定種子。
固定示例代碼:
SEED = 42
x = np.random.randn(100,256)
y = np.random.randn(100,1)
def get_model1():
os.environ['PYTHONHASHSEED']=str(SEED)
np.random.seed(SEED)
tf.random.set_seed(SEED)
random.seed(SEED)
model = Sequential([
layers.Dense(256, activation='relu'),
layers.Dense(128, activation='relu'),
layers.Dense(64, activation='relu'),
layers.Dense(32, activation='relu'),
layers.Dense(16, activation='relu'),
layers.Dense(1)
])
model.compile(loss='binary_crossentropy',
optimizer=keras.optimizers.Adam(lr=0.0001),
metrics=['accuracy'])
return model
get_model1().fit(x,y,epochs=4)
print ("--"*10)
def get_model2():
os.environ['PYTHONHASHSEED']=str(SEED)
np.random.seed(SEED)
tf.random.set_seed(SEED)
random.seed(SEED)
inputs1 = layers.Input(256)
x1 = layers.Dense(units=256, activation="relu")(inputs1)
x2 = layers.Dense(units=128, activation="relu")(x1)
x3 = layers.Dense(units=64, activation="relu")(x2)
x4 = layers.Dense(units=32, activation="relu")(x3)
x5 = layers.Dense(units=16, activation="relu")(x4)
outputs = layers.Dense(1)(x5)
model = models.Model(inputs=inputs1, outputs=outputs, name="mymodel")
model.compile(loss='binary_crossentropy',
optimizer=keras.optimizers.Adam(learning_rate=0.0001),
metrics=['accuracy'])
return model
get_model2().fit(x,y,epochs=4)
輸出:
Epoch 1/4
4/4 [==============================] - 1s 6ms/step - loss: 1.4076 - accuracy: 0.0000e 00
Epoch 2/4
4/4 [==============================] - 0s 9ms/step - loss: 1.2012 - accuracy: 0.0000e 00
Epoch 3/4
4/4 [==============================] - 0s 5ms/step - loss: 1.1590 - accuracy: 0.0000e 00
Epoch 4/4
4/4 [==============================] - 0s 5ms/step - loss: 1.1359 - accuracy: 0.0000e 00
--------------------
Epoch 1/4
4/4 [==============================] - 1s 6ms/step - loss: 1.4076 - accuracy: 0.0000e 00
Epoch 2/4
4/4 [==============================] - 0s 5ms/step - loss: 1.2012 - accuracy: 0.0000e 00
Epoch 3/4
4/4 [==============================] - 0s 5ms/step - loss: 1.1590 - accuracy: 0.0000e 00
Epoch 4/4
4/4 [==============================] - 0s 5ms/step - loss: 1.1359 - accuracy: 0.0000e 00
如您所見,兩個模型的損失收斂相同。
GPU 操作的再現性變得棘手,因為某些 GPU 操作是不確定的。但是,由于您僅使用密集層,因此您的運行是確定性的(并且可重現)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/375437.html
