TFLearn 快速入门实战:基于 Titanic 数据集构建深度神经网络生存预测模型

原创2026-09-24 16:33:001,382 阅读
文章标签:深度学习机器学习

TFLearn 快速入门实战:基于 Titanic 数据集构建深度神经网络生存预测模型

本教程源自 TFLearn 官方文档的 Tutorials 入口(docs/templates/tutorials.md),是该项目文档体系中唯一的完整入门教程(docs/templates/tutorials/quickstart.md)。你将用 TFLearn 与 TensorFlow,基于乘客个人信息(性别、年龄、舱位等级等)预测泰坦尼克号沉船事故中的幸存概率,完整走一遍"数据下载 → CSV 加载 → 特征预处理 → 三层全连接网络搭建 → 训练 → 预测"的经典机器学习流程。读完本文,你将掌握 TFLearn 中 load_csv 数据加载、input_data / fully_connected / regression 网络搭建以及 DNN 模型封装的核心用法,并能独立复现一个准确率约 81% 的二分类任务。

教程入口概览

TFLearn 官方文档在 docs/templates/tutorials.md 中规划了三类教程:

教程类别 主题 状态
Introduction TFLearn Quickstart:通过一个具体机器学习任务学习 TFLearn 基础,构建并训练深度神经网络分类器 已发布
Computer Vision Build an Image Classifier Coming soon
Natural Language Processing Build a Text Classifier Coming soon

其中"Introduction"类的 Quickstart 是唯一已经发布、内容完整的教程,也是本文的主体。计算机视觉与 NLP 两个入口在当前仓库中仍处于规划状态,如果你想提前接触这两类任务的写法,可以先行阅读 examples/images/(如 convnet_mnist.py)与 examples/nlp/(如 lstm.py)下的示例代码,但本文严格按照官方 Quickstart 教程展开。

任务背景:泰坦尼克号幸存者分析

1912 年 4 月 15 日,泰坦尼克号与冰山相撞后沉没,2224 名乘客与船员中有 1502 人罹难。虽然幸存存在一定的运气成分,但某些群体确实拥有更高的幸存概率——例如女性、儿童和上流阶层乘客。本教程要做的,就是构建一个深度神经网络分类器,找出"这些人是谁"。

具体而言,这是一个经典的二分类任务:

  • 类别 0:未幸存(not survived)
  • 类别 1:幸存(survived)
  • 特征数:每位乘客有 8 个特征

数据集与字段说明

TFLearn 会自动为你下载泰坦尼克数据集(该数据集托管在 TFLearn 官网资源目录,下载逻辑见 tflearn/datasets/titanic.py 中的 download_dataset 函数,若本地已存在同名文件则跳过下载并直接复用)。数据集中每位乘客包含以下字段:

VARIABLE DESCRIPTIONS:
survived        Survived
                (0 = No; 1 = Yes)
pclass          Passenger Class
                (1 = 1st; 2 = 2nd; 3 = 3rd)
name            Name
sex             Sex
age             Age
sibsp           Number of Siblings/Spouses Aboard
parch           Number of Parents/Children Aboard
ticket          Ticket Number
fare            Passenger Fare

数据集中的部分真实样本如下:

survived pclass name sex age sibsp parch ticket fare
1 1 Aubart, Mme. Leontine Pauline female 24 0 0 PC 17477 69.3000
0 2 Bowenur, Mr. Solomon male 42 0 0 211535 13.0000
1 3 Baclini, Miss. Marie Catherine female 5 2 1 2666 19.2583
0 3 Youseff, Mr. Gerious male 45.5 0 0 2628 7.2250

可以看出:survived 是标签列(第一列),其余 8 列(pclass、name、sex、age、sibsp、parch、ticket、fare)为特征。注意数据中同时包含字符串字段(如 name、sex)与数值字段(如 age、fare),这决定了后续必须进行预处理。

环境准备

在开始之前,请确保已经安装 TensorFlow 与 TFLearn。安装方法可参考仓库内的 docs/templates/installation.md。此外,教程代码依赖 NumPy(用于数组转换),示例中通过 import numpy as np 引入。

第一步:加载数据

数据集以 CSV 文件形式存储。TFLearn 提供了 load_csv() 函数,可以将 CSV 文件加载为 Python list。关键参数 target_column 用于指定标签所在列——本例中标签(survived 与否)位于第一列(索引 0)。

加载代码如下:

import numpy as np
import tflearn

# Download the Titanic dataset
from tflearn.datasets import titanic
titanic.download_dataset('titanic_dataset.csv')

# Load CSV file, indicate that the first column represents labels
from tflearn.data_utils import load_csv
data, labels = load_csv('titanic_dataset.csv', target_column=0,
                        categorical_labels=True, n_classes=2)

load_csv 返回一个元组 (data, labels),其中 data 是特征列表,labels 是标签列表。

从源码层面看,load_csv 定义于 tflearn/data_utils.py,完整签名如下:

def load_csv(filepath, target_column=-1, columns_to_ignore=None,
             has_header=True, categorical_labels=False, n_classes=None):

各参数的默认值与作用:

  • filepath:CSV 文件路径(必填)。
  • target_column:标签所在列的索引。默认值为 -1,即默认把最后一列当作标签;本例显式指定为 0,因为 Titanic 数据的第一列才是 survived。
  • columns_to_ignore:需要忽略的列索引列表(可选)。传入后会在读取时直接剔除对应列,且源码内部会自动修正目标列被移除后的索引偏移。
  • has_header:CSV 是否含表头行。默认 True,此时会先 next(data_file) 跳过表头。
  • categorical_labels:若为 True,标签会被转换为二值向量(one-hot),以便配合 categorical_crossentropy 损失使用。
  • n_classes:类别总数。当 categorical_labels=True 时必填,源码中若未提供会直接断言报错 "n_classes not specified!"。

当我们设置 categorical_labels=True, n_classes=2 时,内部会调用 tflearn/data_utils.py 中的 to_categorical 函数:把整数类别向量 [0, 1, 0, ...] 转换为形状为 (样本数, 2) 的二进制矩阵(第 0 位为 1 表示未幸存,第 1 位为 1 表示幸存),这正是 softmax + categorical_crossentropy 所需要的标签形态。

第二步:数据预处理

数据是"原样"给出的,需要经过预处理才能送入深度神经网络分类器。预处理包含两个环节。

环节一:丢弃与预测目标无关的字段。 教程假设乘客姓名与其幸存概率不相关,因此丢弃 name 和 ticket 两个字段。经过丢弃后(标签列已由 load_csv 单独取出),剩余特征变为:pclass、sex、age、sibsp、parch、fare,共 6 个。

环节二:将全部数据转换为数值。 神经网络只能对数值进行运算,而数据中仍含字符串字段。由于 name 已被丢弃,只需处理 sex 字段:简单地将男性(male)映射为 0、女性(female)映射为 1。

预处理函数如下:

# Preprocessing function
def preprocess(data, columns_to_ignore):
    # Sort by descending id and delete columns
    for id in sorted(columns_to_ignore, reverse=True):
        [r.pop(id) for r in data]
    for i in range(len(data)):
      # Converting 'sex' field to float (id is 1 after removing labels column)
      data[i][1] = 1. if data[i][1] == 'female' else 0.
    return np.array(data, dtype=np.float32)

# Ignore 'name' and 'ticket' columns (id 1 & 6 of data array)
to_ignore=[1, 6]

# Preprocess data
data = preprocess(data, to_ignore)

两个值得注意的实现细节:

  1. 按降序删除列:sorted(columns_to_ignore, reverse=True) 保证先删除索引较大的列,再删除索引较小的列,从而避免删除前一列导致后续列索引发生偏移。因为 name 在原始数据(去掉标签列后)中索引为 1,ticket 索引为 6,to_ignore=[1, 6] 正是为此设计。
  2. 性别编码索引固定为 1:删除 name 后,sex 成为去掉标签列后的第 2 个字段(索引 1),因此预处理中直接操作 data[i][1]。如果你的数据列顺序不同,这里需要相应调整。

最后用 np.array(data, dtype=np.float32) 将列表转换为 float32 的 NumPy 数组,这是 TFLearn 输入层默认接受的张量类型(input_data 的 dtype 默认即为 tf.float32,见 tflearn/layers/core.py)。

第三步:构建深度神经网络

教程构建的是一个 3 层全连接神经网络,全部通过 TFLearn 高层 API 完成。首先需要指定输入数据的形状:每个样本有 6 个特征,且按批次(batch)处理样本以节省内存,因此输入形状为 [None, 6]——其中 None 代表未知维度(即批次大小可变)。

# Build neural network
net = tflearn.input_data(shape=[None, 6])
net = tflearn.fully_connected(net, 32)
net = tflearn.fully_connected(net, 32)
net = tflearn.fully_connected(net, 2, activation='softmax')
net = tflearn.regression(net)

逐层解读:

  • tflearn.input_data(shape=<a href="https://link.gitcode.com/i/9aed79df686710c79ec5ccf821439077" target="_blank">None, 6]):输入层。从源码 [tflearn/layers/core.py 可知,它会自动创建一个形状为 [None, 6] 的 TensorFlow placeholder,并注册到 tf.GraphKeys.INPUTS 集合中,供 DNN 模型自动获取。如果首元素未写 None,源码会自动补上代表批次维度的 None。该层还支持 placeholder、data_preprocessing、data_augmentation 等参数。
  • 两个 fully_connected(net, 32):两个隐藏层,每层 32 个神经元。从源码 tflearn/layers/core.py 看,fully_connected 的完整签名支持众多参数:activation(默认 'linear')、bias(默认 True)、weights_init(默认 'truncated_normal')、bias_init(默认 'zeros')、regularizer / weight_decay、trainable、restore、reuse、scope、name 等。本教程两个隐藏层都使用默认激活函数,即线性激活(不带非线性变换);如果你想在隐藏层引入非线性,可以显式指定如 activation='relu' 之类的激活函数(TFLearn 支持的全部激活见 tflearn/activations.py)。
  • fully_connected(net, 2, activation='softmax'):输出层。2 个神经元对应 2 个类别(未幸存/幸存),softmax 将输出转换为概率分布,两个输出分别表示"未幸存概率"与"幸存概率"。
  • tflearn.regression(net):回归层(TFLearn 中用于配置优化目标)。从源码 tflearn/layers/estimator.py 看,它的默认配置为:优化器 optimizer='adam'(自适应矩估计)、损失函数 loss='categorical_crossentropy'(分类交叉熵,与前面 one-hot 标签匹配)、评估指标 metric='default'(即 accuracy 准确率)、学习率 learning_rate=0.001、batch_size=64、shuffle_batches=True。它会生成一个 TrainOp 并注册到 tf.GraphKeys.TRAIN_OPS 集合,供模型类执行训练。教程中未显式传参,即全部使用这些默认值。

第四步:训练模型

TFLearn 提供了模型封装类 DNN,可自动完成分类任务所需的训练、预测、保存/恢复等操作。本例训练 10 个 epoch(网络将完整"看"10 遍全部数据),批次大小为 16,并开启指标显示:

# Define model
model = tflearn.DNN(net)
# Start training (apply gradient descent algorithm)
model.fit(data, labels, n_epoch=10, batch_size=16, show_metric=True)

从源码 tflearn/models/dnn.py 看,DNN.__init__ 会从 TensorFlow 集合中自动收集训练操作(TRAIN_OPS)、输入(INPUTS)与目标(TARGETS),并基于 tflearn/helpers/trainer.py 中的 Trainer 和 tflearn/helpers/evaluator.py 中的 Evaluator 构建训练与评估管线;它还支持 clip_gradients(默认 5.0)、tensorboard_dir(默认 /tmp/tflearn_logs/)、checkpoint_path 等参数。

fit 方法(tflearn/models/dnn.py)的常用参数包括:

  • X_inputs / Y_targets:训练数据与标签,支持数组、多输入列表或 dict 形式。
  • n_epoch:训练轮数。
  • validation_set:验证集。可以是 (X_val, Y_val) 元组,也可以是小于 1 的浮点数(自动从训练数据中切分对应比例作为验证集)。
  • show_metric:是否在每个训练步骤显示准确率。
  • batch_size:批大小;若指定会覆盖网络回归层中设置的 batch_size(本例用 16 覆盖了 regression 层的默认 64)。
  • shuffle:是否打乱批次。
  • snapshot_epoch / snapshot_step:是否按 epoch 或按 step 做模型快照与校验。
  • run_id:为本次运行命名(用于 TensorBoard 区分)。
  • callbacks:训练生命周期中的自定义回调。

训练过程的实际输出如下:

---------------------------------
Run id: MG9PV8
Log directory: /tmp/tflearn_logs/
---------------------------------
Training samples: 1309
Validation samples: 0
--
Training Step: 82  | total loss: 0.64003
| Adam | epoch: 001 | loss: 0.64003 - acc: 0.6620 -- iter: 1309/1309
--
Training Step: 164  | total loss: 0.61915
| Adam | epoch: 002 | loss: 0.61915 - acc: 0.6614 -- iter: 1309/1309
--
Training Step: 246  | total loss: 0.56067
| Adam | epoch: 003 | loss: 0.56067 - acc: 0.7171 -- iter: 1309/1309
--
Training Step: 328  | total loss: 0.51807
| Adam | epoch: 004 | loss: 0.51807 - acc: 0.7799 -- iter: 1309/1309
--
Training Step: 410  | total loss: 0.47475
| Adam | epoch: 005 | loss: 0.47475 - acc: 0.7962 -- iter: 1309/1309
--
Training Step: 492  | total loss: 0.51677
| Adam | epoch: 006 | loss: 0.51677 - acc: 0.7701 -- iter: 1309/1309
--
Training Step: 574  | total loss: 0.48988
| Adam | epoch: 007 | loss: 0.48988 - acc: 0.7891 -- iter: 1309/1309
--
Training Step: 656  | total loss: 0.55073
| Adam | epoch: 008 | loss: 0.55073 - acc: 0.7427 -- iter: 1309/1309
--
Training Step: 738  | total loss: 0.50242
| Adam | epoch: 009 | loss: 0.50242 - acc: 0.7854 -- iter: 1309/1309
--
Training Step: 820  | total loss: 0.41557
| Adam | epoch: 010 | loss: 0.41557 - acc: 0.8110 -- iter: 1309/1309
--

对训练日志的解读要点:

  • Training samples: 1309:训练样本共 1309 人(与泰坦尼克数据集实际可用记录一致)。
  • Training Step: 82 等:由于批大小为 16,1309 个样本被划分为 82 个左右的批次,每个 epoch 末尾对应一次 step 递增(epoch 1 结束于 step 82,epoch 2 结束于 step 164,依此类推)。
  • 每行依次给出优化器(Adam)、当前 epoch、loss(交叉熵损失)、acc(准确率)以及 iter(当前进度)。
  • 损失总体呈下降趋势,准确率从 epoch 1 的约 0.662 波动上升至 epoch 10 的 0.8110。

训练结束时,模型整体准确率约为 81%,即能对约 81% 的乘客正确预测其幸存与否。

第五步:用模型做预测

模型训练完成后即可投入预测。教程用一个趣味案例收尾:取电影《泰坦尼克号》的两位主角——迪卡普里奥(Jack Dawson)与温丝莱特(Rose DeWitt Bukater)——计算他们的幸存概率(类别 1):

# Let's create some data for DiCaprio and Winslet
dicaprio = [3, 'Jack Dawson', 'male', 19, 0, 0, 'N/A', 5.0000]
winslet = [1, 'Rose DeWitt Bukater', 'female', 17, 1, 2, 'N/A', 100.0000]
# Preprocess data
dicaprio, winslet = preprocess([dicaprio, winslet], to_ignore)
# Predict surviving chances (class 1 results)
pred = model.predict([dicaprio, winslet])
print("DiCaprio Surviving Rate:", pred[0][1])
print("Winslet Surviving Rate:", pred[1][1])

预测输出:

DiCaprio Surviving Rate: 0.13849584758281708
Winslet Surviving Rate: 0.92201167345047

model.predict 的底层实现在 tflearn/models/dnn.py 中,它基于 Evaluator 对输入批量前向计算,返回 softmax 概率矩阵;pred[i][1] 即第 i 个样本的"幸存概率"。

结果解读:迪卡普里奥的幸存概率仅约 0.138(三等舱、男性、无亲属同行),温丝莱特的幸存概率高达约 0.922(一等舱、女性、票价高)。模型准确复现了电影结局——这也印证了本次分析的核心结论:头等舱的女性与儿童幸存概率最高,三等舱的男性乘客幸存概率最低。

完整源码

将上述步骤整合为可直接运行的完整脚本(官方教程原样提供,也见 docs/templates/tutorials/quickstart.md 与仓库内另一副本 tutorials/intro/quickstart.md):

from __future__ import print_function

import numpy as np
import tflearn

# Download the Titanic dataset
from tflearn.datasets import titanic
titanic.download_dataset('titanic_dataset.csv')

# Load CSV file, indicate that the first column represents labels
from tflearn.data_utils import load_csv
data, labels = load_csv('titanic_dataset.csv', target_column=0,
                        categorical_labels=True, n_classes=2)


# Preprocessing function
def preprocess(data, columns_to_ignore):
    # Sort by descending id and delete columns
    for id in sorted(columns_to_ignore, reverse=True):
        [r.pop(id) for r in data]
    for i in range(len(data)):
      # Converting 'sex' field to float (id is 1 after removing labels column)
      data[i][1] = 1. if data[i][1] == 'female' else 0.
    return np.array(data, dtype=np.float32)

# Ignore 'name' and 'ticket' columns (id 1 & 6 of data array)
to_ignore=[1, 6]

# Preprocess data
data = preprocess(data, to_ignore)

# Build neural network
net = tflearn.input_data(shape=[None, 6])
net = tflearn.fully_connected(net, 32)
net = tflearn.fully_connected(net, 32)
net = tflearn.fully_connected(net, 2, activation='softmax')
net = tflearn.regression(net)

# Define model
model = tflearn.DNN(net)
# Start training (apply gradient descent algorithm)
model.fit(data, labels, n_epoch=10, batch_size=16, show_metric=True)

# Let's create some data for DiCaprio and Winslet
dicaprio = [3, 'Jack Dawson', 'male', 19, 0, 0, 'N/A', 5.0000]
winslet = [1, 'Rose DeWitt Bukater', 'female', 17, 1, 2, 'N/A', 100.0000]
# Preprocess data
dicaprio, winslet = preprocess([dicaprio, winslet], to_ignore)
# Predict surviving chances (class 1 results)
pred = model.predict([dicaprio, winslet])
print("DiCaprio Surviving Rate:", pred[0][1])
print("Winslet Surviving Rate:", pred[1][1])

进阶方向与源码指引

本教程演示的"数据加载 → 预处理 → 层堆叠 → DNN 封装 → 训练/预测"是 TFLearn 一切任务(分类、回归、聚类、生成等)的通用骨架。基于本教程打下的基础,你可以顺着以下仓库资源继续深入:

需要注意的是:官方文档将图像分类与文本分类教程标注为 "Coming soon",因此本篇文章严格以已发布的 Quickstart 教程为准;你在 TFLearn 中开展图像或文本任务时,应以上述 examples 目录下的成熟示例为第一手参考。

登录后查看全文
tflearn