keras Nans的tensorflow 模型预测

iklwldmw  于 2022-11-13  发布在  其他
关注(0)|答案(3)|浏览(255)

我是TensorFlow框架的新手,我正在尝试应用Tensorflow来基于这个泰坦尼克号数据集预测幸存者:https://www.kaggle.com/c/titanic/data。

import tensorflow as tf
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
#%%
titanictrain = pd.read_csv('train.csv')
titanictest = pd.read_csv('test.csv')
df = pd.concat([titanictrain,titanictest],join='outer',keys='PassengerId',sort=False,ignore_index=True).drop(['Name'],1)

#%%

def preprocess(df):
    df['Fare'].fillna(value=df.groupby('Pclass')['Fare'].transform('median'),inplace=True)
    df['Fare'] = df['Fare'].map(lambda x: np.log(x) if x>0 else 0)
    df['Embarked'].fillna(value=df['Embarked'].mode()[0],inplace=True)
    df['CabinAlphabet'] = df['Cabin'].str[0]
    categories_to_one_hot = ['Pclass','Sex','Embarked','CabinAlphabet']
    df = pd.get_dummies(df,columns=categories_to_one_hot,drop_first=True)
    return df
df = preprocess(df)

df = df.drop(['PassengerId','Ticket','Cabin','Survived'],1)

titanic_trainandval = df.iloc[:len(titanictrain)]
titanic_test = df.iloc[len(titanictrain):] #test after preprocessing

titanic_test.head()

#  split train into training and validation set
labels = titanictrain['Survived']
y = labels.values

test = titanic_test.copy() # real test sets
print(len(test), 'test examples')

这里我尝试对数据进行预处理:
1.删除名称列,并在列车和测试集上进行一次热编码
2.删除['PassengerId','Ticket','Cabin','Survived']以简化操作。
1.拆分列车并按原顺序进行试验


这张图片显示了训练集的外观。

"""# model training"""

from tensorflow.keras.layers import Input, Dense, Activation,Dropout
from tensorflow.keras.models import Model

X = titanic_trainandval.copy()
input_layer = Input(shape=(X.shape[1],))
dense_layer_1 = Dense(10, activation='relu')(input_layer)
dense_layer_2 = Dense(5, activation='relu')(dense_layer_1)
output = Dense(1, activation='softmax',name = 'predictions')(dense_layer_2)

model = Model(inputs=input_layer, outputs=output)
base_learning_rate = 0.0001

model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=True), optimizer=tf.keras.optimizers.Adam(lr=base_learning_rate), metrics=['acc'])

history = model.fit(X, y, batch_size=5, epochs=20, verbose=2, validation_split=0.1,shuffle = False)

submission = pd.DataFrame()
submission['PassengerId'] = titanictest['PassengerId']

然后,我将训练集X放入模型中,以获得结果。然而,历史显示了以下结果:

无论我如何改变学习率和批量大小,结果都不会改变,损失总是“nan”,基于测试集的预测也总是“nan”。
有人能解释一下问题出在哪里,并给予一些可能的解决方案吗?

a2mppw5e

a2mppw5e1#

乍一看,你的代码中有两个主要问题:
1.你的输出层必须是Dense(2, activation='softmax') .这是因为你的是一个二进制分类问题,如果你使用softmax来生成概率,那么输出dim必须等于类的数目。(你可以使用一个带有sigmoid激活的输出维)
1.你必须改变你的损失函数。与softmax和数字编码的目标使用sparse_categorical_crossentropy。(你可以使用binary_crossentropy与sigmoid和from_logits=假作为默认值)
PS:在开始拟合之前,请确保删除原始数据中的所有NaN

rqmkfv5c

rqmkfv5c2#

马可·切利亚尼在第1点和第2点上是正确的。
真实的的问题是你为什么有NaN是因为你在代码中填充了NaN。如果你仔细看,即使在你的第三张照片中,Age列上的第888个例子也包含了NaN。
这就是为什么你有NaN。解决这个问题,并应用Marco Cerliani的建议,你就可以开始了。

kgsdhlau

kgsdhlau3#

除了上述答案外,我还想补充的一点是,无论何时您想使用form_logits=True来解决分类问题,请使用线性激活函数,即activation='linear',这是最后一层中激活函数的默认值。

相关问题