全篇以tensorflow案例作为来源
这篇教程使用的是泰坦尼克号乘客的数据。模型会根据乘客的年龄、性别、票务舱和是否独自旅行等特征来预测乘客生还的可能性。
首先导入需要的模块
import functools
import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds
TRAIN_DATA_URL和TEST_DATA_URL是数据集的网址,使用tf.keras.utils.get_file从TRAIN_DATA_URL下载数据集train.cs,同时给下载的文件命名为train.csv。 train_file_path是该文件被保存在计算机中的路径。
TRAIN_DATA_URL="https://storage.googleapis.com/tfdatasets/titanic/ train.cs "
TEST_DATA_URL = "https://storage.googleapis.com/tf-datasets/titanic/eval.csv"
train_file_path = tf.keras.utils.get_file("train.csv", TRAIN_DATA_URL)
test_file_path = tf.keras.utils.get_file("eval.csv", TEST_DATA_URL)
np.set_printoptions用于控制输出方式,precision控制小数点后输出个数,默认是8. Suppress表示小数是否以科学计数法方式输出。 np.set_printoptions(precision=3, suppress=True)表示保留3位小数,小数不需要以科学计数法形式输出。
np.set_printoptions(precision=3, suppress=True)
查看train.csv文件,如果没有列名,那么需要将列名通过字符串列表传给 make_csv_dataset 函数的 column_names 参数。
CSV_COLUMNS = ['survived', 'sex', 'age', 'n_siblings_spouses', 'parch', 'fare', 'class', 'deck', 'embark_town', 'alone']
dataset = tf.data.experimental.make_csv_dataset(
column_names=CSV_COLUMNS,)
如果只需要某些列,可以使用select_columns函数。
dataset = tf.data.experimental.make_csv_dataset(
select_columns = columns_to_use,
)
选择需要作为标签的列。这里将’survived’作为标签,其值有[0, 1]。
LABEL_COLUMN = 'survived'
LABELS = [0, 1]
正式使用tf.data.experimental.make_csv_dataset从读取csv数据并创建dataset。 file_path表示csv文件在计算机中的路径。 batch_size表示在单个批次中合并的记录数。 label_name表示标签列,在这是’survived’(LABEL_COLUMN)。na_value=?表示将?当成缺失值,用NA来填充。 num_epochs=1表示重复此数据集1次。 ignore_errors=True表示忽略CSV文件解析错误(例如,格式错误的数据或空行),然后移至下一个有效的CSV记录。最后返回dataset。 构建train.csv和test.csv的dataset。
def get_dataset(file_path):
dataset = tf.data.experimental.make_csv_dataset(
file_path,
batch_size=12,
label_name= LABEL_COLUMN,
na_value="?",
num_epochs=1,
ignore_errors=True)
return dataset
raw_train_data = get_dataset(train_file_path)
raw_test_data = get_dataset(test_file_path)
处理数据 模型训练前,有时会使用one hot编码器对类别进行“二进制化”操作,然后将其作为模型训练的特征。该数据集既有连续变量(age),又有离散变量('class’等),下面分别对这些数据进行处理。
分类数据(离散)
创立一个分类的字典
CATEGORIES = {
'sex': ['male', 'female'],
'class' : ['First', 'Second', 'Third'],
'deck' : ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'],
'embark_town' : ['Cherbourg', 'Southhampton', 'Queenstown'],
'alone' : ['y', 'n']
}
tf.feature_column主要针对离散特征和连续特征进行特征处理。tf.feature_column.categorical_column_with_vocabulary_list将字符串的离散特征通过词表映射为离散特征,使用前定义好离散特征的取值(CATEGORIES), 当出现新值的时候可以分配新的索引位置,或者映射到已有的位置上。 indicator_column可用于包装任何categorical_column_*产生的向量,然后作为NN模型的input_layer的输入。 通过循环,处理所有分类数据,得到categorical_columns,这将是后续构建模型时处理输入数据的一部分。接下来处理连续数据。
categorical_columns = []
for feature, vocab in CATEGORIES.items():
cat_col = tf.feature_column.categorical_column_with_vocabulary_list(
key=feature, vocabulary_list=vocab)
categorical_columns.append(tf.feature_column.indicator_column(cat_col))
连续数据 连续数据需要标准化。写一个函数标准化这些值,然后将这些值改造成 2 维的张量。 首先通过tf.cast(data, tf.float32)将数据data的数据类型转化为tf.float32,
def process_continuous_data(mean, data):
data = tf.cast(data, tf.float32) * 1/(2*mean)
return tf.reshape(data, [-1, 1])
在使用标准化的方法之前需要知道每列的均值
MEANS = {
'age' : 29.631308,
'n_siblings_spouses' : 0.545455,
'parch' : 0.379585,
'fare' : 34.385399
}
tf.feature_column.numeric_column用于将连续值特征直接映射成连续特征。functools.partial的作用是预先设置参数,使得之后调用的时候,减少函数的参数 由此将离散数据转化为适合输入模型的特征。
numerical_columns = []
for feature in MEANS.keys():
num_col = tf.feature_column.numeric_column(feature, normalizer_fn=functools.partial(process_continuous_data, MEANS[feature]))
numerical_columns.append(num_col)
将这两个特征列的集合相加,并且传给 tf.keras.layers.DenseFeatures 从而创建一个进行预处理的输入层。
preprocessing_layer=tf.keras.layers.DenseFeatures(categorical_columns+numerical_columns)
利用tf.keras.Sequential建立模型 利用model.compile编译模型,并设置损失函数,优化器和指标。
model = tf.keras.Sequential([
preprocessing_layer,
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid'),
])
model.compile(
loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
实例化
train_data = raw_train_data.shuffle(500)
test_data = raw_test_data
训练模型
model.fit(train_data, epochs=20)
当模型训练完成的时候,你可以在测试集 test_data 上检查准确性。
test_loss, test_accuracy = model.evaluate(test_data)
print('\n\nTest Loss {}, Test Accuracy {}'.format(test_loss, test_accuracy))
使用 tf.keras.Model.predict 推断一个批次或多个批次的标签。
predictions = model.predict(test_data)
for prediction, survived in zip(predictions[:10], list(test_data)[0][1][:10]):
print("Predicted survival: {:.2%}".format(prediction[0]),
" | Actual outcome: ",
("SURVIVED" if bool(survived) else "DIED"))
`
|