课后作业(一):如何建立一个线性分类器并进行优化

2017 年 12 月 21 日 论智 Bot
来源:sandipanweb
编译:Bot

编者按:之前,论智曾在TOP 10:初学者需要掌握的10大机器学习(ML)算法介绍了一些基础算法及其思路,为了与该帖联动,我们特从机器学习热门课程HSE的Introduction to Deep Learning和吴恩达的Neural Networks and Deep Learning中挑选了一些题目,演示Python、TensorFlow和Keras在深度学习中的实战应用.

“课后作业”第一题如何建立一个线性分类器并进行优化,来自HSE。注:本文所列代码可能并非完整答案,请参考注释思路自行尝试。

在这个任务中,我们将实现一个线性分类器,并用numpy和随机梯度下降算法对它进行训练。

二元分类

为了更直观,我们用人造数据(synthetic data)解决二元分类问题。

上图中有红、蓝两类数据,从分布上看它们不是线性可分的。所以为了分类,我们应该在里面添加特征或使用非线性模型。请注意,图中两类数据的决策边缘都呈圆形,这意味着我们能通过建立二元特征来使它们线性分离,具体思路如下图所示:

用expand函数添加二次函数后,我们得到了这样的测试结果:

  
    
    
    
  1. # 简单的随机数测试

  2. dummy_X = np.array([

  3.        [0,0],

  4.        [1,0],

  5.        [2.61,-1.28],

  6.        [-0.59,2.1]

  7.    ])

  8. # 调用expand函数

  9. dummy_expanded = expand(dummy_X)

  10. # 它应该返回这些值:   x0       x1       x0^2     x1^2     x0*x1    1

  11. dummy_expanded_ans = np.array([[ 0.    ,  0.    ,  0.    ,  0.    ,  0.    ,  1.    ],

  12.                               [ 1.    ,  0.    ,  1.    ,  0.    ,  0.    ,  1.    ],

  13.                               [ 2.61  , -1.28  ,  6.8121,  1.6384, -3.3408,  1.    ],

  14.                               [-0.59  ,  2.1   ,  0.3481,  4.41  , -1.239 ,  1.    ]])


logistic回归

曾经我们提到过,logistic回归非常适合二元分类问题。为了分类对象,我们需要预测对象表示为1(默认类)的概率,这就需要用到线性模型和逻辑函数的输出:


  
    
    
    
  1. def probability(X, w):

  2.    """

  3.    对输入赋值特征和权值

  4.    根据上式,返回输入x后y==1的预测概率,P(y=1|x)

  5.    :参数 X: feature matrix X of shape [n_samples,6] (expanded) →特征矩阵X

  6.    :参数 w: weight vector w of shape [6] for each of the expanded features →权值向量w

  7.    :返回值: 范围在 [0,1] 之间的一系列概率.

  8.    """

  9.    return 1. / (1 + np.exp(-np.dot(X, w)))

在logistic回归中,我们能通过最小化交叉熵发现最优参数w:


  
    
    
    
  1. def compute_loss(X, y, w):

  2.    """

  3.    将特征矩阵X [n_samples,6], 目标向量 [n_samples] of 1/0,

  4.    以及权值向量 w [6]代入上述公式, 计算标量的损失函数.

  5.    """

  6.    return -np.mean(y*np.log(probability(X, w)) + (1-y)*np.log(1-probability(X, w)))

由于用了梯度下降算法训练模型,我们还需要计算梯度,具体来说,就是要对每个权值的损失函数求导:

以下是具体的数学计算过程(也可点击https://math.stackexchange.com/questions/477207/derivative-of-cost-function-for-logistic-regression/2539508#2539508查看):


  
    
    
    
  1. def compute_grad(X, y, w):

  2.    """

  3.    将特征矩阵X [n_samples,6], 目标向量 [n_samples] of 1/0,

  4.    以及权值向量 w [6]代入上述公式, 计算每个权值的导数vector [6].

  5.    """

  6.    return np.dot((probability(X, w) - y), X) / X.shape[0]


训练

现在我们已经建立了函数,接下来就该用随机梯度下降训练分类器了。我们将试着调试超参数,如batch size、学习率等,来获得最佳设置。

Mini-batch SGD

不同于满梯度下降,随机梯度下降在每次迭代中只需要一个随机样本来计算其损失的梯度,并进入下一个步骤:


  
    
    
    
  1. w = np.array([0, 0, 0, 0, 0, 1]) # 初始化

  2. eta = 0.05 # 学习率

  3. n_iter = 100

  4. batch_size = 4

  5. loss = np.zeros(n_iter)

  6. for i in range(n_iter):

  7.    ind = np.random.choice(X_expanded.shape[0], batch_size)

  8.    loss[i] = compute_loss(X_expanded, y, w)

  9.    dw = compute_grad(X_expanded[ind, :], y[ind], w)

  10.    w = w - eta*dw

下图展示了当batch size=4时,决策面(decision surface)和交叉熵损失函数如何随着不同batch的SGD发生变化。

左:决策面;右:损失函数

用Momentum优化SGD

Momentum是模拟物理里动量的概念,如下图所示,它能在相关方向加速SGD,抑制振荡,从而加快收敛。从计算角度说,就是对上一步骤更新向量和当前更新向量做加权平均,将其用于当前计算。

  
    
    
    
  1. eta = 0.05 # 学习率

  2. alpha = 0.9 # momentum

  3. nu = np.zeros_like(w)

  4. n_iter = 100

  5. batch_size = 4

  6. loss = np.zeros(n_iter)

  7. for i in range(n_iter):

  8.    ind = np.random.choice(X_expanded.shape[0], batch_size)

  9.    loss[i] = compute_loss(X_expanded, y, w)

  10.    dw = compute_grad(X_expanded[ind, :], y[ind], w)

  11.    nu = alpha*nu + eta*dw

  12.    w = w - nu

下图展示了引入Momentum后,当batch size=4时相应决策面和交叉熵损失函数随不同batch SGD+momentum发生的变化。可以看出,损失函数下降速度明显加快,更快收敛。

左:决策面;右:损失函数

RMSprop

加快收敛速度后,之后我们要做的是调整超参数学习率,这里我们介绍Hinton老爷子的RMSprop。这是一种十分高效的算法,利用梯度的平方来调整学习率:

  
    
    
    
  1. eta = 0.05 # 学习率

  2. alpha = 0.9 # momentum

  3. G = np.zeros_like(w)

  4. eps = 1e-8

  5. n_iter = 100

  6. batch_size = 4

  7. loss = np.zeros(n_iter)

  8. for i in range(n_iter):

  9.    ind = np.random.choice(X_expanded.shape[0], batch_size)

  10.    loss[i] = compute_loss(X_expanded, y, w)

  11.     dw = compute_grad(X_expanded[ind, :], y[ind], w)

  12.     G = alpha*G + (1-alpha)*dw**2

  13.     w = w - eta*dw / np.sqrt(G + eps)

下图是使用了SGD + RMSProp后决策面和损失函数的变化情况,较之之前,函数下降更快,收敛也更快。

原文地址:sandipanweb.wordpress.com/

课程地址:www.coursera.org/specializations/aml

登录查看更多
1

相关内容

在机器学习领域,分类的目标是指将具有相似特征的对象聚集。而一个线性分类器则透过特征的线性组合来做出分类决定,以达到此种目的。对象的特征通常被描述为特征值,而在向量中则描述为特征向量。
【新书册】贝叶斯神经网络,41页pdf
专知会员服务
174+阅读 · 2020年6月3日
专知会员服务
137+阅读 · 2020年5月19日
Sklearn 与 TensorFlow 机器学习实用指南,385页pdf
专知会员服务
126+阅读 · 2020年3月15日
Python数据分析:过去、现在和未来,52页ppt
专知会员服务
99+阅读 · 2020年3月9日
专知会员服务
112+阅读 · 2019年12月24日
如何选择合适的损失函数,请看......
算法与数学之美
5+阅读 · 2019年9月8日
sklearn 与分类算法
人工智能头条
7+阅读 · 2019年3月12日
从零开始深度学习第8讲:利用Tensorflow搭建神经网络
从示例中理解SVM算法(附代码)
论智
9+阅读 · 2018年5月10日
免费|机器学习算法Python实现
全球人工智能
5+阅读 · 2018年1月2日
算法优化|梯度下降和随机梯度下降 — 从0开始
全球人工智能
7+阅读 · 2017年12月25日
动手写机器学习算法:SVM支持向量机(附代码)
七月在线实验室
12+阅读 · 2017年12月5日
BAT题库 | 机器学习面试1000题系列(第191~195题)
七月在线实验室
6+阅读 · 2017年11月15日
用 Scikit-Learn 和 Pandas 学习线性回归
Python开发者
9+阅读 · 2017年9月26日
Arxiv
7+阅读 · 2020年3月1日
Arxiv
20+阅读 · 2019年9月7日
Few Shot Learning with Simplex
Arxiv
5+阅读 · 2018年7月27日
W-net: Bridged U-net for 2D Medical Image Segmentation
Arxiv
19+阅读 · 2018年7月12日
Arxiv
9+阅读 · 2018年3月28日
Arxiv
25+阅读 · 2018年1月24日
VIP会员
相关VIP内容
【新书册】贝叶斯神经网络,41页pdf
专知会员服务
174+阅读 · 2020年6月3日
专知会员服务
137+阅读 · 2020年5月19日
Sklearn 与 TensorFlow 机器学习实用指南,385页pdf
专知会员服务
126+阅读 · 2020年3月15日
Python数据分析:过去、现在和未来,52页ppt
专知会员服务
99+阅读 · 2020年3月9日
专知会员服务
112+阅读 · 2019年12月24日
相关资讯
如何选择合适的损失函数,请看......
算法与数学之美
5+阅读 · 2019年9月8日
sklearn 与分类算法
人工智能头条
7+阅读 · 2019年3月12日
从零开始深度学习第8讲:利用Tensorflow搭建神经网络
从示例中理解SVM算法(附代码)
论智
9+阅读 · 2018年5月10日
免费|机器学习算法Python实现
全球人工智能
5+阅读 · 2018年1月2日
算法优化|梯度下降和随机梯度下降 — 从0开始
全球人工智能
7+阅读 · 2017年12月25日
动手写机器学习算法:SVM支持向量机(附代码)
七月在线实验室
12+阅读 · 2017年12月5日
BAT题库 | 机器学习面试1000题系列(第191~195题)
七月在线实验室
6+阅读 · 2017年11月15日
用 Scikit-Learn 和 Pandas 学习线性回归
Python开发者
9+阅读 · 2017年9月26日
Top
微信扫码咨询专知VIP会员