最近在看算法导论中文版,第一部分的基础知识里有许多数学上的知识,多重对数函数就是其中一个我不太熟悉的知识。 多重对数函数的定义是: lg*n=min{i≥0:lg(i)n≤1} lg*2=1 lg*4=2 lg*16=3 lg*65536=4 lg*265536=5 也就是说呢, lg(1)16=lg16=4
以外的源码 2.牺牲代码复用性,每个类都必须是单独的组件,绝不互相引用,做到完全解耦 package *; /** * @program: simple_tools * @description: 对数函数 new LogFunction(); } } } } /** * 功能描述: * 〈初始化对数函数 zero and not be one"); } instance.setA(a); } /** * 功能描述: * 〈判断点是否在对数函数上 point.getY(); return y == Math.pow(x,instance.getA()); } /** * 功能描述: * 〈每个对数函数都会过点
指数函数与对数函数的核心公式指数函数与对数函数的曲线绘制from __future__ import annotations , annotationsimport matplotlib.pyplot 'font.size' ] = 16plt.rcParams[ 'axes.unicode_minus' ] = False # 正确显示负号plt.figure(figsize = (12 , 8) """自然对数函数Natural logarithmic function (通常表示为 ln(x) 或 log_e(x))常用对数函数Common logarithmic function (以10为底的对数 self.a) expected = k * log(self.x , self.a) self.assertTrue(expr.equals(expected)) # [5,8] 反向验证: a^(logₐy) = y self.assertEqual( a_val ** log(y_val , a_val) , # 3^{log₃8}
注意:C语言标准库未直接提供以任意正数为底的对数函数,但可通过换底公式推导:logₐ(b) = log(b)/log(a) 或 logₐ(b) = log10(b)/log10(a)。 + n * 0.69314718056 return result 3.3 log10()函数伪代码实现 log10()的实现通常基于换底公式: ,因为直接实现常用对数的效率低于复用已有的自然对数函数 错误:%s\n", x1, strerror(errno)); // 输出"数值参数超出定义域" } // 测试exp()参数过大(double最大值约为1.8e308,e^709≈8e307 pH值、震级等工程换算 特殊值结果 exp(0)=1.0;exp(+∞)=+∞ log(1)=0.0;log(e)=1.0 log10(1)=0.0;log10(10)=1.0 七、经典面试题 指数与对数函数是 return NAN; } return result; } int main() { // 测试用例:合法场景、x非法、base非法 printf("log_2(8)
可以直接对两边求导\(G'(A(x)) = F'(A(x))A'(x) = \frac{A(x)}{A'(x)}\)
[rxd1d8mwf2.png] 现在我们有了这3种算法,我们需要知道哪个算法更快。 最好的方法是计算函数是怎样增长的。 [w92nkmin4r.png] 对数函数在不同量级的表现 有趣的是对数并不总是最优的,比如函数和函数。 第一张图展现了对数函数的增长比二次方要慢很多。 [fejs5cekfu.png] 然而,更仔细的看一下,如果输入数据比较小,那么对数函数会比二次方函数要快一点。 [ei66a8py9m.png] 因此,如果你是处理比较小的问题,不使用对数函数可能会更好一些。 又学到了一点小知识,有问题可以留言~
比如一个黑箱里有2个苹果,8个橙子我们把从黑箱里取苹果、橙子看成是一个随机过程,X={苹果,橙子}。 带负号的对数函数显然符合以上要求,当然,肯定有其他函数也会符合以上要求,对此,香农在《A Mathematical Theory of Communication》(通信的数学理论)这篇论文中有说明选择对数函数的原因 而最自然的选择是对数函数。 关于对数函数更便捷的原因,论文中给出了3点: 在实践中更有用。 加倍时间,可能的消息数会近似变成原来的平方(1,2,4,8,...),而其对数则是加倍(log2 1,log2 2,log2 4,log2 8,...)=(0,1,2,3,...) 那么,为什么选择2为底的对数呢,论文中的解释是这样的: [s8ajda8l11.png] [v9z3mkglbe.png] 大致意思是说选择什么为底与用什么单位来度量信息是对应的。
这些数学函数包含了许多常见的数学运算,如三角函数、指数函数、对数函数、统计函数等。本文将介绍NumPy中一些常用的数学函数及其用法,展示NumPy在数值计算方面的强大功能。 示例如下:import numpy as nparr = np.array([2, 4, 6])# 加法result = np.add(arr, 2)print(result) # [4 6 8]# inf -0.]指数和对数函数NumPy提供了指数函数(如幂函数和指数函数)以及对数函数(如自然对数和以2为底的对数)。这些函数可用于计算数值的幂、指数和对数值。 示例代码如下:import numpy as nparr = np.array([6, 7, 8, 9, 10])# 平均值result = np.mean(arr)print(result)# 标准差
比如一个黑箱里有2个苹果,8个橙子我们把从黑箱里取苹果、橙子看成是一个随机过程,X={苹果,橙子}。 带负号的对数函数显然符合以上要求,当然,肯定有其他函数也会符合以上要求,对此,香农在《A Mathematical Theory of Communication》(通信的数学理论)这篇论文中有说明选择对数函数的原因 而最自然的选择是对数函数。 关于对数函数更便捷的原因,论文中给出了3点: 在实践中更有用。 对数函数可以让一些工程上非常重要的参数比如时间、带宽、继电器数量等与可能性的数量的对数成线性关系,例如,增加一个继电器会使继电器的可能状态数加倍,而如果对这一可能状态数求以2为底的对数,结果只是加 1。 加倍时间,可能的消息数会近似变成原来的平方(1,2,4,8,...),而其对数则是加倍(log2 1,log2 2,log2 4,log2 8,...)=(0,1,2,3,...)
高等数学将基本初等函数归为五类:幂函数、指数函数、对数函数、三角函数、反三角函数。 比较头疼的是numpy中的幂函数不支持负数定义域,所以找了很多办法来解决该问题。 主函数代码如下: #! : # 一般地,对数函数是以幂(真数)为自变量,指数为因变量,底数为常量的函数。 # 对数函数是6类基本初等函数之一。 # 一般地,函数y=logaX(a>0,且a≠1)叫做对数函数,也就是说以幂(真数)为自变量,指数为因变量,底数为常量的函数,叫对数函数。 # 其中x是自变量,函数的定义域是(0,+∞),即x>0。 因此指数函数里对于a的规定,同样适用于对数函数。
例如,在 Python 中,2 ** 3 表示 $2$ 的 $3$ 次幂,结果为 $8$。指数函数计算可以使用指数函数库,如 exp()。 对数函数:对数函数是形如 f(x) = logₐ(x) 的函数,其中 a 是对数的底。对数函数的图像是一个从左向右递增的曲线。对数函数的特点是 x 的增加对应着 y 增长速度逐渐减慢。 对数函数常用于描述倍增现象,例如霍夫曼编码和指数增长模型。 除了上述函数类型外,还有三角函数、双曲函数、阶乘函数等。这些函数在数学和科学领域中具有广泛的应用。
交叉熵损失函数在计算中通常会涉及对数运算,而对数函数在定义域上有限制。对数函数的定义域是正实数,即输入值必须大于零。 在李沐老师的本节中,如果交叉熵损失函数的计算结果中包含负数或零,将会导致问题。 为了解决这个问题,通常会在交叉熵损失函数的计算中添加一个小的平滑项,例如加上一个较小的常数(如10的-8次方)以确保避免出现负数或零。这被称为“平滑交叉熵”或“平滑对数损失”。 对数函数定义域问题:在计算交叉熵损失函数时,添加一个小的平滑项。可以在对数函数的输入上加上一个较小的常数,例如(如10的-8次方),以确保避免出现负数或零。 这样可以避免对数函数在定义域之外的值上计算,确保损失函数的计算结果正确。 在交叉熵损失函数中,添加了平滑项(如10的-8次方)以确保避免对数函数的定义域问题。
假设有底数为2和3的两个对数函数,如上图。当X取N(数据规模)时,求所对应的时间复杂度得比值,即对数函数对应的y值,用来衡量对数底数对时间复杂度的影响。 用文字表述:算法时间复杂度为log(n)时,不同底数对应的时间复杂度的倍数关系为常数,不会随着底数的不同而不同,因此可以将不同底数的对数函数所代表的时间复杂度,当作是同一类复杂度处理,即抽象成一类问题。 排序算法中有一个叫做“归并排序”或者“合并排序”的算法,它用到的就是分而治之的思想,而它的时间复杂度就是N*logN,此算法采用的是二分法,所以可以认为对应的对数函数底数为2,也有可能是三分法,底数为3
此外,也很乏味 同一函数的对数函数的一阶导数要简单得多: ? 二阶导数也很简单: ? 当你实际使用对数时,你会得到一个不同的函数。 你走路和开车时不需要走相同的路线。 这正是一个函数和该函数的对数函数共同之处:相同的参数可以最小化损失函数。 对这个函数和它对数函数同时求导就得到损失函数的最小值。 一个数学证明 我们来证明一个使函数最小化的参数等于这个函数的对数函数的最小化的参数。 ? 它的对数函数是: ? 部分图像如下: ? 可以看到,在这两种情况下,函数的最大值都是当x=0.3时取得。 是的,我们没有得到相同的函数,但是我们仍然有相同的临界点来帮助我们最小化损失函数。 一句话总结:一个函数和该函数的对数函数有一个共同之处,就是最小化的参数是相同的,对数求导要简单很多,会加快我们的计算速度。 deephub翻译组:gkkkkkk DeepHub
h 和 k 决定了对数函数曲线顶点的位置,而 a 决定了曲线的开口方向和聚集程度。 余弦函数通常作为传统损失中的对数函数,例如CosFace和ArcFace。 年龄在野外(CALFW),4) 年龄在姿势(CPLFW),5) 正面视角的明星(CFP-FP),6) 正面视角的视觉几何组(VGGFace2-FP),7) IARPA Janus基准B(IJB-B),8) 超参数 a , h 和 k 一起决定了X2-Softmax损失中的对数函数曲线,以及对数函数曲线与余弦函数之间的差异。超参数 a 决定了对数函数曲线的开口方向和收敛程度。 对数函数应该随着面特征 x_{i} 与权重 W_{y_{i}} 之间的角度增加而减小,因此超参数 a 应设置为负数。随着 a 的绝对值增加,对数函数曲线变得更密集和更陡峭。 超参数 h 表示对数函数曲线顶点的水平坐标。随着超参数 h 的减小,对数函数曲线向左移动,对数函数曲线与余弦函数曲线之间的差异增加,这意味着角边界同时增加。
假设有底数为2和3的两个对数函数,如上图。当X取N(数据规模)时,求所对应的时间复杂度得比值,即对数函数对应的y值,用来衡量对数底数对时间复杂度的影响。 用文字表述:算法时间复杂度为log(n)时,不同底数对应的时间复杂度的倍数关系为常数,不会随着底数的不同而不同,因此可以将不同底数的对数函数所代表的时间复杂度,当作是同一类复杂度处理,即抽象成一类问题。 排序算法中有一个叫做“归并排序”或者“合并排序”的算法,它用到的就是分而治之的思想,而它的时间复杂度就是N*logN,此算法采用的是二分法,所以可以认为对应的对数函数底数为2,也有可能是三分法,底数为3
现在让我们继续探讨对数函数的概念。前面讲解了指数函数,对数函数则是指数函数的逆运算。如果有一个指数函数表达式为y = a^x ,那么它的对数表达式就是x = log_a y 。 为了方便表示,我们通常将左侧的结果记为$y$,右侧的未知函数记为$x$,因此对数函数最终表示为y = log_a x 。为了更加深刻地记忆这一点,让我们看一下它的分布图例。 然而,当我们转而讨论对数函数时,其表示形式导致了这一点被调换至( (1,0) ),因此对于对数函数而言,它的恒过点即为( (1,0) )。 剩下关于对数的变换我就不再详细讲解了。 因为对数函数的特性是,其参数 ( x ) 可以无限接近于0,但不能等于0。因此,如果参数等于0,就会导致对数函数计算时出现错误或无穷大的情况。 在讨论中,我们还回顾了指数和对数函数的基本概念,这些函数在交叉熵的定义和理解中起着重要作用。指数函数展示了指数级增长的特性,而对数函数则是其逆运算,用于计算相对熵和交叉熵函数中的对数项。
2、我们在代数运算中,将对数函数分为三类:常用对数函数(10)、自然对数函数(e)、其他对数函数,而在算法导论中lgN默认都是以2为底,这个需要留意。 (93); static { list.add(BigDecimal.ZERO); list.add(BigDecimal.ONE); } /** * 1,2,3,4,5,6, 7 ,8 * 1,1,2,3,5,8,13,21 * 支持num超过92的超大型数字,使用了ArrayList进行缓存以提高性能 */ public static BigDecimal fibBig(int num
2、我们在代数运算中,将对数函数分为三类:常用对数函数(10)、自然对数函数(e)、其他对数函数,而在算法导论中lgN默认都是以2为底,这个需要留意。 BigDecimal>(93);static { list.add(BigDecimal.ZERO); list.add(BigDecimal.ONE);}/*** 1,2,3,4,5,6, 7 ,8 * 1,1,2,3,5,8,13,21* 支持num超过92的超大型数字,使用了ArrayList进行缓存以提高性能*/public static BigDecimal fibBig(int num)
对数函数(log) 对数的定义:一般地,如果ax=N(a>0,且a≠1),那么数x叫做以a为底N的对数,记作x=logaN,读作以a为底N的对数,其中a叫做对数的底数,N叫做真数。 一般地,函数y=logax(a>0,且a≠1)叫做对数函数,也就是说以幂(真数)为自变量,指数为因变量,底数为常量的函数,叫对数函数。