我是TensorFlow框架的新手,我试图基于此Titanic数据集应用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.Drop Name列并在火车和测试仪上进行一次热编码
2。为简单起见,删除['PassengerId','Ticket','Cabin','Survived']。
"""# 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'。
有人可以解释问题出在哪里,并给出一些可能的解决方案吗?
答案 0 :(得分:3)
乍看之下,您的代码中存在2个主要问题:
您的输出层必须为Dense(2, activation='softmax')
。这是因为您的问题是二进制分类问题,如果您使用softmax生成概率,则输出dim必须等于类数。 (您可以在激活sigmoid
的情况下使用一个输出维度)
您必须更改损失功能。具有softmax和数字编码目标的用户使用sparse_categorical_crossentropy
。 (您可以将binary_crossentropy与sigmoid
一起使用,并且from_logits = False为默认值)
PS:开始拟合之前,请确保删除原始数据中的所有NaN
答案 1 :(得分:0)
Marco Cerliani在点1和点2是正确的。
拥有NaN的真正问题是因为您在代码中输入了NaN。如果仔细看,即使在第三张照片中,“年龄”列上的第888个示例也包含NaN。
这就是为什么您有NaN的原因。解决这个问题,并应用Marco Cerliani的建议,您就可以开始:D
答案 2 :(得分:0)
除了上述答案外,我还想补充一点:每当您要使用form_logits=True
解决分类问题时,请使用线性激活函数,即activation='linear'
,这是该函数的默认值最后一层激活功能。