12

クランプ機能はclamp(x, min, max) = min if x < min, max if x > max, else x

クランプ関数のように動作する関数が必要ですが、滑らかです (つまり、連続微分があります)。

4

2 に答える 2

9

通常のクランプ:

np.clip(x, mi, mx)

Smoothclamp (x < min および x > max の通常のクランプと一致することが保証されています):

def smoothclamp(x, mi, mx): return mi + (mx-mi)*(lambda t: np.where(t < 0 , 0, np.where( t <= 1 , 3*t**2-2*t**3, 1 ) ) )( (x-mi)/(mx-mi) )

Sigmoid (クランプの近似値、最小値よりも小さくはなく、最大値よりも大きくなることはありません)

def sigmoid(x,mi, mx): return mi + (mx-mi)*(lambda t: (1+200**(-t+0.5))**(-1) )( (x-mi)/(mx-mi) )

Sigmoid は可逆関数であり、情報が失われないため、目的によっては Sigmoid の方が Smoothclamp よりも優れています。

他の目的のために、すべてのx > xmaxに対してf(x) = xmaxであることを確認する必要がある場合があります。その場合は、Smoothclamp の方が適しています。また、別の回答で述べたように、Smoothclamp 関数のファミリ全体がありますが、ここで指定したものは私の目的には十分です (スムーズな導関数以外の特別なプロパティは必要ありません)。

それらをプロットします:

import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 1)
x = np.linspace(-4,7,1000)
ax.plot(x, np.clip(x, -1, 4),'k-', lw=2, alpha=0.8, label='clamp')
ax.plot(x, smoothclamp(x, -1, 4),'g-', lw=3, alpha=0.5, label='smoothclamp')
ax.plot(x, sigmoid(x, -1, 4),'b-', lw=3, alpha=0.5, label='sigmoid')
plt.legend(loc='upper left')
plt.show()

グラフ

また、これら 2 つの算術平均も使用できる可能性があります。

def clampoid(x, mi, mx): return mi + (mx-mi)*(lambda t: 0.5*(1+200**(-t+0.5))**(-1) + 0.5*np.where(t < 0 , 0, np.where( t <= 1 , 3*t**2-2*t**3, 1 ) ) )( (x-mi)/(mx-mi) )
于 2017-07-18T11:25:29.460 に答える