<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 絕對損失和 Huber 損失 > 原文:[https://www.ste 科書.ds100.org/ch/10/modeling_abs_huber.html](https://www.ste 科書.ds100.org/ch/10/modeling_abs_huber.html) ``` # HIDDEN # Clear previously defined variables %reset -f # Set directory for data loading to work properly import os os.chdir(os.path.expanduser('~/notebooks/10')) ``` ``` # HIDDEN import warnings # Ignore numpy dtype warnings. These warnings are caused by an interaction # between numpy and Cython and can be safely ignored. # Reference: https://stackoverflow.com/a/40846742 warnings.filterwarnings("ignore", message="numpy.dtype size changed") warnings.filterwarnings("ignore", message="numpy.ufunc size changed") import numpy as np import matplotlib.pyplot as plt import pandas as pd import seaborn as sns %matplotlib inline import ipywidgets as widgets from ipywidgets import interact, interactive, fixed, interact_manual import nbinteract as nbi sns.set() sns.set_context('talk') np.set_printoptions(threshold=20, precision=2, suppress=True) pd.options.display.max_rows = 7 pd.options.display.max_columns = 8 pd.set_option('precision', 2) # This option stops scientific notation for pandas # pd.set_option('display.float_format', '{:.2f}'.format) ``` ``` # HIDDEN tips = sns.load_dataset('tips') tips['pcttip'] = tips['tip'] / tips['total_bill'] * 100 ``` ``` # HIDDEN def mse_loss(theta, y_vals): return np.mean((y_vals - theta) ** 2) def abs_loss(theta, y_vals): return np.mean(np.abs(y_vals - theta)) ``` ``` # HIDDEN def compare_mse_abs(thetas, y_vals, xlims, figsize=(10, 7), cols=3): if not isinstance(y_vals, np.ndarray): y_vals = np.array(y_vals) rows = int(np.ceil(len(thetas) / cols)) plt.figure(figsize=figsize) for i, theta in enumerate(thetas): ax = plt.subplot(rows, cols, i + 1) sns.rugplot(y_vals, height=0.1, ax=ax) plt.axvline(theta, linestyle='--', label=rf'$ \theta = {theta} $') plt.title(f'MSE = {mse_loss(theta, y_vals):.2f}\n' f'MAE = {abs_loss(theta, y_vals):.2f}') plt.xlim(*xlims) plt.yticks([]) plt.legend() plt.tight_layout() ``` 為了擬合模型,我們選擇了一個損失函數,并選擇了使損失最小化的模型參數。在上一節中,我們介紹了均方誤差(mse)損失函數: $$ \begin{aligned} L(\theta, \textbf{y}) &= \frac{1}{n} \sum_{i = 1}^{n}(y_i - \theta)^2\\ \end{aligned} $$ 我們使用了一個常量模型來預測數據集中所有條目的相同數字$\theta$。當我們使用 MSE 損失來擬合這個模型時,我們發現$\hat \theta=\text mean(\textbf y)$。在 Tips 數據集中,我們發現擬合常數模型將預測$16.08\%$因為$16.08\%$是 Tip 百分比的平均值。 在本節中,我們介紹了兩個新的損耗函數,即**平均絕對誤差**損耗函數和**huber**損耗函數。 ### 平均絕對誤差 現在,我們將保持我們的模型相同,但切換到一個不同的損失函數:平均絕對誤差(MAE)。這個損失函數取的是絕對差,而不是每個點的平方差和我們的預測值: $$ \begin{aligned} L(\theta, \textbf{y}) &= \frac{1}{n} \sum_{i = 1}^{n} |y_i - \theta| \\ \end{aligned} $$ ### 比較 mse 和 mae[?](#Comparing-MSE-and-MAE) 為了更好地了解 MSE 和 MAE 的比較方式,讓我們比較它們在不同數據集中的損失。首先,我們將使用一個點的數據集:$\textbf y=[14]$。 ``` # HIDDEN compare_mse_abs(thetas=[11, 12, 13, 14, 15, 16], y_vals=[14], xlims=(10, 17)) ``` ![](https://img.kancloud.cn/bd/bb/bdbbe4531c814a1cd4acc50ba6703220_695x479.jpg) 我們發現 MSE 通常高于 MAE,因為誤差是平方的。讓我們看看當有五個點時會發生什么:$\textbf y=[12.1,12.8,14.9,16.3,17.2]。$ ``` # HIDDEN compare_mse_abs(thetas=[12, 13, 14, 15, 16, 17], y_vals=[12.1, 12.8, 14.9, 16.3, 17.2], xlims=(11, 18)) ``` ![](https://img.kancloud.cn/aa/f9/aaf9a7f5e9e74730e975a1830ddb3c4f_695x479.jpg) 請記住,實際損失值本身對我們不是很有趣;它們只對比較不同的$theta$值有用。一旦我們選擇了一個損失函數,我們將尋找產生最小損失的$\hat \theta$,即$\theta$。因此,我們感興趣的是損失函數是否產生不同的$\hat \theta$。 到目前為止,這兩個損失函數似乎在$\hat \theta 上達成一致。然而,如果我們再近一點看,就會發現一些差異。我們首先計算損失,并將它們與我們嘗試的 6 個$\theta$值的$theta$進行比較。 ``` # HIDDEN thetas = np.array([12, 13, 14, 15, 16, 17]) y_vals = np.array([12.1, 12.8, 14.9, 16.3, 17.2]) mse_losses = [mse_loss(theta, y_vals) for theta in thetas] abs_losses = [abs_loss(theta, y_vals) for theta in thetas] plt.scatter(thetas, mse_losses, label='MSE') plt.scatter(thetas, abs_losses, label='MAE') plt.title(r'Loss vs. $ \theta $ when $ \bf{y}$$= [ 12.1, 12.8, 14.9, 16.3, 17.2 ] $') plt.xlabel(r'$ \theta $ Values') plt.ylabel('Loss') plt.legend(); ``` ![](https://img.kancloud.cn/29/89/298996aa2e904664de6429d3678f042c_444x303.jpg) 然后,我們計算更多的$\theta$值,使曲線平滑: ``` # HIDDEN thetas = np.arange(12, 17.1, 0.05) y_vals = np.array([12.1, 12.8, 14.9, 16.3, 17.2]) mse_losses = [mse_loss(theta, y_vals) for theta in thetas] abs_losses = [abs_loss(theta, y_vals) for theta in thetas] plt.plot(thetas, mse_losses, label='MSE') plt.plot(thetas, abs_losses, label='MAE') plt.title(r'Loss vs. $ \theta $ when $ \bf{y}$$ = [ 12.1, 12.8, 14.9, 16.3, 17.2 ] $') plt.xlabel(r'$ \theta $ Values') plt.ylabel('Loss') plt.legend(); ``` ![](https://img.kancloud.cn/91/94/9194079853bfa6d531e4b6dfcaabf21d_444x303.jpg) 然后,我們放大 Y 軸上 1.5 到 5 之間的區域,以更清楚地看到最小值的差異。我們用虛線標出了最小值。 ``` # HIDDEN thetas = np.arange(12, 17.1, 0.05) y_vals = np.array([12.1, 12.8, 14.9, 16.3, 17.2]) mse_losses = [mse_loss(theta, y_vals) for theta in thetas] abs_losses = [abs_loss(theta, y_vals) for theta in thetas] plt.figure(figsize=(7, 5)) plt.plot(thetas, mse_losses, label='MSE') plt.plot(thetas, abs_losses, label='MAE') plt.axvline(np.mean(y_vals), c=sns.color_palette()[0], linestyle='--', alpha=0.7, label='Minimum MSE') plt.axvline(np.median(y_vals), c=sns.color_palette()[1], linestyle='--', alpha=0.7, label='Minimum MAE') plt.title(r'Loss vs. $ \theta $ when $ \bf{y}$$ = [ 12.1, 12.8, 14.9, 16.3, 17.2 ] $') plt.xlabel(r'$ \theta $ Values') plt.ylabel('Loss') plt.ylim(1.5, 5) plt.legend() plt.tight_layout(); ``` ![](https://img.kancloud.cn/06/82/0682234bd58a67f36a7780744b9eb6d3_478x335.jpg) 我們從經驗上發現,MSE 和 MAE 可以為同一個數據集生成不同的$\hat \theta。一個更仔細的分析揭示了它們何時會不同,更重要的是,它們為什么會不同。 ### 離群值[?](#Outliers) 我們可以在上面的損失圖和$\theta$圖中看到的一個區別在于損失曲線的形狀。繪制均方根誤差會導致損失函數中平方項產生拋物線。 另一方面,繪制 MAE 會產生一系列連接的線條。當我們考慮到絕對值函數是線性的時,這是有意義的,因此取許多絕對值函數的平均值應該產生一個半線性函數。 由于 MSE 有一個平方誤差項,所以它對異常值更為敏感。如果$\theta=10$且一個點位于 110,則該點的毫秒誤差項將為$(10-110)^2=10000$而在 mae 中,該點的誤差項將為$10-110=100$。我們可以用一組三點來說明這一點,即$textbf y=[12,13,14]$并繪制 MSE 和 MAE 的損失與$theta$曲線。 使用下面的滑塊將第三個點移動到遠離其余數據的位置,并觀察損失曲線會發生什么。(由于 MSE 的值大于 MAE,所以我們已經縮放了曲線以保持這兩個曲線都在視圖中。) ``` # HIDDEN def compare_mse_abs_curves(y3=14): thetas = np.arange(11.5, 26.5, 0.1) y_vals = np.array([12, 13, y3]) mse_losses = [mse_loss(theta, y_vals) for theta in thetas] abs_losses = [abs_loss(theta, y_vals) for theta in thetas] mse_abs_diff = min(mse_losses) - min(abs_losses) mse_losses = [loss - mse_abs_diff for loss in mse_losses] plt.figure(figsize=(9, 2)) ax = plt.subplot(121) sns.rugplot(y_vals, height=0.3, ax=ax) plt.xlim(11.5, 26.5) plt.xlabel('Points') ax = plt.subplot(122) plt.plot(thetas, mse_losses, label='MSE') plt.plot(thetas, abs_losses, label='MAE') plt.xlim(11.5, 26.5) plt.ylim(min(abs_losses) - 1, min(abs_losses) + 10) plt.xlabel(r'$ \theta $') plt.ylabel('Loss') plt.legend() ``` ``` # HIDDEN interact(compare_mse_abs_curves, y3=(14, 25)); ``` <button class="js-nbinteract-widget">Loading widgets...</button> 我們已經顯示了下面$y_3=14$和$y_3=25$的曲線。 ``` # HIDDEN compare_mse_abs_curves(y3=14) ``` ![](https://img.kancloud.cn/11/12/1112fb31163f7439d5ac08ae9dd51f5d_560x181.jpg) ``` # HIDDEN compare_mse_abs_curves(y3=25) ``` ![](https://img.kancloud.cn/d2/83/d283961f43baa658e5056d200a1511e3_560x181.jpg) 當我們將該點移離其他數據時,MSE 曲線也隨之移動。當$y_=14$時,mse 和 mae 都有$that \theta=13$。然而,當$y_=25$時,MSE 損失產生的是$hat \theta=16.7$而 MAE 產生的是$hat \theta=13$,與以前沒有變化。 ### 最小化 mae[?](#Minimizing-the-MAE) 既然我們對 MSE 和 MAE 的區別有了定性的認識,我們就可以最小化 MAE,使這一區別更加精確。如前所述,我們將取損失函數對$\theta$的導數,并將其設為零。 然而,這一次我們必須處理這樣一個事實:絕對函數并不總是可微的。當$x&gt;0$時,$\frac \部分\部分 x x=1$時。當$x&lt;0$時,$\frac \部分\部分 x x=-1$時。雖然$x 在$x=0$時在技術上是不可微的,但是我們將設置$\frac \ partial \ partial x x=0$以便方程更容易處理。 回想一下,MAE 的方程是: $$ \begin{aligned} L(\theta, \textbf{y}) &= \frac{1}{n} \sum_{i = 1}^{n}|y_i - \theta|\\ &= \frac{1}{n} \left( \sum_{y_i < \theta}|y_i - \theta| + \sum_{y_i = \theta}|y_i - \theta| + \sum_{y_i > \theta}|y_i - \theta| \right)\\ \end{aligned} $$ 在上面的行中,我們將求和分為三個單獨的求和:一個是每$y_i&lt;\theta$有一個術語,一個是每$y_i=\theta$有一個術語,一個是每$y_i&gt;\theta$有一個術語。為什么求和看起來更復雜?如果我們知道$y_i&lt;\theta$我們也知道$y_i-\theta&lt;0$因此之前的$frac \ partial \ partial \theta y_i-\theta=-1$上面的每個術語都有類似的邏輯,以使取導數更容易。 現在,我們取與$\theta$相關的導數,并將其設為零: $$ \begin{aligned} \frac{1}{n} \left( \sum_{y_i < \theta}(-1) + \sum_{y_i = \theta}(0) + \sum_{y_i > \theta}(1) \right) &= 0 \\ \sum_{y_i < \theta}(-1) + \sum_{y_i > \theta}(1) &= 0 \\ -\sum_{y_i < \theta}(1) + \sum_{y_i > \theta}(1) &= 0 \\ \sum_{y_i < \theta}(1) &= \sum_{y_i > \theta}(1) \\ \end{aligned} $$ 上面的結果是什么意思?在左側,對于每個小于$\theta$的數據點,我們有一個術語。在右邊,對于每個大于$\theta$的數據點,我們都有一個。然后,為了滿足這個方程,我們需要為$\theta$選擇一個值,該值具有相同數量的較小和較大的點。這是一組數字的 _ 中位數 _ 的定義。因此,MAE 的$theta$的最小值是$that\theta=\text 中位數(\textbf y)$。 當我們有奇數個點時,當點按排序順序排列時,中間值就是中間點。我們可以看到,在下面的例子中,當$\theta$位于中間值時,損失最小: ``` # HIDDEN def points_and_loss(y_vals, xlim, loss_fn=abs_loss): thetas = np.arange(xlim[0], xlim[1] + 0.01, 0.05) abs_losses = [loss_fn(theta, y_vals) for theta in thetas] plt.figure(figsize=(9, 2)) ax = plt.subplot(121) sns.rugplot(y_vals, height=0.3, ax=ax) plt.xlim(*xlim) plt.xlabel('Points') ax = plt.subplot(122) plt.plot(thetas, abs_losses) plt.xlim(*xlim) plt.xlabel(r'$ \theta $') plt.ylabel('Loss') points_and_loss(np.array([10, 11, 12, 14, 15]), (9, 16)) ``` ![](https://img.kancloud.cn/3a/b7/3ab73896414c8052e71f34893f347b4e_560x181.jpg) 但是,當我們有偶數個點時,當$\theta$是兩個中心點之間的任何值時,損失最小。 ``` # HIDDEN points_and_loss(np.array([10, 11, 14, 15]), (9, 16)) ``` ![](https://img.kancloud.cn/f1/a8/f1a857b423d781a07226df6d6c67de68_560x181.jpg) 當我們使用 MSE 時,情況并非如此: ``` # HIDDEN points_and_loss(np.array([10, 11, 14, 15]), (9, 16), mse_loss) ``` ![](https://img.kancloud.cn/fd/d4/fdd457e06d18a97d283a2e2235b6ec0b_560x181.jpg) ### mse 與 mae 比較[?](#MSE-and-MAE-Comparison) 我們的研究和上述推導表明,MSE 比 MAE 更容易區分,但對異常值更敏感。對于 MSE,$\hat \theta=\text mean(\textbf y)$,而對于 mae \hat \theta=\text mean(\textbf y)$。注意中位數受異常值的影響比平均值小。這一現象源于我們對兩個損失函數的構造。 我們還發現 MSE 有一個唯一的$\hat \theta$,而平均絕對值在有偶數個數據點的情況下可以是多個可能的$\hat \theta$值。 ### Huber 損失 第三個損失函數 huber loss 結合了 mse 和 mae,創建了一個對離群值具有可微性 _ 和 _ 的損失函數。Huber 損失通過類似于接近最小值的$\theta$值的 mse 函數和遠離最小值的$\theta$值的絕對損失來實現這一點。 和往常一樣,我們通過獲取數據集中每個點的 Huber 損失的平均值來創建一個損失函數。 讓我們看看當我們改變$\theta$時,huber loss 函數為一個數據集輸出了什么樣的結果。 ``` # HIDDEN def huber_loss(est, y_obs, alpha = 1): d = np.abs(est - y_obs) return np.where(d < alpha, (est - y_obs)**2 / 2.0, alpha * (d - alpha / 2.0)) thetas = np.linspace(0, 50, 200) loss = huber_loss(thetas, np.array([14]), alpha=5) plt.plot(thetas, loss, label="Huber Loss") plt.vlines(np.array([14]), -20, -5,colors="r", label="Observation") plt.xlabel(r"Choice for $\theta$") plt.ylabel(r"Loss") plt.legend() plt.savefig('huber_loss.pdf') ``` ![](https://img.kancloud.cn/c8/17/c817062e84d47ba4e0aeb65091470c04_420x290.jpg) 我們可以看到 Huber 損失是平穩的,不像 Mae。Huber 損失也以線性速率增加,與均方損失的二次速率不同。 然而,Huber 損失確實有一個缺點。注意,一旦$\theta$離這一點足夠遠,它就會從 MSE 過渡到 MAE。我們可以調整這個“足夠遠”來得到不同的損失曲線。例如,我們可以在離觀察點只有一個單位遠的地方進行一次$theta$轉換: ``` # HIDDEN loss = huber_loss(thetas, np.array([14]), alpha=1) plt.plot(thetas, loss, label="Huber Loss") plt.vlines(np.array([14]), -20, -5,colors="r", label="Observation") plt.xlabel(r"Choice for $\theta$") plt.ylabel(r"Loss") plt.legend() plt.savefig('huber_loss.pdf') ``` ![](https://img.kancloud.cn/4c/13/4c133b71cb18d564b2b212cc411b803f_420x290.jpg) 或者我們可以在離觀察點 10 個單位遠的地方進行轉換: ``` # HIDDEN loss = huber_loss(thetas, np.array([14]), alpha=10) plt.plot(thetas, loss, label="Huber Loss") plt.vlines(np.array([14]), -20, -5,colors="r", label="Observation") plt.xlabel(r"Choice for $\theta$") plt.ylabel(r"Loss") plt.legend() plt.savefig('huber_loss.pdf') ``` ![](https://img.kancloud.cn/46/90/4690863396c637885a83fc33f2de4683_420x290.jpg) 此選擇會導致不同的損失曲線,因此可能會導致不同的值$\hat\theta$。如果我們想使用 Huber 損失函數,我們還有一個額外的任務,就是將這個轉換點設置為合適的值。 Huber 損失函數的數學定義如下: $$ L_\alpha(\theta, \textbf{y}) = \frac{1}{n} \sum_{i=1}^n \begin{cases} \frac{1}{2}(y_i - \theta)^2 & | y_i - \theta | \le \alpha \\ \alpha ( |y_i - \theta| - \frac{1}{2}\alpha ) & \text{otherwise} \end{cases} $$ 它比以前的損失函數更復雜,因為它結合了 MSE 和 MAE。附加參數$\alpha$設置 Huber 損失從 MSE 過渡到絕對損失的點。 嘗試求 Huber 損失函數的導數是繁瑣的,不會產生像 mse 和 mae 這樣優雅的結果。相反,我們可以使用一種稱為梯度下降的計算方法來找到$\theta$的最小值。 ### 摘要[?](#Summary) 在本節中,我們介紹了兩個損失函數:平均絕對誤差和 Huber 損失函數。我們展示了一個使用 mae 擬合的常數模型,$\hat \theta=\text 中位數(\textbf y)$。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看