页面树结构

2017-11-09 ApacheCN 开源组织,第二期邀请成员活动,一起走的更远 : http://www.apachecn.org/member/209.html


MachineLearning 优酷地址 : http://i.youku.com/apachecn

转至元数据结尾
转至元数据起始

在先前的TensorFlow线性模型教程中,我们训练了一个逻辑回归模型,以使用人口普查收入数据集预测个人年收入超过5万美元的概率 。TensorFlow也适用于训练深层神经网络,您可能会考虑选择哪一个 - 那么为什么不这两个呢?是否可以将两者的优势结合在一个模型中?

在本教程中,我们将介绍如何使用TF.Learn API联合训练广泛的线性模型和深入的前馈神经网络。这种方法结合了记忆和泛化的优势。它对于具有稀疏输入特征的通用大规模回归和分类问题(例如,具有大量可能特征值的分类特征)是有用的。如果您有兴趣了解Wide&Deep Learning如何运作,请查看我们的研究论文

上图显示了宽模型(具有稀疏特征和变换的逻辑回归),深度模型(具有嵌入层和多个隐藏层的前馈神经网络)的比较,以及宽&深度模型(两者的联合训练)。在高层次上,只需3个步骤即可使用TF.Learn API来配置宽,深或宽和深的模型:

  1. 选择广泛部分的功能:选择要使用的稀疏基础列和交叉列。
  2. 选择深部分的要素:选择连续列,每个分类列的嵌入维度和隐藏的图层大小。
  3. 把它们全部放在一个Wide&Deep模型(DNNLinearCombinedClassifier)中。

就是这样!我们来看一个简单的例子。

 

建立

要尝试本教程的代码:

  1.  如果还没有安装TensorFlow [安装TensorFlow]。

  2. 下载教程代码

  3. 安装熊猫数据分析库。tf.learn不需要大熊猫,但它支持它,本教程使用大熊猫。安装大熊猫:

    1. 获取pip

    ```shell#Ubuntu / Linux 64位$ sudo apt-get install python-pip python-dev

    #Mac OS X $ sudo easy_install pip $ sudo easy_install - 升级六个```

    1. 使用pip安装熊猫:

    shell $ sudo pip install pandas

    如果您在安装熊猫麻烦,请查阅 说明书 上的熊猫网站。

  4. 使用以下命令执行教程代码来训练本教程中描述的线性模型:

shell $ python wide_n_deep_tutorial.py --model_type=wide_n_deep 

请继续阅读,了解此代码如何构建其线性模型。

定义基本特征列

首先,我们来定义我们将使用的基本分类和连续特征列。这些基列将是模型的宽部分和深部使用的构件块。

import tensorflow as tf

# Categorical base columns.
gender = tf.contrib.layers.sparse_column_with_keys(column_name="gender", keys=["Female", "Male"])
race = tf.contrib.layers.sparse_column_with_keys(column_name="race", keys=[
  "Amer-Indian-Eskimo", "Asian-Pac-Islander", "Black", "Other", "White"])
education = tf.contrib.layers.sparse_column_with_hash_bucket("education", hash_bucket_size=1000)
relationship = tf.contrib.layers.sparse_column_with_hash_bucket("relationship", hash_bucket_size=100)
workclass = tf.contrib.layers.sparse_column_with_hash_bucket("workclass", hash_bucket_size=100)
occupation = tf.contrib.layers.sparse_column_with_hash_bucket("occupation", hash_bucket_size=1000)
native_country = tf.contrib.layers.sparse_column_with_hash_bucket("native_country", hash_bucket_size=1000)

# Continuous base columns.
age = tf.contrib.layers.real_valued_column("age")
age_buckets = tf.contrib.layers.bucketized_column(age, boundaries=[18, 25, 30, 35, 40, 45, 50, 55, 60, 65])
education_num = tf.contrib.layers.real_valued_column("education_num")
capital_gain = tf.contrib.layers.real_valued_column("capital_gain")
capital_loss = tf.contrib.layers.real_valued_column("capital_loss")
hours_per_week = tf.contrib.layers.real_valued_column("hours_per_week") 

宽模型:具有交叉特征列的线性模型

宽模型是一个线性模型,具有广泛的稀疏和交叉特征列:

wide_columns = [
  gender, native_country, education, occupation, workclass, relationship, age_buckets,
  tf.contrib.layers.crossed_column([education, occupation], hash_bucket_size=int(1e4)),
  tf.contrib.layers.crossed_column([native_country, occupation], hash_bucket_size=int(1e4)),
  tf.contrib.layers.crossed_column([age_buckets, education, occupation], hash_bucket_size=int(1e6))]
具有交叉特征列的宽模型可以有效地记住功能之间的稀疏交互。也就是说,交叉特征列的一个限制是它们不会推广到没有出现在训练数据中的特征组合。让我们用嵌入式添加一个深层次的模型来解决这个问题。

 

深层模型:嵌入式神经网络

深层模型是前馈神经网络,如前图所示。每个稀疏的高维度分类特征首先被转换成低维和密集的实值向量,通常被称为嵌入向量。这些低维密集嵌入矢量与连续特征相连,然后在正向传递中馈入神经网络的隐层。嵌入值被随机初始化,并与所有其他模型参数一起训练,以最小化训练损失。如果您有兴趣了解有关嵌入的更多信息,请参阅维基百科上的 TensorFlow关于词汇向量表示Word嵌入的教程。

我们将使用 embedding_column并将它们连接到连续列来配置分类列的嵌入:

deep_columns = [
  tf.contrib.layers.embedding_column(workclass, dimension=8),
  tf.contrib.layers.embedding_column(education, dimension=8),
  tf.contrib.layers.embedding_column(gender, dimension=8),
  tf.contrib.layers.embedding_column(relationship, dimension=8),
  tf.contrib.layers.embedding_column(native_country, dimension=8),
  tf.contrib.layers.embedding_column(occupation, dimension=8),
  age, education_num, capital_gain, capital_loss, hours_per_week] 
较高的dimension嵌入的是,更多的自由度的模式将要学习的功能表示。为了简单起见,我们在这里为所有功能列设置尺寸为8。在经验上,对维度数量的更明智的决定是从一个价值的顺序开始 日志2⁡(ñ) 要么  ķñ4,哪里  ñ 是特征列中的唯一特征的数量  ķ 是一个小常数(通常小于10)。

通过密集嵌入,深层模型可以更好地概括,并对以前在培训数据中看不到的特征对进行预测。然而,当两个特征列之间的底层交互矩阵稀疏和高等级时,很难学习特征列的有效低维表示。在这种情况下,大多数特征对之间的交互应该为零,除了少数几个,但密集的嵌入将导致所有特征对的非零预测,因此可能会过度泛化。另一方面,具有交叉特征的线性模型可以用更少的模型参数有效地记住这些“异常规则”。

现在,我们来看看如何联合训练广泛而深入的模式,让他们相互补充优势和劣势。

 

将宽和深度模型结合为一体

通过将其最终输出对数几率作为预测结合起来,将广泛的模型和深度模型相结合,然后将预测提供给物流损失函数。所有的图形定义和变量分配已经在你的引擎盖下处理,所以你只需要创建一个 DNNLinearCombinedClassifier

import tempfile
model_dir = tempfile.mkdtemp()
m = tf.contrib.learn.DNNLinearCombinedClassifier(
    model_dir=model_dir,
    linear_feature_columns=wide_columns,
    dnn_feature_columns=deep_columns,
    dnn_hidden_units=[100, 50]) 

训练和评估模型

在我们训练模型之前,让我们一起阅读普查数据集,就像我们在TensorFlow线性模型教程中所做的一样。输入数据处理代码再次提供给您方便:

import pandas as pd
import urllib

# Define the column names for the data sets.
COLUMNS = ["age", "workclass", "fnlwgt", "education", "education_num",
  "marital_status", "occupation", "relationship", "race", "gender",
  "capital_gain", "capital_loss", "hours_per_week", "native_country", "income_bracket"]
LABEL_COLUMN = 'label'
CATEGORICAL_COLUMNS = ["workclass", "education", "marital_status", "occupation",
                       "relationship", "race", "gender", "native_country"]
CONTINUOUS_COLUMNS = ["age", "education_num", "capital_gain", "capital_loss",
                      "hours_per_week"]

# Download the training and test data to temporary files.
# Alternatively, you can download them yourself and change train_file and
# test_file to your own paths.
train_file = tempfile.NamedTemporaryFile()
test_file = tempfile.NamedTemporaryFile()
urllib.urlretrieve("http://mlr.cs.umass.edu/ml/machine-learning-databases/adult/adult.data", train_file.name)
urllib.urlretrieve("http://mlr.cs.umass.edu/ml/machine-learning-databases/adult/adult.test", test_file.name)

# Read the training and test data sets into Pandas dataframe.
df_train = pd.read_csv(train_file, names=COLUMNS, skipinitialspace=True)
df_test = pd.read_csv(test_file, names=COLUMNS, skipinitialspace=True, skiprows=1)
df_train[LABEL_COLUMN] = (df_train['income_bracket'].apply(lambda x: '>50K' in x)).astype(int)
df_test[LABEL_COLUMN] = (df_test['income_bracket'].apply(lambda x: '>50K' in x)).astype(int)

def input_fn(df):
  # Creates a dictionary mapping from each continuous feature column name (k) to
  # the values of that column stored in a constant Tensor.
  continuous_cols = {k: tf.constant(df[k].values)
                     for k in CONTINUOUS_COLUMNS}
  # Creates a dictionary mapping from each categorical feature column name (k)
  # to the values of that column stored in a tf.SparseTensor.
  categorical_cols = {k: tf.SparseTensor(
      indices=[[i, 0] for i in range(df[k].size)],
      values=df[k].values,
      dense_shape=[df[k].size, 1])
                      for k in CATEGORICAL_COLUMNS}
  # Merges the two dictionaries into one.
  feature_cols = dict(continuous_cols.items() + categorical_cols.items())
  # Converts the label column into a constant Tensor.
  label = tf.constant(df[LABEL_COLUMN].values)
  # Returns the feature columns and the label.
  return feature_cols, label

def train_input_fn():
  return input_fn(df_train)

def eval_input_fn():
  return input_fn(df_test)
阅读数据后,您可以对模型进行培训和评估:
m.fit(input_fn=train_input_fn, steps=200)
results = m.evaluate(input_fn=eval_input_fn, steps=1)
for key in sorted(results):
    print("%s: %s" % (key, results[key]))
输出的第一行应该是这样的accuracy: 0.84429705。我们可以看到,使用宽和深度模型,使用广泛线性模型,约83.6%的准确度提高到约84.4%。如果您想看到一个有效的端对端示例,您可以下载我们的 示例代码

请注意,本教程只是一个小型数据集的简单示例,可让您熟悉API。如果您在具有许多可能的特征值的许多稀疏特征列的大型数据集上尝试,则Wide&Deep Learning将更加强大。再次,请随时查看我们的 研究论文,了解更多关于如何在现实世界的大型机器学习问题中应用广泛和深度学习的想法。

 

  • 无标签