[英]Is there any difference between the DNN model by keras and the DNN model by pytorch?
這是我的 Torch 和 keras 的 DNN 代碼。 我用它們來訓練相同的數據,但最終得到完全不同的 AUC 結果(keras 版本達到 0.74,torch 版本達到 0.67)。 所以我很困惑。 而且我已經嘗試了很多次,我的結果仍然存在差異? 兩種型號有區別嗎?
categorical_embed_sizes = [589806, 21225, 2565, 2686, 343, 344, 10, 2, 8, 8, 7, 7, 2, 2, 2, 17, 17, 17]
#keras model
cat_input, embeds = [], []
for i in range(cat_len):
input_ = Input(shape=(1, ))
cat_input.append(input_)
nums = categorical_embed_sizes[i]
embed = Embedding(nums, 8)(input_)
embeds.append(embed)
cont_input = Input(shape=(cont_len,), name='cont_input', dtype='float32')
cont_input_r = Reshape((1, cont_len))(cont_input)
embeds.append(cont_input_r)
#Merge_L=concatenate([train_emb,trainnumber_emb,departstationname_emb,arrivestationname_emb,seatname_emb,orderofftime_emb,fromcityname_emb,tocityname_emb,daytype_emb,num_input_r])
Merge_L=concatenate(embeds, name='cat_1')
Merge_L=Dense(256,activation=None,name='dense_0')(Merge_L)
Merge_L=PReLU(name='merge_0')(Merge_L)
Merge_L=BatchNormalization(name='bn_0')(Merge_L)
Merge_L=Dense(128,activation=None,name='dense_1')(Merge_L)
Merge_L=PReLU(name='prelu_1')(Merge_L)
Merge_L=BatchNormalization(name='bn_1')(Merge_L)
Merge_L=Dense(64,activation=None,name='Dense_2')(Merge_L)
Merge_L=PReLU(name='prelu_2')(Merge_L)
Merge_L=BatchNormalization(name='bn_2')(Merge_L)
Merge_L=Dense(32,activation=None,name='Dense_3')(Merge_L)
Merge_L=PReLU(name='prelu_3')(Merge_L)
Merge_L=BatchNormalization(name='bn_3')(Merge_L)
Merge_L=Dense(16,activation=None,name='Dense_4')(Merge_L)
Merge_L=PReLU(name='prelu_4')(Merge_L)
predictions= Dense(1, activation='sigmoid', name='Dense_rs')(Merge_L)
predictions=Reshape((1,), name='pred')(predictions)
cat_input.append(cont_input)
model = Model(inputs=cat_input,
outputs=predictions)
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=[tf.keras.metrics.BinaryAccuracy(), tf.keras.metrics.AUC()])
# torch model
class DNN(nn.Module):
def __init__(self, categorical_length, categorical_embed_sizes, categorical_embed_dim, in_size):
super(DNN, self).__init__()
self.categorical_length = categorical_length
self.categorical_embed_sizes = categorical_embed_sizes
self.categorical_embed_dim = categorical_embed_dim
self.in_size = in_size
self.nn = torch.nn.Sequential(
nn.Linear(self.in_size, 256),
nn.PReLU(256),
nn.BatchNorm1d(256),
nn.Linear(256, 128),
nn.PReLU(128),
nn.BatchNorm1d(128),
nn.Linear(128, 64),
nn.PReLU(64),
nn.BatchNorm1d(64),
nn.Linear(64, 32),
nn.PReLU(32),
nn.BatchNorm1d(32),
nn.Linear(32, 16),
nn.PReLU(16)
)
self.out = torch.nn.Sequential(
nn.Linear(16, 1),
nn.Sigmoid()
)
self.embedding = nn.Embedding(self.categorical_embed_sizes, self.categorical_embed_dim)
def forward(self, x):
x_categorical = x[:, :self.categorical_length].long()
x_categorical = self.embedding(x_categorical).view(x_categorical.size(0), -1)
x = torch.cat((x_categorical, x[:, self.categorical_length:]), dim=1)
x = self.nn(x)
out = self.out(x)
return out
網絡的結果取決於權重初始化方案。 Keras 和 Pytorch 有不同的權重初始化方案。 Keras 使用 Glorot,Pytorch 使用 Kaming。
即使您使用相同的方案,結果也不會相同(但會接近),因為每次開始新訓練時權重初始化都會有所不同。
最后我找到了我遇到的錯誤的真正原因。 它與 model 結構或參數無關。 其實sklearn的roc_auc_score function的錯誤輸入是這個錯誤的直接原因。
眾所周知, sklearn.metrics.roc_auc_score
至少需要y_true
和y_score
。 y_true
是數據集的真實標簽, y_score
是 label 1 的預測概率(用於二進制任務)。
但是當我使用 Torch 的輸出來計算兩個指標(准確度和 AUC)時,我將輸出轉換為 0-1 向量。 所以我的y_score
不再是概率,而是 0-1 個向量。
然后錯誤發生了......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.