Skip to content

Instantly share code, notes, and snippets.

@patricksurry
Last active August 14, 2023 06:53
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save patricksurry/9858e5d2489ec25d71e51c45c066bd79 to your computer and use it in GitHub Desktop.
Save patricksurry/9858e5d2489ec25d71e51c45c066bd79 to your computer and use it in GitHub Desktop.
softclip-notebook
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"%matplotlib inline \n",
"import numpy as np\n",
"import pandas as pd\n",
"from matplotlib import pyplot as plt\n",
"import seaborn as sns\n",
"sns.set_style('whitegrid')"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"def softplus(x):\n",
" \"\"\"numerically stable calcuation for log(1 + exp(x))\"\"\"\n",
" return np.log(1 + np.exp(-np.abs(x))) + np.maximum(x,0)\n",
"\n",
"\n",
"def softminus(x):\n",
" return -softplus(-x)\n",
"\n",
"\n",
"# default scaling constants to match tanh corner shape\n",
"_c_tanh = 2 / (np.e*np.e + 1) # == 1 - np.tanh(1) ~= 0.24\n",
"_c_softclip = np.log(2) / _c_tanh\n",
"_c_expclip = 1 / (2 * _c_tanh)\n",
"\n",
"\n",
"def tanhclip(x, a, b):\n",
" \"\"\"Canonical soft-clipping with tanh(x). Must specify both endpoints\"\"\"\n",
" scale = (b - a) / 2\n",
" return (np.tanh((x - a) / scale - 1) + 1) * scale + a\n",
"\n",
"\n",
"def softclip(x, a=None, b=None, c=_c_softclip):\n",
" \"\"\"\n",
" Clipping with softplus and softminus, with paramterized corner sharpness.\n",
" Set either (or both) endpoint to None to indicate no clipping at that end.\n",
" \"\"\"\n",
" # when clipping at both ends, make c dimensionless w.r.t. b - a / 2 \n",
" if a is not None and b is not None:\n",
" c /= (b - a) / 2\n",
"\n",
" v = x\n",
" if a is not None:\n",
" v = v - softminus(c*(x - a)) / c \n",
" if b is not None:\n",
" v = v - softplus(c*(x - b)) / c\n",
" return v\n",
"\n",
"\n",
"def expclip(x, a=None, b=None, c=_c_expclip):\n",
" \"\"\"\n",
" Exponential soft clipping, with parameterized corner sharpness.\n",
" Simpler functional form but 3rd, 5th, ... and subequent odd derivatives are discontinuous at 0\n",
" \"\"\"\n",
" if a is not None and b is not None:\n",
" c /= (b - a) / 2\n",
" \n",
" v = np.clip(x, a, b)\n",
" if a is not None:\n",
" v = v + np.exp(-c*np.abs(xs-a))/(2*c)\n",
" if b is not None:\n",
" v = v - np.exp(-c*np.abs(xs-b))/(2*c)\n",
" return v\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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CwCNGjWiUaNGjBo16h/TVaxYkWrVqh0bZ8OGDcFfSREJG6p1qnVF3f5DmUw58B01A3buv2Wo1XHEIqp1qnUip1Psjw/4+6WyDx48yBtvvMHIkSN56aWXiI6OxjRNgGOHUyQlJXHgwAEyMzMBWLZs2T/GTU5OPvb8woULGTZs2EmXv3PnTnbv3g3A4sWLqVWrVnBWTETkOKp1Ulhem/QAu5x2elb/N06ny+o4Usyo1olEhrDZExou4uPjadSoEd26dcPpdFKiRAl27dpFlSr//2me0+nkmWee4d///jeJiYk4nf/cjPfddx9PPvkkU6dOBWDQoEF89dVX/5guKiqKF198ke3bt9OgQQPatm0bupUTETlKtU5CYfP21cz0LaOB1023K/paHUdEtU4kXJmmWShfK1euNP/uZM8VlqysLMuWfbwWLVqccZq/bycrt1swKL91wi37okWLFpmFVIMK60u17uRU6yJPfvL3HXuFmfJ+ffP7hZNCkOjchNP2V60LPdU66yi/tcIt/9nWu2J/OK6IiIgUXOrKH/nBuY2WeaVp3eRGq+OIiEgYUxNqsV9++cXqCCIiIadaV/SN/vkJHCb0bj/C6igillGtEzk7akJFRESkQKb//CG/Rx+ivVmDejWbWB1HRETCnJpQERERybeA38+HK0dS0h+g73VjrI4jIiIRQE2oiIiI5NsHM14mLdrPNdHNqFCm8O8LKSIikUe3aBEREZF8ycnNYuKOCVQGHu42yuo4IiISIYr1ntDc3FwmTpx4zvP99ttv9OvX75zna9myJQAvv/wy27ZtO+f5RURCbcuWLXTs2JH+/ftjGAYLFy484zzp6el07doVgH79+pGXlxfqmBImRk3qR7rLxk1lbyDWHWd1HJGzplonYq1i3YTu3r07X01oQT311FNUqlSp0JcrInImqamptG7dmiFDhvDdd9+xdu3ac5p/5MiRREVFhSidhJM9+7bxddbPeHLt/LvT81bHETknqnUi1gqfw3H/GA9LPgnumA1vhYt6nPLlt99+m7Vr1/Lmm2/SpUsXnnvuOXJzc9m9ezd9+/alffv2XHvttVx88cUYhoHNZmP06NEAbNq0ibvvvpvMzEzatGnDQw89dMLYEydOZPz48QQCAdq2bcvDDz987LXbbruN5557jm+++Yb169eTkZHBgQMHGDhwIE2a6KqCIkWa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\n",
"text/plain": [
"<Figure size 1152x288 with 3 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"fig, axs = plt.subplots(1, 3, figsize=(16, 4), sharey=True)\n",
"\n",
"xs = np.linspace(-5, 5, 101)\n",
"\n",
"a = -1\n",
"b = 2\n",
"\n",
"plt.ylim(a-1, b+1)\n",
"\n",
"axs[0].plot(xs, np.clip(xs, a, b), label='hard clip')\n",
"axs[0].plot(xs, tanhclip(xs, a, b), label='tanh clip')\n",
"axs[0].plot(xs, softclip(xs, a, b), label='soft clip')\n",
"axs[0].plot(xs, expclip(xs, a, b), label='exp clip')\n",
"axs[0].set_title('Clip on [a, b]')\n",
"axs[0].legend()\n",
"\n",
"axs[1].plot(xs, np.clip(xs, a, None), label='hard clip')\n",
"axs[1].plot(xs, softclip(xs, a, None), label='soft clip')\n",
"axs[1].plot(xs, expclip(xs, a, None), label='exp clip')\n",
"axs[1].set_title('Clip on [a, .)')\n",
"axs[1].legend()\n",
"\n",
"axs[2].plot(xs, np.clip(xs, None, b), label='hard clip')\n",
"axs[2].plot(xs, softclip(xs, None, b), label='soft clip')\n",
"axs[2].plot(xs, expclip(xs, None, b), label='exp clip')\n",
"axs[2].set_title('Clip on (., b]')\n",
"axs[2].legend()\n",
"\n",
"None"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment