数学知识
二元一次不等式
当点A(x, y) 满足 y > kx + b 时 A在直线kx+b上半部分 
当点A(x, y) 满足 y = kx + b 时 A在直线kx+b上 
当点A(x, y) 满足 y < kx + b 时 A在直线kx+b下半部分 
tanh函数
函数及其导函数的 图像和数学表达式如下


复合函数的导数
[g(x) * f(x)]′ = g′(x) f(x) + g(x) f′(x) 
[g(x) / f(x)]’ = ( g’(x)f(x) - g(x)f(x) ) / ( f(x)^2 )  
参看微积分的求导法则
激活函数
还没有悟出来,先看下面的例子吧
示例
线性二分类问题
假设数据集(x1, y1), (x2, y2) …. 是线性可分的,对应的标签为l(1, -1, …),求划分直线kx+b
损失函数是什么?((kx+b) - y)^2?
显然不是,因为最终输出的是1,-1的数字。k和b是未知数,
求得k,b需要知道其梯度,而梯度又是靠损失函数得来的
根据上面的二元一次不等式的性质,设置一个函数
f(z) => return z >= 0 ? 1 : -1 
设z=kx+b-y, 那么损失函数为 (f(z) - l)^2
这里 f(z)称之为激活函数,有了它就把k和b参数关联到标签l上了
但是 f(z) 返回值是常数(1或-1),而常数的导数是0, 很难求到偏导数。。。
迂回地,使用上面的tanh函数来代替这里的f(z)。。。因为它们的性质相同,大于0时偏于1,小于0时偏于-1,tanh有导函数
如此便是:
(k, b)’= ((tanh(z) - l)^2)’ 
令 f1 = tanh(z) - l 则  
(k, b)’= 2 * f1 * f1’ 
  = 2 * (tanh(z) - l) * (tanh(z) - l)’ 
  = 2 * (tanh(z) - l) * tanh(z)’ 
  = 2 * (tanh(z) - l) * dtanh(z) * (z)’ 
(k)’= 2*(tanh(z) - l) * dtanh(z) * x 
(b)’= 2*(tanh(z) - l) * dtanh(z) 
这里全靠链式法则推导,心里没什么谱。。。。
示例代码如下:

结果如下

2D平面中的点投影直线的问题
假设(x1, y1),(x2, y2) … 通过变换矩阵得到新的点(u1,v1), (u2, v2) ….
可以通过梯度下降法求出这个变换矩阵,然而这个杀千刀的在结果里边把v丢掉了 给的数字是 (u1/v1), (u2/v2)… 然后去求变换矩阵。。。
这里的激活函数是 f(nx, ny) = nx/ny
损失函数 依然是 (f(nx, ny) - l)^2
求的参数是 a, b, c, d, t1, t2
nx = ax + by + t1 
ny = cx + dy + t2 
(nx/ny - l)^2’ 
= 2(nx/ny - l) * (nx/ny - l)’ 
= 2(nx/ny - l) * 1 * (nx/ny)’ 
= 2(nx/ny - l) * (nx’ny - ny nx’)/(ny ny) 
设 c = 2(nx/ny - l) / (ny ny) 则各个参数的偏导数为:
a’ = c * ny x 
b’ = c * ny y 
c’ = c * (-nx x) 
d’ = c * (-nx y) 
t1’= c*ny 
t2’= c*(-nx) 
示例代码如下:


运行结果如下

3D空间的点投影到2D平面的问题
3维空间中的点P3(x, y, z) 呈现到2D平面上P2(x0, y0),其过程是 变换矩阵M乘以P3得到 NP3,然后做一次齐次变换,即NP3点各个分量除以NP3的z,其x和y就是屏幕上点
已知3维空间的点集合D3 和 映射到平面上点集合D2 求变换矩阵M
一般地,变换矩阵是 4x4 16个数字数字 其实有用的是其中的12个,如下变换后的新点的坐标为:
nx = ax + by + cz + t1 
ny = ex + fy + gz + t2 
nx = ix + jy + kz + t3 
齐次变换之后的2D的点为:
x0 = nx / nz 
y0 = ny / nz 
这里的激活函数有两个 nx / nz 和 ny / nz
损失函数是 (x0 - l[0])^2 + (y[0] - l[1])^2
则导函数为:
((x0 - l[0])^2 + (y[0] - l[1])^2)’ =  
 2(nx/nz - l[0])/(nz*nz) * (nx' nz - nx nz') +  
 2(ny/nz - l[1])/(nz*nz) * (ny' nz - ny nz') 
设
c1 = 2(nx/nz - l[0])/(nz * nz) 
c2 = 2(ny/nz - l[0])/(nz * nz) 
则各个参数的偏导为: 
a' = c1 * nz * x 
b' = c1 * nz * y 
c' = c1 * nz * z 
e' = c2 * nz * x 
f' = c2 * nz * y 
g' = c2 * nz * z  
i' = (c1 * -nx + c2 * -ny) * x 
j' = (c1 * -nx + c2 * -ny) * y 
k' = (c1 * -nx + c2 * -ny) * z 
t1' =  c1 * nz 
t2' =  c2 * nz 
t3' =  (c1 * -nx + c2 * -ny) 
示例代码如下:


运行结果如下:

 
                                 
                                 
                 
             
                            