成本函数训练目标与准确性目标

rwa*_*ace 0 classification machine-learning neural-network gradient-descent loss-function

当我们训练神经网络时,我们通常使用梯度下降,这依赖于连续的,可微分的实值成本函数。最终成本函数可能会产生均方误差。或者换种说法,梯度下降隐式地认为最终目标是回归 -最大限度地减少实值误差度量。

有时,我们希望神经网络要做的就是执行分类 -给定输入,将其分类为两个或多个离散类别。在这种情况下,用户关心的最终目标是分类准确性-正确分类的案例的百分比。

但是,当我们使用神经网络进行分类时,尽管我们的目标是分类准确度,但这并不是神经网络试图优化的目标。神经网络仍在尝试优化实值成本函数。有时这些指向同一方向,但有时却不同。特别是,我一直在遇到这样的情况:经过训练以正确最小化成本函数的神经网络具有比简单的手工编码阈值比较差的分类精度。

我已经使用TensorFlow将其简化为一个最小的测试用例。它建立一个感知器(无隐藏层的神经网络),在绝对最小的数据集(一个输入变量,一个二进制输出变量)上训练它,评估结果的分类精度,然后将其与简单手的分类精度进行比较编码的阈值比较;结果分别是60%和80%。直观地讲,这是因为具有大输入值的单个离群值会产生相应的大输出值,因此,将成本函数最小化的方法是,在对两种以上普通情况进行错误分类的过程中,要尽最大努力适应这种情况。感知器正确地执行了被告知要执行的操作;只是这与我们实际想要的分类器不符。

我们如何训练神经网络,使其最终最大化分类精度?

import numpy as np
import tensorflow as tf
sess = tf.InteractiveSession()
tf.set_random_seed(1)

# Parameters
epochs = 10000
learning_rate = 0.01

# Data
train_X = [
    [0],
    [0],
    [2],
    [2],
    [9],
]
train_Y = [
    0,
    0,
    1,
    1,
    0,
]

rows = np.shape(train_X)[0]
cols = np.shape(train_X)[1]

# Inputs and outputs
X = tf.placeholder(tf.float32)
Y = tf.placeholder(tf.float32)

# Weights
W = tf.Variable(tf.random_normal([cols]))
b = tf.Variable(tf.random_normal([]))

# Model
pred = tf.tensordot(X, W, 1) + b
cost = tf.reduce_sum((pred-Y)**2/rows)
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
tf.global_variables_initializer().run()

# Train
for epoch in range(epochs):
    # Print update at successive doublings of time
    if epoch&(epoch-1) == 0 or epoch == epochs-1:
        print('{} {} {} {}'.format(
            epoch,
            cost.eval({X: train_X, Y: train_Y}),
            W.eval(),
            b.eval(),
            ))
    optimizer.run({X: train_X, Y: train_Y})

# Classification accuracy of perceptron
classifications = [pred.eval({X: x}) > 0.5 for x in train_X]
correct = sum([p == y for (p, y) in zip(classifications, train_Y)])
print('{}/{} = perceptron accuracy'.format(correct, rows))

# Classification accuracy of hand-coded threshold comparison
classifications = [x[0] > 1.0 for x in train_X]
correct = sum([p == y for (p, y) in zip(classifications, train_Y)])
print('{}/{} = threshold accuracy'.format(correct, rows))
Run Code Online (Sandbox Code Playgroud)

des*_*aut 5

我仍然不确定这是否是一个恰当的问题,更不用说适合SO了。不过,我会尝试一下,也许您会发现我的答案中至少有一些要素很有帮助。

我们如何训练神经网络,使其最终最大化分类精度?

我正在寻找一种方法来获得更接近准确性的连续代理功能

首先,并不是用于(深度)神经网络分类任务的损失函数是由他们发明的,但是它可以追溯到几十年前,实际上它来自逻辑回归的早期。这是二进制分类的简单情况的等式:

在此处输入图片说明

其背后的想法恰恰是想出一个连续且可微的函数,这样我们就能够利用凸优化的(庞大且仍在扩展中)来解决分类问题。

可以肯定地说,考虑到上述期望的数学约束,上述损失函数是迄今为止迄今为止最好的。

我们是否应该考虑解决并完成该问题(即更好地近似精度)?至少原则上没有。我的年龄已经足够大,可以记住一个时代,当时实际上仅有的激活功能是tanhsigmoid; 然后来到ReLU,为该领域带来了真正的推动。同样,某人最终可能会提出更好的损失函数,但可以说这将在研究论文中发生,而不是作为SO问题的答案...

也就是说,当前损失函数来自概率论和信息论的非常基本的事实(与深度学习的当前领域形成鲜明对比的领域基于牢固的理论基础)这一事实至少引起了一些疑问一个更好的损失建议可能就在眼前。


关于损失与准确性之间的关系还有另一个微妙的要点,这使得后者与前者在质量上有所不同,并且在此类讨论中经常被忽略。让我详细说明一下...

与该讨论相关的所有分类器(即神经网络,逻辑回归等)都是概率分类器。也就是说,它们不返回硬类成员资格(0/1),而是返回类概率([0,1]中的连续实数)。

为了简化讨论,只限于二进制情况,将类概率转换为(硬)类成员时,我们隐式涉及一个阈值,通常等于0.5,例如if p[i] > 0.5,then class[i] = "1"。现在,我们发现很多情况下,这种天真的默认阈值选择将不起作用(首先想到的是严重失衡的数据集),我们将不得不选择其他情况。但是,对于我们这里的讨论,重要的一点是,这一门槛的选择,而成为至关重要的准确性,完全是对外来减少损失的数学优化问题,并作为它们之间的进一步的“绝缘层”,牺牲简单地说,损失只是准确性的代表(不是)。


在某种程度上扩大了已经很广泛的讨论:我们是否可以完全摆脱连续和可微函数数学优化的(非常)限制约束?换句话说,我们可以消除反向传播和梯度下降吗?

好吧,我们实际上已经这样做了,至少在强化学习这个领域是这样的:2017年是OpenAI关于进化策略的 新研究成为头条新闻的一年。另外,这是优步(Uber)在2017年12月发表的关于该主题的超新鲜论文,再次引起了社区的极大热情


这些是我的想法,基于我对您问题的理解。正如我已经说过的那样,即使这种理解是不正确的,也希望您会在这里找到一些有用的元素...