在深度学习领域,优化技术的目标是最小化损失函数,以减少训练误差并降低泛化误差。本文将探讨线性模型,它们是机器学习中最简单的模型之一,同时也是构建深度神经网络的基础。在监督学习问题中,主要分为回归和分类两大类。回归问题的目标值是实际值,例如,如果有工作描述数据并希望预测该工作将获得多少薪水,这就是一个回归任务,因为薪水是一个实数值。或者,如果有药品库存数据,并有需求(x1)和使用量(x2)变量,以及需要预测的变量(依赖变量)是供应量(y),这也是回归可以解决的问题,因为库存变量是一个实数值。
相对地,如果目标值的数量是有限的,那么它就是一个分类任务。例如,如果想要识别图像中的物体,假设想知道图片中是否有摩托车、汽车、围栏或建筑物或自行车。这是一个物体识别任务。由于物体的数量是有限的,分类可以解决这个问题。或者,如果正在分析一篇文章并想知道主题是什么,无论是关于机器学习、计算机视觉还是深度学习,那也是一个分类任务,因为目标值的数量再次是有限的。
对于样本X,线性模型是权重向量和特征向量X的点积。如果想要将模型应用于整个训练集,那么有一个矩阵X,它有L行和d列。这种乘法产生一个大小为L的向量,每个分量预测线性模型。那么如何衡量模型误差或了解训练或测试集的质量呢?
均方误差(Mean Squared Error)是回归中用于损失函数的流行选择之一。以xi为例,计算这个样本的模型预测是w和xi的乘积,然后从目标值(yi)中减去。然后计算目标值与预测值的偏差,然后取其平方,并在所有训练集上平均偏差的平方。它衡量模型适合数据的程度。均方误差越小,模型对数据的拟合就越好。均方误差以向量形式书写。
机器学习的本质是优化损失以找到最佳模型。因此,最后讨论的函数,通过最小化它来衡量模型对数据的拟合程度。因此,目标是找到一组参数w,使得训练集的均方误差最小。如果对方程求导并求解,那么将得到优化问题的解析解。但这涉及到矩阵的求逆和高度复杂的操作,如果特征数量更多(比如说超过100),找到逆矩阵是非常困难的。回归的线性模型简单但对深度神经网络非常有价值。
如何将线性方法适应于分类问题?逻辑回归。逻辑回归是一个回归模型,可以用于分类问题,从最简单的分类,即二元分类开始,目标上只有两个值(比如说负一和一),负和正,是/否,成功/失败,即使在有多个类别的分类问题中,如强烈同意、同意、强烈反对和反对。
让通过使用Python编程解决一个2D分类问题,使用合成数据,以更好地理解算法的工作原理。
import numpy as np
from sklearn.datasets import make_moons
from matplotlib import pyplot
from pandas import DataFrame
# 生成2D分类数据集
X, y = make_moons(n_samples=1000, noise=0.5)
# 散点图,点按类别值着色
df = DataFrame(dict(x=X[:,0], y=X[:,1], label=y))
colors = {0:'red', 1:'blue'}
fig, ax = pyplot.subplots()
grouped = df.groupby('label')
for key, group in grouped:
group.plot(ax=ax, kind='scatter', x='x', y='y', label=key, color=colors[key])
pyplot.show()
上述代码的输出显示数据不能线性分离。然后必须添加特征或使用非线性模型。因为两个类别之间的决策线是圆形的,可以添加二次部分,使上述数据中的问题线性可分,如下所示。
下一步是添加特征。扩展允许线性模型进行非线性分离。
def expand(X):
X_expanded = np.zeros((X.shape[0], 6))
X_expanded[:, 0] = X[:, 0]
X_expanded[:, 1] = X[:, 1]
X_expanded[:, 2] = X[:, 0] ** 2
X_expanded[:, 3] = X[:, 1] ** 2
X_expanded[:, 4] = X[:, 0] * X[:, 1]
X_expanded[:, 5] = 1
return X_expanded
def probability(X, w):
return 1 / (1 + np.exp(-np.dot(X, w)))
dummy_weights = np.linspace(-1, 1, 6)
predict_prob = probability(X_expanded[:1, :], dummy_weights)[0]
def compute_loss(X, y, w):
l = X.shape[0]
p = probability(X, w)
return -(1.0/l) * np.sum(y * np.log(p) + (1-y) * np.log(1-p))
cross_ent = compute_loss(X_expanded, y, dummy_weights)