[学习笔记] Tangent Distance
Tangent Distance
简介
切空间距离可以用在KNN方法中度量距离,其解决的是图像经过有限变换之后还能否被分类正确,例如。对一张数字为5的手写数字图片,将其膨胀后得到图像p1,此时KNN还应认为p1与原图接近,即距离较近,而不是距离其他类别较近。而Tangent Distance较好的解决了经过图像变换后距离度量的问题,其通过梯度下降算法在切空间中优化求得被分类向量和原始图像及其经过变换后图像的空间中最近的点。
Question

对于上面这张图,我们使用传统的欧式距离,极有可能将左边的图分类成4,而不是9。这暴露出一个问题,传统的欧式距离对旋转、缩放、平移等等变换是不鲁棒的,这就告诉我们我们需要一个新的对于常规变换鲁棒的距离评估标准。
Tangent Vector
切空间向量是如何定义的呢?简单的说,切空间向量的切是指在参数变化方向上的切,即输入图像/向量关于参数的微分。要理解这个,首先我们要先将图像变换数学化(为将问题简单化,我们认为只有一种变换,即旋转变换):
\]
上式表示输入图像x旋转a角度变为xt,我们怎么求旋转变换关于角度a的微分呢?很简单:
\]
这个定义,也就是图像关于a的微分,也就是切空间向量的定义。
那么这个切空间向量有什么用呢,很有用!
我们可以在切线方向也就是切空间里去搜索一种最合适的变换,也就是得到一个最合适的a,使得变换后的图像与原图的欧式距离最小。
一个简单的想法就是穷举出所有的经过变换后的图像,我们将图片每隔1度旋转增广一张,那么肯定能找到一张与所需要分类的图片距离最近的图像。
当然,切空间距离可不是这么简单,上面的想法是让a离散化的想法,实际上a是连续的,我们可以通过梯度下降法来求得一个最为合适的参数a,从而找到最合适的距离。
Tangent Distance
上面我们定义了切空间向量,下面是切空间距离的定义:
\]
这个定义可以这么理解,T由于是参数方向上的微分,乘以系数a然后加上x就是在参数方向上的变换,a取0度,就是不旋转,a取15度就是旋转15度。而a是参数,通过最小化与需要判别图像的欧式距离来得到参数a,继而得到切空间距离。
显然这里优化过程是需要用到梯度下降算法的。
将上式扩展为多种变换,就是对T的定义扩展为矩阵,比如有r种变换,图像像素维度d,则T矩阵就是r x d的。a就是d x 1维度。
Gradient Descent
简答推导一下这里梯度下降的公式:
\]
好了,上面推导完了梯度,可以开始写代码了。
Coding
import cv2 as cv
import numpy as np
import copy
class GradientDescent():
def __init__(self,T):
self.T = T #(2,784)
def __call__(self,x,y):
r,d = self.T.shape # (2,784)
a = np.ones(shape = (r,1)) # (2,1)
t = 0
while True:
b = copy.copy(a)
# (784,2).dot (2,1) -> (784,1) -> (2,1)
a = a - 0.0005 * self.T.dot(x + self.T.T.dot(a) - y)
t += 1
#print(a,b)
if np.sqrt(np.mean((b-a)**2)) < 0.0001 or t > 5000:
break
return a,self.T
class TanhDistance():
def __init__(self,frame,transforms = None):
self.vectors = []
h,w = frame.shape
self.hw = h*w
if transforms is not None:
for transform in transforms:
t = transform(frame) # (h,w)
self.vectors.append(np.reshape(t,(h*w,)) - np.reshape(frame,(h*w,)))
self.gradientDescent = GradientDescent(np.array(self.vectors)) # r,28*28
def __call__(self,x,y):
x = np.reshape(x,(self.hw,1))
y = np.reshape(y,(self.hw,1))
a,T = self.gradientDescent(x,y) # (28*28,1)
return np.sqrt(np.mean((x + T.T.dot(a) - y)**2))
def get_transforms(frame):
h,w = frame.shape
transformations = []
# rotate
delta_theta = 5
M = cv.getRotationMatrix2D(((w-1)/2.0,(h-1)/2.0),delta_theta,1)
transformations.append(lambda x:cv.warpAffine(x,M,(w,h)))
# shift
delta_x = 2
delta_y = 0
M = np.float32([[1,0,delta_x],[0,1,delta_y]])
transformations.append(lambda x:cv.warpAffine(x,M,(w,h)))
return transformations
if __name__ == "__main__":
img = cv.imread("/home/xueaoru/图片/0000.jpg")
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
gray = cv.resize(gray,(28,28))/255
transforms = get_transforms(gray)
metric = TanhDistance(gray,transforms)
img2 = cv.imread("/home/xueaoru/图片/000.jpg")
gray2 = cv.cvtColor(img2,cv.COLOR_BGR2GRAY)
gray2 = cv.resize(gray2,(28,28))/255
print("tan distance:{}".format(metric(gray,gray2)))
print("l2 distance:{}".format(np.sqrt(np.mean((gray - gray2)**2))))
#for transform in transforms:
# print(transform(gray))
所用图片:


距离结果:
tangent distance:0.3062723225969733
l2 distance:0.336102326896069Q
[学习笔记] Tangent Distance的更多相关文章
- ArcGIS JS 学习笔记1 用ArcGIS JS 实现仿百度地图的距离量测和面积量测
一.开篇 在博客注册了三年,今天才决定写第一篇博客,警告自己不要懒!!! 二.关于ArcGIS JS 版本选择 在写这篇博客时ArcGIS JS 4.0正式版已经发布.它和3.x版本的不同是,Map不 ...
- <老友记>学习笔记
这是六个人的故事,从不服输而又有强烈控制欲的monica,未经世事的千金大小姐rachel,正直又专情的ross,幽默风趣的chandle,古怪迷人的phoebe,花心天真的joey——六个好友之间的 ...
- 【Unity Shaders】学习笔记——SurfaceShader(十一)光照模型
[Unity Shaders]学习笔记——SurfaceShader(十一)光照模型 转载请注明出处:http://www.cnblogs.com/-867259206/p/5664792.html ...
- 【Unity Shaders】学习笔记——SurfaceShader(九)Cubemap
[Unity Shaders]学习笔记——SurfaceShader(九)Cubemap 如果你想从零开始学习Unity Shader,那么你可以看看本系列的文章入门,你只需要稍微有点编程的概念就可以 ...
- 【Unity Shaders】学习笔记——SurfaceShader(七)法线贴图
[Unity Shaders]学习笔记——SurfaceShader(七)法线贴图 转载请注明出处:http://www.cnblogs.com/-867259206/p/5627565.html 写 ...
- DirectX 11游戏编程学习笔记之8: 第6章Drawing in Direct3D(在Direct3D中绘制)(习题解答)
本文由哈利_蜘蛛侠原创,转载请注明出处.有问题欢迎联系2024958085@qq.com 注:我给的电子版是700多页,而实体书是800多页,所以我在提到相关概念的时候 ...
- osgEarth学习笔记(转载)
osgEarth学习笔记1. 通过earth文件创建图层时,可以指定多个影像数据源和多个高程数据源,数据源的顺序决定渲染顺序,在earth文件中处于最前的在渲染时处于最底层渲染:所以如果 ...
- Unity3D 骨骼动画原理学习笔记
最近研究了一下游戏中模型的骨骼动画的原理,做一个学习笔记,便于大家共同学习探讨. ps:最近改bug改的要死要活,博客写的吭哧吭哧的~ 首先列出学习参考的前人的文章,本文较多的参考了其中的表述: 1. ...
- ArcGIS API for JavaScript 4.2学习笔记[21] 对3D场景上的3D要素进行点击查询【Query类学习】
有人问我怎么这个系列没有写自己做的东西呢? 大哥大姐,这是"学习笔记"啊!当然主要以解读和笔记为主咯. 也有人找我要实例代码(不是示例),我表示AJS尚未成熟,现在数据编辑功能才简 ...
随机推荐
- Linux下的打包操作
范例一:将整个 test 目录下的文件全部打包成为 test.tar[python@master ~]$ tar -cvf test.tar test/ ==仅打包,不压缩!test/ ...
- java_day06_java高级特性
Advance Java Programming 第六章: java语言高级特性(part1) 1.static修饰符 1)static变量 在类中,使用static修饰的成员变量,就是静态变量,反之 ...
- scroll js 原生
1.当前位置滚动: document.documentElement.scrollTop 当前位置: 有可能是0 window.scrollTo(,document.documentElement.s ...
- main特别之处
//package new_Object; public class Main{ public static void main(String[] args) { System.out.println ...
- MySQL 安装与基本概念
Mysql版本 第一条产品线:5.0.xx及升级到5.1.xx的产品系列,这条产品线继续完善与改进其用户体验和性能,同时增加新功能,这条路线可以说是MySQL早期产品的延续系列,这一系列的产品发布情况 ...
- Mark点
MARK点是PCB应用于设计中的自动贴片机上的位置识别点,也被称为基准点.直径为1MM.钢网Mark点是电路板贴片加工中PCB印刷锡膏/红胶时的位置识别点.Mark点的选用直接影响钢网的印刷效率,确保 ...
- vim文本编辑及文件查找应用1
vim编辑器: 文本编辑器: 文本:纯文本,ASCII text;Unicode(全球通用); 文本编辑种类: 行编辑器:sed 全屏编辑器:nano, ...
- 在RecyclerView中集成QQ汽泡一
上次已经实现了QQ汽泡的自定义View的效果[http://www.cnblogs.com/webor2006/p/7726174.html],接着再将它应用到列表当中,这样才算得上跟QQ的效果匹配, ...
- 第十五届四川省省赛 SCU - 4443 Range Query
先给你1~N的N个数 再给你每种最多50个的条件(ai,bi,ci) 或者[ai,bi,ci] (ai,bi,ci)表示下标ai到bi的最小值必为ci [ai,bi,ci]表示下标ai到bi的最大值必 ...
- Nginx location模块整理
location模块 Nginx location location 指令的作用是根据用户请求的URI来执行不同的应用,URI就是根据用户请求到的网址URL进行匹配,匹配成功了进行相关的操作. loc ...