TFLearn - 快速入门

在本教程中,您将学习如何使用 TFLearn 和 TensorFlow,根据泰坦尼克号乘客的个人信息(如性别、年龄等)来估计其存活几率。为了解决这个经典的机器学习任务,我们将构建一个深度神经网络分类器。

先决条件

确保您已安装 tensorflow 和 tflearn。如果尚未安装,请按照以下说明进行操作。

概述

Titanic

介绍

1912 年 4 月 15 日,泰坦尼克号在与冰山相撞后沉没,2224 名乘客和船员中有 1502 人遇难。尽管在沉船事故中生存下来存在一定的运气成分,但某些人群比其他人更有可能生存,例如妇女、儿童和上层阶级。在本教程中,我们将进行分析以找出这些人是谁。

数据集

让我们看一下数据集(TFLearn 会自动为您下载)。对于每位乘客,提供以下信息

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

以下是数据集中的部分样本

是否存活 客舱等级 姓名 性别 年龄 兄弟姐妹/配偶人数 父母/子女人数 船票号码 票价
1 1 Aubart, Mme. Leontine Pauline 女性 24 0 0 PC 17477 69.3000
0 2 Bowenur, Mr. Solomon 男性 42 0 0 211535 13.0000
1 3 Baclini, Miss. Marie Catherine 女性 5 2 1 2666 19.2583
0 3 Youseff, Mr. Gerious 男性 45.5 0 0 2628 7.2250

我们的任务中有 2 个类别:“未存活”(类别 0)和“存活”(类别 1),乘客数据有 8 个特征。

构建分类器

加载数据

数据集存储在一个 csv 文件中,因此我们可以使用 TFLearn 的 load_csv() 函数将数据从文件加载到 Python 的 list 中。我们指定 'target_column' 参数来指示我们的标签(存活或未存活)位于第一列(id: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)

预处理数据

数据是“按原样”提供的,需要进行一些预处理才能用于我们的深度神经网络分类器。

首先,我们将丢弃那些不太可能对我们的分析有所帮助的字段。例如,我们假设“姓名”字段在我们的任务中不是很有用,因为我们估计乘客姓名与其存活几率无关。基于这种想法,我们丢弃“姓名”和“船票号码”字段。

然后,我们需要将所有数据转换为数值,因为神经网络模型只能对数字执行操作。但是,我们的数据集包含一些非数值,例如“姓名”或“性别”。由于“姓名”被丢弃,我们只需要处理“性别”字段。在这个简单的例子中,我们将为男性分配“0”,为女性分配“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)

构建深度神经网络

我们正在使用 TFLearn 构建一个 3 层神经网络。我们需要指定输入数据的形状。在我们的例子中,每个样本共有 6 个特征,我们将按批处理样本来节省内存,因此我们的数据输入形状为 [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 提供了一个模型包装器“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)

输出

---------------------------------
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
--

我们的模型训练完成,总体准确率约为 81%,这意味着它可以预测 81% 的乘客的正确结果(存活或未存活)。

测试模型

现在是时候测试我们的模型了。为了好玩,让我们以泰坦尼克号电影的主角(迪卡普里奥和温斯莱特)为例,计算他们存活的几率(类别 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

令人印象深刻!我们的模型准确地预测了电影的结果。迪卡普里奥的几率很小,但温斯莱特有很大的存活几率。

更普遍地说,通过这项研究可以看出,头等舱的妇女和儿童乘客的存活几率最高,而三等舱的男性乘客的存活几率最低。

源代码

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])