> For the complete documentation index, see [llms.txt](https://sisyphus.gitbook.io/project/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://sisyphus.gitbook.io/project/deep-learning-basics/basics/derivatives/a-smooth-differentiable-max-function.md).

# A Smooth (differentiable) Max Function

{% embed url="<https://zhuanlan.zhihu.com/p/45014864>" %}

{% embed url="<https://kexue.fm/archives/3290>" %}

#### Take home: 使用 LogSumExp 函数取代max函数

Q：想到一个点，既然多分类下的 hinge loss 可以用 differentiable 的 trick 推出 softmax，那 ranking 问题是不是也可以用 hinge loss 去做 pair-wise 的 loss function? 是不是也可以用 differentiable 的手段推出某种 loss。

A：triplet就是pair-wise版的 hinge loss；softmax的pair-wise版叫 [Neighbourhood components analysis](https://link.zhihu.com/?target=https%3A//en.wikipedia.org/wiki/Neighbourhood_components_analysis)

LogSumExp函数的导数恰好为softmax函数：

![](http://www.zhihu.com/equation?tex=%5Cfrac%7B%5Cpartial+%5Clog%5Cleft%28+%5Csum_%7Bi%3D1%2Ci%5Cneq+y%7D%5E%7BC%7D%7Be%5E%7Bz_i%7D%7D+%5Cright%29%7D%7B%5Cpartial+z_j%7D+%3D+%5Cfrac%7Be%5E%7Bz_j%7D%7D%7B%5Csum_%7Bi%3D1%2Ci%5Cneq+y%7D%5Ec%7Be%5E%7Bz_i%7D%7D%7D)

这里出现了一个经典的歧义，**softmax实际上并不是max函数的smooth版，而是one-hot向量（最大值为1，其他为0）的smooth版**。其实从输出上来看也很明显，softmax的输出是个向量，而max函数的输出是一个数值，不可能直接用softmax来取代max。max函数真正的smooth版本是LogSumExp函数.

经过这一变换，给予非目标分数的1的梯度将会通过LogSumExp函数传播给所有的非目标分数，各个非目标分数得到的梯度是通过softmax函数进行分配的，较大的非目标分数会得到更大的梯度使其更快地下降。这些非目标分数的梯度总和为1，目标分数得到的梯度为-1，总和为0，绝对值和为2，这样我们就有效地限制住了梯度的总幅度。

LogSumExp函数值是大于等于max函数值的，而且等于取到的条件也是非常苛刻的，所以**使用LogSumExp函数相当于变相地加了一定的** ![m](http://www.zhihu.com/equation?tex=m) 。但这往往还是不够的，我们可以选择跟hinge loss一样添加一个 ![m](http://www.zhihu.com/equation?tex=m) ，那样效果应该也会不错，不过softmax交叉熵损失走的是另一条路：继续smooth。

注意到**ReLU函数** ![\max(x,0)](http://www.zhihu.com/equation?tex=%5Cmax%28x%2C0%29) **也有一个smooth版，即softplus函数** ![\log(1+e^x)](http://www.zhihu.com/equation?tex=%5Clog%281%2Be%5Ex%29) 。使用softplus函数之后，即使 ![z\_y](http://www.zhihu.com/equation?tex=z_y) 超过了LogSumExp函数，仍会得到一点点梯度让 ![z\_y](http://www.zhihu.com/equation?tex=z_y) 继续上升，这样其实也是变相地又增加了一点 ![m](http://www.zhihu.com/equation?tex=m) ，使得泛化性能有了一定的保障。替换之后就可以得到：

![](http://www.zhihu.com/equation?tex=%5Cbegin%7Baligned%7D+%5Cmathcal%7BL%7D_%7Bsoftmax%7D++%26%3D+%5Clog%5Cleft%281+%2B+e%5E%7B%5Clog%5Cleft%28+%5Csum_%7Bi%3D1%2Ci%5Cneq+y%7D%5E%7BC%7D%7Be%5E%7Bz_i%7D%7D+%5Cright%29+-+z_y%7D%5Cright%29%5C%5C+%26%3D+%5Clog%5Cleft%281+%2B+%5Cfrac%7B%5Csum_%7Bi%3D1%2Ci%5Cneq+y%7D%5E%7BC%7D%7Be%5E%7Bz_i%7D%7D%7D%7Be%5E%7Bz_y%7D%7D%5Cright%29%5C%5C+%26%3D+%5Clog%5Cfrac%7B%5Csum_%7Bi%3D1%7D%5E%7BC%7D%7Be%5E%7Bz_i%7D%7D%7D%7Be%5E%7Bz_y%7D%7D%5C%5C+%26%3D+-%5Clog%5Cfrac%7Be%5E%7Bz_y%7D%7D%7B%5Csum_%7Bi%3D1%7D%5E%7BC%7D%7Be%5E%7Bz_i%7D%7D%7D+%5Cend%7Baligned%7D)

这个就是大家所熟知的softmax交叉熵损失函数了。**在经过两步smooth化之后，我们将一个难以收敛的函数逐步改造成了softmax交叉熵损失函数，解决了原始的目标函数难以优化的问题**。从这个推导过程中我们可以看出**smooth化不仅可以让优化更畅通，而且还变相地在类间引入了一定的间隔，从而提升了泛化性能**。

在最优化问题中，求一个函数的最大值或最小值，最直接的方法是求导，然后比较各阶极值的大小。然而，我们所要优化的函数往往不一定可导，比如函数中含有最大值函数 max( x, y) 的。这时候就得求助于其他思路了。有一个很巧妙的思路是，将这些不可导函数用一个可导的函数来近似它，从而我们用求极值的方法来求出它近似的最优值。本文的任务，就是探究一个简单而有用的函数，它能够作为最大值函数的近似，并且具有多阶导数。

在数学分析中，笔者已经学习过一个关于最大值函数的公式，即当x≥0,y≥0 时，我们有:

Max(x,y) = 1 / 2 \* ( | x + y | + | x − y | )

那么，为了寻求一个最大值的函数，我们首先可以考虑寻找一个能够近似表示绝对值 | x | 的函数，这样我们就把问题从二维降低到一维了。那么，哪个函数可以使用呢？

直接观察挺难发现哪个函数可以使用的，我们将问题逐步向简单推进。我们对 f(x)=|x| 求导，除了 x = 0 这一点外，其他都可以顺利求导。

f′(x)= 1, x > 0

f′(x)= −1 x < 0

这是一个简单的分段函数，在物理中，这类函数十分常见，跟它最接近的，应该是单位阶跃函数θ(x)：

θ(x) = 1, x > 0

θ(x) = 0 x < 0

那么

f′(x) = 2 \* θ(x) − 1

下面只需要寻求 θ(x) 的近似函数，物理学家已经提供现成的函数给我们了，一个比较简单的形式是:

$$\theta(x)=\lim\_{k\to +\infty} \frac{1}{1+e^{-k x}}$$&#x20;

那么我们就可以取 $$\frac{1}{1+e^{-k x}}$$ 作为近似函数了，代入(4) 式得到 $$\frac{2e^{k x}}{1+e^{k x}}-1$$ ，积分得到

$$\begin{aligned}f(x)&=\frac{2}{k}\ln(1+e^{kx})-x\  &=\frac{1}{k}\left\[\ln(1+e^{kx})+\ln(1+e^{-kx})\right]\  &=\frac{1}{k}\ln(2+e^{kx}+e^{-kx})\end{aligned}$$&#x20;

不难发现，(6) 式中的对数部分，在 k 足够大的时候，常数 2 的影响微乎其微，把它去掉之后，我们有一个比较简单的绝对值函数：

$$|x|=\lim\_{k\to +\infty} \frac{1}{k}\ln(e^{kx}+e^{-kx})$$&#x20;

结合 (7) 式和 (1) 式，我们就得到

$$\max(x,y)=\lim\_{k\to +\infty} \frac{1}{2k}\left{\ln\[e^{k(x+y)}+e^{-k(x+y)}]+\ln\[e^{k(x-y)}+e^{-k(x-y)}]\right}$$&#x20;

(8) 式还可以再化简，我们得到

$$\max(x,y)=\lim\_{k\to +\infty} \frac{1}{2k}\ln(e^{2kx}+e^{-2kx}+e^{2ky}+e^{-2ky})$$&#x20;

并且由于 (1) 式是在 x≥0,y≥0 时成立的，所以(9)式中的 e−2kx 和 e−2ky 均变得不重要了，我们也把它们去掉，进一步得到

$$\max(x,y)=\lim\_{k\to +\infty} \frac{1}{2k}\ln(e^{2kx}+e^{2ky})$$&#x20;

或者写成

$$\max(x,y)=\lim\_{k\to +\infty} \frac{1}{k}\ln(e^{kx}+e^{ky})$$&#x20;

(11) 式正是我们希望得到的理想的最大值函数。虽然我们的推导基于 x ≥ 0, y ≥ 0，但是不难发现，对于x,y 中出现负数时，上述公式仍然成立！它甚至还可以推广到多个变量的最大值函数：

$$\max(x,y,z,\dots)=\lim\_{k\to +\infty} \frac{1}{k}\ln(e^{kx}+e^{ky}+e^{kz}+\dots)$$&#x20;

关于 (11) 式更多的展示，请阅读Matrix67的《如何构造一个平滑的最大值函数》：\
<http://www.matrix67.com/blog/archives/2830> 观察 (11) 式的结构可以看出，这实际上是做了这样的一个事情：**找一个在整个实数域上都单调递增的函数，而且增长速度要快于线性增长，然后求和，最后取逆函数。**&#x56E0;此，不难构造出类似的函数：我们选 $$y=x^{2k+1}$$ ，那么得到

$$\max(x,y)=\lim\_{k\to+\infty} \sqrt\[2k+1]{x^{2k+1}+y^{2k+1}}$$&#x20;

当然，(13) 的精度（或者说收敛速度）远没有 (11) 那么好，要提高精度也不难，比如

$$\max(x,y)=\lim\_{k\to +\infty} \frac{1}{k}\ln\ln\left(e^{e^{kx}}+e^{e^{ky}}\right)$$&#x20;

综合精度和简洁两方面考虑，估计最优的选择就是 (11) 了。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sisyphus.gitbook.io/project/deep-learning-basics/basics/derivatives/a-smooth-differentiable-max-function.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
