4.5 softmax分类
借助对数几率回归,可对Yes-No型问题的回答进行建模。现在,希望能够回答具有多个选项的问题,如“你的出生地是波士顿、伦敦还是悉尼?”
对于这样的问题,可使用softmax函数,它是对数几率回归在C个可能不同的值上的推广。
该函数的返回值为含C个分量的概率向量,每个分量对应于一个输出类别的概率。由于各分量为概率,C个分量之和始终为1,这是因为softmax的公式要求每个样本必须属于某个输出类别,且所有可能的样本均被覆盖。如果各分量之和小于1,则意味着存在一些隐藏的类别;若各分量之和大于1,则说明每个样本可能同时属于多个类别。
可以证明,当类别总数为2时,所得到的输出概率与对数几率回归模型的输出完全相同。
为实现该模型,需要将之前的模型实现中变量初始化部分稍做修改。由于模型需要计算C个而非1个输出,所以需要C个不同的权值组,每个组对应一个可能的输出。因此,会使用一个权值矩阵而非一个权值向量。该矩阵的每行都与一个输入特征对应,而每列都对应于一个输出类别。
在尝试softmax分类时,我们准备使用经典的鸢尾花数据集Iris(下载链接https://archive.ics.uci.edu/ml/datasets/Iris)。该数据集中包含4个数据特征及3个可能的输出类(不同类型的鸢尾花),因此权值矩阵的维数应为4×3。
变量初始化代码如下所示:
正如所期望的那样,TensorFlow提供了一个softmax函数的内嵌实现:
对数几率回归中对损失计算的考虑也同样应用于拟合一个候选损失函数,因为这里的输出也是概率值。准备再次使用交叉熵,并对其进行改造以适应多类情形。
对于单个训练样本i,交叉熵的形式变为:
将每个输出类别在训练样本上的损失相加。注意,对于训练样本的期望类别,yc应当为1,对其他情形应为0,因此实际上这个和式中只有一个损失值被计入,它度量了模型为真实类别预测的概率的可信度。
为计算训练集上的总损失值,我们将每个训练样本的损失相加:
在代码层面,TensorFlow为softmax交叉熵函数提供了两个实现版本:一个版本针对训练集中每个样本只对应单个类别专门做了优化。例如,训练数据可能有一个类别值或者是“dog”,或者是“person”或“tree”。这个函数是tf.nn.sparse_softmax_cross_entropy_with_logits。
另一个版本允许用户使用包含每个样本属于每个类别的概率信息的训练集。例如,可使用像“60%被询问的人认为这幅图片与狗有关,25%认为与树有关,其余人认为与人有关”的训练数据,该函数是tf.nn.softmax_cross_entropy_with_logits。在一些真实用例中,可能需要这样的函数,但对于正在考虑的简单问题,并不需要它。在可能的情况下,稀疏版本是更好的选择,因为它的计算速度非常快。注意,模型的最终输出将总是单个类别值,这个版本只是为了支持更灵活的训练数据。
下面定义输入方法。我们将复用来自对数几率回归示例中的read_csv函数,但在调用时会使用数据集中的默认值,它们都是数值型的。
为了使用sparse_softmax_cross_entropy_with_logits,无须将每个类别都转换成它自己的变量,但需要将值转换为范围是0~2的整数,因为总的类别数为3。在数据集文件中,类别是一个来自“Iris-setosa”、“Iris-versicolor”和“Iris-virginica”的字符串。为对其进行转换,可用tf.pack创建一个张量,并利用tf.equal将文件输入与每个可能的值进行比较。然后,利用tf.argmax找到那个张量中值为真的位置,从而有效地将各类别转化为0~2范围的整数。
对于训练函数,内容完全相同。
为了评估模型的准确率,需要对sigmoid版本稍做修改:
推断过程将计算各测试样本属于每个类别的概率。可利用tf.argmax函数来选择预测的输出值中具有最大概率的那个类别。最后,把tf.equal与期望的类别进行比较,并像之前sigmoid的例子中那样运用tf.reduce_mean计算准确率。
运行上述代码,可以获得约95%的准确率。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论