TensorFlow实现对数几率回归

注:本文来自《面向机器智能的TensorFlow实践》一书,请购买正版图书:https://item.jd.com/12176592.html

线性回归模型所预测的是一个连续值或任意实数。下面介绍一种能够回答Yes-No类型的问题(如,这封邮件是否为垃圾邮件?)的模型。

在机器学习领域,有一个极为常见的函数——logistic函数。由于外形与字母S相仿,它也称为sigmoid函数(sigma为等价于S的希腊字母)。

这里写图片描述

从上图可清楚地看到logistic/sigmoid函数呈现出类似字母“S”的形状。

logistic函数是一个概率分布函数,即给定某个特定输入,该函数将计算输出为“success”的概率,也就是对问题的回答为“Yes”的概率。

这个函数接受单个输入值。为使该函数能够接受多维数据,或来自训练集中样本的特征,需要将它们合并为单个值。可利用上述的线性回归模型表达式。

为在代码中对此进行表示,可复用线性模型的所有元素。不过,为了运用sigmoid函数,需要对预测部分稍做修改。

# same params and variables initialization as log reg.
# 与对数几率回归相同的参数和变量初始化
W = tf.Variable(tf.zeros([5, 1]), name="weights")
b = tf.Variable(0., name="bias")

# former inference is now used for combining inputs
# 之前的推断现在用于值的合并
def combine_inputs(X):
    return tf.matmul(X, W) + b

# new inferred value is the sigmoid applied to the former
# 新的推断值是将sigmoid函数运用到前面的合并值的输出
def inference(X):
    return tf.sigmoid(combine_inputs(X))

下面重点讨论该模型的损失函数,也可以使用平方误差。logistic函数会计算回答为“Yes”的概率。在训练集中,“Yes”回答应当代表100%的概率,或输出值为1的概率。然后,损失应当刻画的是对于特定样本,模型为其分配一个小于1的值的概率。因此,回答“No”将表示概率值为0,于是损失是模型为那个样本所分配的概率值,并取平方。
假设某个样本的期望输出为“Yes”,但模型为其预测了一个非常低的接近于0的概率,这意味着几乎可以100%地认为答案为“No”。
平方误差所惩罚的是与损失为同一数量级的情形,就好比为“No”输出赋予的概率为20%、30%,甚至50%。
对于这种类型的问题,采取如下的交叉熵(cross entropy)损失函数会更为有效。
这里写图片描述

可以用可视化的方式依据对“Yes”的预测结果,对这两种损失函数进行比较。
这里写图片描述

交叉熵与平方误差(L2)函数会被叠加绘制。交叉熵输出了一个更大的值(“惩罚”),因为输出与期望值相去甚远。

借助交叉熵,当模型对期望输出为“Yes”的样本的预测概率接近于0时,罚项的值就会增长到接近于无穷大。这就使得训练完成后,模型不可能做出这样的错误预测。这使得交叉熵更适合作为该模型的损失函数。

TensorFlow提供了一个可在单个优化步骤中直接为一个sigmoid输出计算交叉熵的方法:

def loss(X, Y):
    return tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(combine_inputs(X), Y))

这里写图片描述

这里写图片描述

下面将该模型运用到一些数据上。我们准备使用来自https://www.kaggle.com/c/titanic/data的Kaggle竞赛数据集Titanic。

该模型应能依据乘客的年龄、性别和船票的等级推断他或她是否能够幸存下来。

为增添一些趣味性,这次准备从文件读取数据。请前往该竞赛对应的页面下载train.csv文件。

编写读取文件的基本代码。对于之前编写的框架,这是一个新的方法。你可加载和解析它,并创建一个批次来读取排列在某个张量中的多行数据,以提升推断计算的效率。

def read_csv(batch_size, file_name, record_defaults):
    filename_queue = tf.train.string_input_producer([os.path.join(os.getcwd(), file_name)])

    reader = tf.TextLineReader(skip_header_lines=1)
    key, value = reader.read(filename_queue)

    # decode_csv will convert a Tensor from type string (the text line) in
    # a tuple of tensor columns with the specified defaults, which also
    # sets the data type for each column
    decoded = tf.decode_csv(value, record_defaults=record_defaults)

    # batch actually reads the file and loads "batch_size" rows in a single tensor
    return tf.train.shuffle_batch(decoded,
                                  batch_size=batch_size,
                                  capacity=batch_size * 50,
                                  min_after_dequeue=batch_size)
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值