​ 之前我们讲了K-NN算法,通过将未知数据点和训练集中的数据点做比较,用样本点之间的距离作为度量,然后从训练集中k个最相似的样本中,通过“选举”的方式,获得最高投票的类别获胜,作为最后分类的结果。

​ 虽然简单直观,但是也有很多缺点:

  • 实际上没有"学习"任何东西,如果算法出错,那么它将无法在接下来的分类中自动改正。
  • 如果不指定数据结构,k-NN算法占用的空间将随着数据集中样本点数量的增大而增大。当使用数据集维度巨大的的时候,使得其不论在实际还是理论上去使用都具有很大的挑战性。

显然,如果我们每次做分类预测的时候都保存着一份几百GB甚至TB的训练集,这显然是不太合理的。我们需要一种学习模型能够在训练时从输入数据学习模式(需要更多的时间来训练模型),但是通过少量参数来定义模型的好处是可以轻松的表示模式,而不需要管训练集的大小。这种机器学习的方式称为:参数化学习

“A learning model that summarizes data with a set of parameters of fifixed size

(independent of the number of training examples) is called a parametric model. No

matter how much data you throw at the parametric model, it won’t change its mind

about how many parameters it needs.” – Russell and Norvig (2009) [73]

总的来说,参数化学习最大的作用就是可以脱离数据集,通过定义参数的方式来表示模型。

本文将讨论参数化学习的概念,并实现一个简单的线性分类器。

什么是参数化学习?

​ 简单来说,参数化学习就是为给定的模型定义必要参数的过程。

​ 对于机器学习来说,参数话学习设计定义模型四个组成成分:

  • Data
  • scoring function
  • Loss function
  • Weights and Biases

Data:我们将要学习的,输入的数据。包括样本点和与样本点所联系的标签。通常我们将输入的数据表示为一个多维的矩阵,矩阵中的每一行代表一个样本点,每一列代表一个特征。伴随与此的还有一个标签向量y,其中yi表示数据集中第i个样本点的标签。

Scoring function:Scoring function将我们输入的Data映射为类别标签。如果我们将其data定义为input_data,Scoring function定义为func( ),类别标签定义为output_label,那么有:
func(input_data)=output_labelfunc(input\_data) = output\_label func(input_data)=output_label
Loss function:对我们的预测结果与真实值的符合程度进行定量,预测结果越符合真实值,loss越低,精度越高(最起码在训练集上是这样),我们训练机器学习模型的目标就是使Loss function最小,以此来提升预测的精度。

Weights & Biases:我们实际上要优化的参数,基于Scoring function和loss function的输出,我们会调整weights和Biases的值来提升准确性。

接下来让我们看看这些部分如何组成一个线性分类器吧。

假设数据集表示为Xi,其中每一个样本点有着对应的标签yi,假设共有N个样本点,K个标签类别。通过这些标量我们可以定义我们的scoring function为
f(xi,W,b)=Wxi+bf(x_i,W,b) = Wx_i+b f(xi​,W,b)=Wxi​+b

参数化学习和线性分类的优势
  • 一旦完成模型的训练,就不再需要训练集,只要保留矩阵W和向量b即可

  • 对于新的测试数据分类速度极快。只需要和矩阵W进行一次点乘再加上向量b即可。


接下来让我们用Python实现一个简单的线性分类器。

需要学习的几个方法:

np.random.seed()

指定伪随机数生成器的“种子”。

个人理解,所谓种子就是指标志。我们在使用随机数生成器生成随机数时,并非是每次真的随机生成一个数组,而是从一个随机数序列中按照次序返回给我们若干个随机数。而这些随机数队列不可能只有一个,每个随机数队列的标志则称为种子(非官方解释,自己的理解)。

举个例子,在随机数生成器中有3个队列,里面存放着大量固定顺序的随机数,如下:

[0.1231,0.3456,0.7739,0.1435,0.7564,0.7653,0.9876,0.4444]
[0.7656,0.3546,0.1236,0.4265,0.1235,0.9999,0.2246,0.6548]
[0.5564,0.1134,0.4378,0.9806,0.5643,0.8789,0.2234,0.2145]

当我们指定np.random.seed(1)的时候,就会从1所代表的队列中按照顺序返回随机数。

当我们指定np.random.seed(2)的时候,就会从2所代表的队列中按照顺序返回随机数。

np.random.randn()

返回一个或一组服从标准正态分布的随机样本值。

当不传入参数时,返回一个浮点数。

当传入一个参数时,返回一个秩为1的数组。

当传入两个参数及以上时,返回对应维度的矩阵,可以表示对应的向量或者矩阵。

flatten()

将一个矩阵折叠成一个一维的数组,作用对象只能是NumPy数组或者Mat。

cv2.putText(image, content,startPoint, Font, size, color, thickness)

作用:在图片上写文字

参数:

image:要写在哪幅图上

content:字符串,要写的文字内容

startPoint:坐标二元组(x,y),表示字符串在图片上的起点位置

font:要使用的字体

size:文字的大小

color:颜色三元组(b,g,r),表示文字的颜色

thickness:文字的粗细

新建一个Linear_classifier.py文件写入如下代码:

import numpy as np
import cv2labels = ["squirrel", "dog", "cat"]np.random.seed(1)W = np.random.randn(3, 3072)
b = np.random.randn(3)origin = cv2.imread("./animal.png")
image= cv2.resize(origin, (32, 32)).flatten()scores = W.dot(image) + bfor(label, score) in zip(labels, scores):print("[INFO]{}:{:.2f}".format(label, score))cv2.putText(origin, "Label:{}".format(labels[np.argmax(scores)]),(10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 0, 255), 2)cv2.imshow("result", origin)
cv2.waitKey(0)

着这个例子并没有从头到尾演示如何训练模型,而是简单的展示了一下我们如何初始化weight矩阵W和bias向量b,并用这些参数通过点乘来分类一副图像。

​ 我们的目标是正确的对下面的松鼠图像进行分类:

第4行初始化了目标类别标签,一共有三个标签:“squirrel", “dog”, “cat”

第6行设置了一个伪随机数的生成器,确保我们的实验结果可以重现

第8行初始化了我们的weight矩阵W,通过在[0,1]之间的标准正态分布中进行采样

第9行初始化了bias向量b,共3行,与分类标签数相对应

第11行从我们的电脑上读入一张图片,定义为矩阵"origin"

第12行将我们的矩阵“origin”拉伸为一个3072维度的向量image

第14行对我们的向量image执行scoring function

第16-17行将scoring function 输出结果按照类别打印到控制台

第19和20行将最终预测的类别结果标记在原来的标签上,并展示出来

如果我们是从头开始对这个线性分类器进行训练,我们需要通过一步步优化对W和b进行学习,但由于我们目前只是简单的演示一下过程,所以我用1来初始化了伪随机数数字生成器,来确保随机值能够给我们提供一个正确的分类结果(在实验之前提前测试过生成的随机数结果)。现在,我们仅需要吧矩阵W和向量b当作是经过某种神奇优化的“黑箱数组”,后面会学习其中的实现细节。

下来让我们执行linear_classifier.py文件

控制台输出以下结果:

[INFO]squirrel:7153.79
[INFO]dog:2259.43
[INFO]cat:1749.35

注意到”squirrel“标签获得了scoring function的最大值,这意味着分类器选择“squirrel”类作为最终的预测结果,我们可以看到,程序将分类结果“squirrel”写在了图片上。

但是我们要记住,我们这里给出的W和b都是特定好的,在实际中,如果我们不通过学习来得到W和b,我们将无法让分类器预测出正确的结果,本文中只是为了简化分类器预测的过程,所以仅仅将W和b进行了初始化。

Loss function

​ 参数化学习的过程其实就是通过一系列参数并不断优化他们,来学习一种方法,这种方法可以将输入的数据映射为最终输出的结果。

​ 但是为了真正意义上的“学习”这种映射,我们还需要探讨两个概念:

  • Loss functions
  • Optmization

什么是Loss Function?

​ 实际上,损失函数就是用来衡量我们所给定的预测器在对数据集中的样本点进行分类时的“好”“坏”程度。

​ 为了提高我们的分类精度,我们需要去调节weight矩阵W和biases向量b的参数。在理想条件下,我们的损失(loss)会随着我们调整模型参数的次数(时间)而下降。

多类别的支持向量机损失

​ 多分类向量损失的灵感来自于支持向量机。支持向量机的scoring function表示为:
f(xi,W,b)=Wxi+bf(x_i,W,b) = Wx_i+b f(xi​,W,b)=Wxi​+b
​ 现在我们有了socring function,我们需要来确定这个函数在做预测时候的表现是好是坏,所以我们需要一个loss function.

为了简化,将我们的scoring function用**s**来表:

s=f(xi,W)s = f(x_i,W) s=f(xi​,W)
​ 第 i 个样本点 被预测为第 j 类的scoring function的输出为:
sj=f(xi,W)js_j = f(x_i,W)_j sj​=f(xi​,W)j​
通过这样的表示,我们可以将他们放在一起,获得 铰链损失函数(hinge loss function)
Li=∑j≠yimax(0,sj−syi+1)L_i = \sum_{j≠y_i}max(0,s_j-s_{y_i}+1) Li​=j​=yi​∑​max(0,sj​−syi​​+1)
​ 铰链损失函数把所有不正确的类别(i ≠ j )加起来,并比较我们为第j类标签(不正确的类)和第yi类(正确的类)返回的评分函数s的输出,用最大值函数来把值钳制在0出,这对与确保我们不会加上负数很重要。

​ 当损失Li = 0 的时候,一个给定的样本点xi就被正确分类了。TODO(因为说明其他类别的预测值小于正确类别的预测值,sj - syi + 1 <= 0 => sj - syi <= 1 )

​ 为了推导出整个训练集的损失,我们简单的取每个Li之和的平均数:
L=1N∑i=1NLiL=\frac{1}{N}\sum^{N}_{i=1}L_i L=N1​i=1∑N​Li​
​ 另一种你可能会遇到的相关的损失函数:平方铰链损失函数


Li=∑j≠yimax(0,sj−syi+1)2L_i =\sum_{j≠y_i}max(0,s_j-s_{y_i}+1)^2 Li​=j​=yi​∑​max(0,sj​−syi​​+1)2
​ 平方项会通过将输出平方来加重处罚损失,这会导致不正确预测的损失以4次方增长。

​ 具体选择那种损失函数依据情况而定,一般来说标准的铰链损失函数更加常用,但是在某些数据集上平方铰链损失函数表现更好,毕竟这是需要我们去调整的超参数(hyperparameter)

·

交叉熵损失和Softmax分类器

​ 和铰链损失最大的区别: 铰链损失呈现的是间隔,而Softmax分类器呈现的是每一个类别标签的概率,更便于人们理解。

​ Softmax分类器是二值化形式的逻辑回归的一般化,如同铰链损失和平方铰链损失一样,我们的函数 f 接收一组输入数据xi , 并通过和矩阵W点乘运算,再加上向量b,将它们映射为输出数据标签
f(xi,W,b)=Wxi+bf(x_i,W,b)=Wx_i+b f(xi​,W,b)=Wxi​+b
​ 但是,和铰链损失不同的是,我们可以将输出的值解释为每个类别标签的非标准的对数概率,我们用交叉熵损失来代替铰链损失:
Li=−logP(esyi∑jesj)L_i=-logP(\frac{e^{s_{y_i}}}{\sum_{j}e^{s_j}}) Li​=−logP(∑j​esj​esyi​​​)
​ 让我们来推理一下这个公式。首先,我们的损失函数应该最小化正确类别的 概率,也就是最大化正确类别的对数概率,也就是最小化正确类别的负对数概率
Li=−logP(Y=yi∣x=xi)L_i=-logP(Y=y_i|x=x_i) Li​=−logP(Y=yi​∣x=xi​)
​ 上式中概率的部分可以表示为:
P(Y=k∣x=xi)=esyi/∑jesjP(Y=k|x=x_i)=e^{s_{y_i}}/\sum_j e^{s_j} P(Y=k∣x=xi​)=esyi​​/j∑​esj​
​ 其中:
s=f(xi,W,b)s=f(x_i,W,b) s=f(xi​,W,b)
​ 综上所述,最终对于单个样本点的损失函数就变成了上面所描述的:
Li=−logP(esyi∑jesj)L_i=-logP(\frac{e^{s_{y_i}}}{\sum_{j}e^{s_j}}) Li​=−logP(∑j​esj​esyi​​​)
​ 最后通过求平均数来计算整个数据集上所有样本点的交叉熵损失:
1N∑i=1NLi\frac{1}{N} \sum^{N}_{i=1}L_i N1​i=1∑N​Li​

参考书籍:Deep Learning For Computer Vision With Python

计算机视觉1.8:参数化学习相关推荐

  1. 威尔士柯基犬,计算机视觉,以及深度学习的力量

    威尔士柯基犬,计算机视觉,以及深度学习的力量 微软亚洲研究院 2014年7月18日   编者按:在上一篇博文中,我们介绍了Adam项目的效果及未来应用:用计算机视觉智能地识别物体.现在让我们走近这项技 ...

  2. 三维图形几何变换算法实验_计算机视觉方向简介 | 深度学习视觉三维重建

    点击上方"计算机视觉life",选择"星标" 快速获得最新干货 作者: Moonsmile https://zhuanlan.zhihu.com/p/79628 ...

  3. 【计算机视觉】opencv入门学习笔记Part.1

    [计算机视觉]opencv入门学习笔记Part.1 1 前言 1.1 opencv概述(摘取自百度百科) 1.2 图像概念引入 1.3 安装opencv库 2 图像基本操作 2.1 图像的读取 2.2 ...

  4. CV:计算机视觉技最强学习路线之CV简介(传统视觉技术/相关概念)、早期/中期/近期应用领域(偏具体应用)、经典CNN架构(偏具体算法)概述、常用工具/库/框架/产品、环境安装、常用数据集、编程技巧

    CV:计算机视觉技最强学习路线之CV简介(传统视觉技术/相关概念).早期/中期/近期应用领域(偏具体应用).经典CNN架构(偏具体算法)概述.常用工具/库/框架/产品.环境安装.常用数据集.编程技巧 ...

  5. <计算机视觉 六> 深度学习目标检测模型的评估标准

    鼠标点击下载     项目源代码免费下载地址 <计算机视觉一> 使用标定工具标定自己的目标检测 <计算机视觉二> labelme标定的数据转换成yolo训练格式 <计算机 ...

  6. 计算机视觉那些事 | 深度学习基础篇

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 1.写在前面 随着人工智能尤其是深度学习的快速发展,计算机视觉成为 ...

  7. CV:计算机视觉技最强学习路线

    CV:计算机视觉技最强学习路线之CV简介(传统视觉技术/相关概念).早期/中期/近期应用领域(偏具体应用).经典CNN架构(偏具体算法)概述.常用工具/库/框架/产品.环境安装.常用数据集.编程技巧_ ...

  8. 计算机视觉面试宝典--深度学习机器学习基础篇(四)

    计算机视觉面试宝典–深度学习机器学习基础篇(四) 本篇主要包含SVM支持向量机.K-Means均值以及机器学习相关常考内容等相关面试经验. SVM-支持向量机 支持向量机(support vector ...

  9. 荐书:《计算机视觉:模型、学习和推理》

    中文版书名:<计算机视觉:模型.学习和推理> 英文书名:Computer Vision: Models, Learning, and Inference, by Simon J.D.Pri ...

最新文章

  1. [引]ASP.NET IIS 注册工具 (Aspnet_regiis.exe)
  2. 170728、单例模式的三种水平代码
  3. 浏览器打开位置服务器,如何启动http服务器,然后打开web浏览器?
  4. 如何使用腾讯云提供的虚拟主机
  5. 软件开发工具(第2章:软件开发过程及其组织)
  6. asp.net core AuthenticationMiddleware 在WebApi中的的使用
  7. cc2530i2c可同时接受两个传感器的数据吗_汽车方向及维修_玉树沃尔沃S40方向机,宝马531电子方向机进水可以维修吗...
  8. mysql数据库架构_MySQL数据库之互联网常用架构方案
  9. java官网门户源码 SSM框架 自适应-响应式 freemarker 静态模版引擎
  10. - -||计算机专业就业前景
  11. java人脸识别Demo(数据库mongo)
  12. 批量添加手机联系人:csv/excel转vcf
  13. 我的世界服务器租服_我的世界中国版开服教程 网易国服怎么租赁服务器
  14. 代购类网站商品高清晰大图片(1000x1000)的采集解决方案 - hackercai - 博客园
  15. 人民币与美元汇率兑换程序
  16. ICON图标设计零基础到精通(UI进阶)
  17. cpu排行计算机专业,cpu性能天梯图,教您电脑cpu排行榜
  18. 人工智能数学基础10:域、函数及相关概念
  19. springboot的商品设计热销排行实现
  20. 【RTSCon 2022】实时通信与价值赋能

热门文章

  1. 万物皆可 Hook,探究 Xposed 框架 Hook 原理
  2. Spark大数据平台应用实战
  3. 专业电影色调PR调色/FCP调色/达芬奇调色LUT预设
  4. 定时清理mysql表数据
  5. 【以太网通信】RGMII 接口及其时序规范
  6. 配置nginx.conf实现80端口重定向至443(http跳转https)
  7. HEX eiditor的安装教程(windows版本)
  8. java mina http_mina的HTTP性能测试
  9. 3. iphone项目如何联机调试和发布程序(99$)
  10. 前端还是java哪个更累_前端开发和后端开发的区别?这两者哪个更累?