tensorflow with求导_TensorFlow - 求导

本文详细介绍了TensorFlow中的求导概念,从函数、反函数、复合函数、极限到导数的计算,包括有限差分法和链式法则。通过C++和双数(dual number)方法展示了求导的程序实现,并探讨了偏导数的计算。
摘要由CSDN通过智能技术生成

从函数开始说明TensorFlow是如何求导的

flyfish

函数

定义域是关于输入的

上域是关于输出的

值域实际上是上域的一个子集

上域是可能输出的集合

值域则是实际输出的集合.

[a, b] 这种形式表示的区间我们称作闭区间.

(a, b) 这种形式表示的区间称作开区间.

(a, b] 包括 b, 但不包括 a.像这样的区间称作半开区间.

反函数

如果f(x)=y,那么f−1(y)=x

变换f−1就像是f的撤销按钮。

类似Ctrl+Z的撤销操作

函数的复合(Function composition)

对于函数f(x)=cos(x2),我们令g(x)=x2,h(x)=cos(x),那么f(x)=h(g(x)),也可表示为f=h 。g,这里的圈是复合符号,表示“与……的复合”,即f是g与h的复合。

读法

The notation g ∘ f is read as

“g circle f “,

“g round f “,

“g composed with f “,

“g after f “,

“g following f “,

“g of f”,

“g on f “.

用C++表达类似

有两个函数g和f

float x, y, z;

// ...

y = g(x);

z = f(y);

或者

z=f(g(x));

极限

limx→2f(x)=1

读作“当x趋于2,f(x)的极限等于1”。

平局速率

平均速率是行使距离除以行驶时间

v=s/t

瞬时速度

v=change inschange int=ΔsΔt

Δt=t1−t0

由于t1非常靠近t0,两时刻的差值 h

v=Δf(t)Δt=f(t+h)−f(t)(t+h)−(t)=f(t+h)−f(t)h

v=limΔt→0ΔsΔt=dsdt

解释

Distinction between speed and velocity(速率和速度之间的区别)

Speed describes only how fast an object is moving, whereas velocity gives both how fast it is and in which direction the object is moving.

速率只描述物体运动的快慢,而速度则给出物体运动的快慢和方向。

求导例子 f(a)=a2

f′(a)=limh→0f(a+h)−f(a)h=limh→0(a+h)2−a2h=limh→0a2+2ah+h2−a2h=limh→02ah+h2h=limh→0(2a+h)=2a

链式求导(Chain rule) 复合函数

在函数的复合中描述

(f∘g)′=(f′∘g)⋅g′

当z=f(y), y=g(x)

dzdx=dzdy⋅dydx=f′(y)g′(x)=f′(g(x))g′(x).

利用公式1求导

f′(x)=limh→0f(x+h)−f(x)h

int main()

{

double h = 0.000001;

double x = 10.0;

double v = ((x + h) * (x + h) - x * x) / h;

std::cout << std::setprecision(20) << v << std::endl;

system("pause");

return 0;

}

利用公式2求导

f′(x)=limh→0f(x+h)−f(x−h)2h

int main()

{

double h = 0.000001;

double x = 10.0;

double v = ((x + h) * (x + h) - (x-h) * (x-h)) /(2*h);

std::cout << std::setprecision(20) << v << std::endl;

system("pause");

return 0;

}

dual number

线性代数中dual number是实数的扩展。单位ε,它的平方是0

类似复数

复数(complex number)

x=a+bi(i2=−1)

其中a,b是任意实数,b称为复数x的虚部,i称为虚数单位

dual number

x=x+xε(ε2=0)

以f(x)=x2,x=10 为例求导

f(10) = 100,df/dx(10) = 20

f(10+ε)=(10+ε)2=100+2∗10∗ε+ε2=100+20∗ε

代码如下

typedef struct

{

double real;

double epsilon;

} DualNumber;

DualNumber DerivationPower(DualNumber d, double e)

{

DualNumber dual = { std::pow(d.real, e), d.epsilon * e * std::pow(d.real, e - 1) };

return dual;

}

int main()

{

double x = 10;

DualNumber v = { x,1 };//variable

DualNumber d1 = DerivationPower(v, 2);

std::cout << d1.real <<:endl d1.epsilon>

system("pause");

return 0;

}

⟨u,u′⟩+⟨v,v′⟩=⟨u+v,u′+v′⟩⟨u,u′⟩−⟨v,v′⟩=⟨u−v,u′−v′⟩⟨u,u′⟩∗⟨v,v′⟩=⟨uv,u′v+uv′⟩⟨u,u′⟩/⟨v,v′⟩=⟨uv,u′v−uv′v2⟩(v≠0)sin⟨u,u′⟩=⟨sin(u),u′cos(u)⟩cos⟨u,u′⟩=⟨cos(u),−u′sin(u)⟩exp⟨u,u′⟩=⟨expu,u′expu⟩log⟨u,u′⟩=⟨log(u),u′/u⟩(u>0)⟨u,u′⟩k=⟨uk,kuk−1u′⟩(u≠0)∣∣⟨u,u′⟩∣∣=⟨|u|,u′signu⟩(u≠0)"

根据上述式子一共实现了以下几种函数的一阶导数

Add, Sub, Mul, Div, Sin, Cos, Exp, Log, Power, Abs

real是函数的值,epsilon是函数的一阶导数

typedef struct

{

double real;

double epsilon;

} DualNumber;

DualNumber Dual(double r, double e)

{

DualNumber epsilon = { r, e };

return epsilon;

}

DualNumber SetConstant(double r)

{

return Dual(r, 0);

}

DualNumber SetVariable(double d)

{

return Dual(d, 1);

}

DualNumber Add(DualNumber U, DualNumber V)

{

return Dual(U.real + V.real, U.epsilon + V.epsilon);

}

DualNumber Sub(DualNumber U, DualNumber V)

{

return Dual(U.real - V.real, U.epsilon - V.epsilon);

}

DualNumber Mul(DualNumber U, DualNumber V)

{

return Dual(U.real * V.real, U.real * V.epsilon + U.epsilon * V.real);

}

DualNumber Div(DualNumber U, DualNumber V)

{

if (V.real == 0) return { 0,0 };

return Dual(U.real / V.real, (U.epsilon - (U.real / V.real) * V.epsilon) / V.real);

}

DualNumber Sin(DualNumber U)

{

return Dual(sin(U.real), U.epsilon * cos(U.real));

}

DualNumber Cos(DualNumber U)

{

return Dual(cos(U.real), -U.epsilon * sin(U.real));

}

DualNumber Exp(DualNumber U)

{

return Dual(exp(U.real), U.epsilon * exp(U.real));

}

DualNumber Log(DualNumber U)

{

assert(U.real > 0);

return Dual(log(U.real), U.epsilon / U.real);

}

DualNumber Power(DualNumber U, double e)

{

return Dual(pow(U.real, e), U.epsilon * e * pow(U.real, e - 1));

}

DualNumber Abs(DualNumber U)

{

assert(U.real != 0);

return Dual(abs(U.real), U.epsilon * ((U.real > 0) ? 1 : -1));

}

int main(void) {

double x = 10;

DualNumber v = SetVariable(x);

DualNumber d1 = Power(v, 2);

std::cout << d1.real <<:endl d1.epsilon>

system("pause");

return 0;

}

偏导

偏导数的符号∂

一个多变量函数的偏导数,就是它关于其中一个变量的导数而保持其他变量不变,函数f(x, y, …) 关于变量x的偏导用以下符号表示

f′x,fx,∂xf,Dxf,D1f,∂∂xf,or∂f∂x.

假设

f(x,y)=y3x2.

要计算 ∂f∂x(x,y)

我们只是把y看成是一个固定的数,然后计算对x的普通导数

∂f∂x(x,y)与

g(x)=b3x2类似

dfdx(x)=2b3x

替换字母之后

∂f∂x(x,y)=2y3x

dual number 计算偏导示例

f(x,y)=x2+xy

f(1,3)

计算 dfdx

f(1+e,y)=(1+e)2+3(1+e)

=1+2∗e+3+3∗e

=4+5∗e

结果

dfdx=5

计算 dfdy

f(1,3+e)=12+1∗(3+e)

=1+3+e

=4+e

结果

dfdy=1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值