文章目錄
- RReLU
- 函數+導函數
- 函數和導函數圖像
- 優缺點
- pytorch中的RReLU函數
- tensorflow 中的RReLU函數
RReLU
- 隨機修正線性單元:Randomized Leaky ReLU
函數+導函數
-
RReLU
函數
R R e L U = { x x ≥ 0 a x x < 0 \rm RReLU = \left\{ \begin{array}{} x \quad x \ge 0 \\ a x \quad x < 0 \end{array} \right. RReLU={xx≥0axx<0?
其中,( a ) 是一個在訓練過程中隨機從均勻分布 ( U(l, u) ) 中采樣的值,( l ) 和 ( u ) 是預先設定的下界和上界,通常 ( 0 < l < u < 1 )。 -
RReLU
函數導數
d d x R R e L U = { 1 x ≥ 0 a x < 0 \frac{d}{dx} \rm RReLU = \left\{ \begin{array}{} 1 \quad x \ge 0 \\ a \quad x < 0 \end{array} \right. dxd?RReLU={1x≥0ax<0?
在 RReLU 中,當 ( x < 0 ) 時,導數是一個隨機變量 ( a ),這個隨機變量在每次訓練時都會從 ( U(l, u) ) 中重新采樣。與 LeakyReLU 不同,RReLU 的斜率 ( a ) 是隨機的,而不是固定的。
函數和導函數圖像
-
畫圖
分為兩張圖了,上面是訓練階段,在訓練階段,負值部分的斜率
P
是隨機從區間[lower, upper]
中采樣的。在測試階段,負值部分的斜率P
是區間[lower, upper]
的平均值((lower + upper) / 2)
。import numpy as np from matplotlib import pyplot as plt# 定義 RReLU 函數 def rrelu_train(x, lower=0.125, upper=0.333):P = np.random.uniform(lower, upper) # 訓練階段:隨機化負值部分的斜率return np.where(x < 0, P * x, x)def rrelu_test(x, lower=0.125, upper=0.333):P = (lower + upper) / 2 # 測試階段:使用負值部分的平均斜率return np.where(x < 0, P * x, x)# 定義 RReLU 的導數 def rrelu_derivative_train(x, lower=0.125, upper=0.333):P = np.random.uniform(lower, upper) # 訓練階段:隨機化負值部分的斜率return np.where(x < 0, P, 1)def rrelu_derivative_test(x, lower=0.125, upper=0.333):P = (lower + upper) / 2 # 測試階段:使用負值部分的平均斜率return np.where(x < 0, P, 1)# 生成數據 x = np.linspace(-2, 2, 1000) lower = 1/8 # 負值部分斜率的下限 upper = 1/3 # 負值部分斜率的上限# 訓練階段 y_train = [rrelu_train(xi, lower, upper) for xi in x] y1_train = [rrelu_derivative_train(xi, lower, upper) for xi in x]# 測試階段 y_test = [rrelu_test(xi, lower, upper) for xi in x] y1_test = [rrelu_derivative_test(xi, lower, upper) for xi in x]# 繪制圖形 fig, axs = plt.subplots(2, 1, figsize=(12, 12))# 訓練階段 axs[0].plot(x, y_train, label='RReLU (Train)', color='blue') axs[0].plot(x, y1_train, label='Derivative (Train)', color='orange') axs[0].set_title(f'RReLU (Train) and Derivative (lower={lower}, upper={upper})') axs[0].legend(loc='upper left') axs[0].spines['right'].set_color('none') axs[0].spines['top'].set_color('none') axs[0].spines['bottom'].set_position(('data', 0)) axs[0].spines['left'].set_position(('data', 0))# 測試階段 axs[1].plot(x, y_test, label='RReLU (Test)', color='blue', linestyle='--') axs[1].plot(x, y1_test, label='Derivative (Test)', color='orange', linestyle='--') axs[1].set_title(f'RReLU (Test) and Derivative (lower={lower}, upper={upper})') axs[1].legend(loc='upper left') axs[1].spines['right'].set_color('none') axs[1].spines['top'].set_color('none') axs[1].spines['bottom'].set_position(('data', 0)) axs[1].spines['left'].set_position(('data', 0))plt.tight_layout() plt.show()
?
優缺點
- RReLU函數相對于PeLU函數的改進
- RReLU函數和PReLU函數的表達式一樣,但是參數 α \alpha α 不一樣,這里的 α \alpha α 是個隨機震蕩的數,范圍是 1 8 ? 1 3 \frac{1}{8} - \frac{1}{3} 81??31?
- 負部分的斜率在訓練中被隨機化到給定的范圍內,然后再測試中被固定。而PReLU訓練中的斜率是訓練出來的。
-
RReLU 的優點
- 緩解“死亡ReLU”問題:與ReLU不同,RReLU在負輸入時引入了一個隨機的斜率,這使得神經元不會因為負輸入而完全失去梯度,從而避免了“死亡ReLU”問題。
- 增強梯度流:RReLU通過在負輸入時提供一個非零梯度,有助于改善梯度消失問題,使得網絡在訓練過程中能夠更好地更新權重。
- 增加模型的靈活性:RReLU的隨機斜率在訓練過程中可以動態調整,這增加了模型的靈活性和適應性,使其能夠更好地處理復雜的模式。
- 提高模型的泛化能力:由于RReLU在訓練時引入了隨機性,這可以作為一種正則化手段,有助于提高模型的泛化能力。
-
RReLU 的缺點
- 計算復雜度增加:RReLU的隨機斜率需要在每次訓練時進行計算,這增加了計算復雜度和訓練時間。
- 參數選擇敏感:RReLU的隨機斜率范圍需要合理選擇,如果選擇不當,可能會導致模型訓練不穩定。
- 測試時的確定性問題:在訓練階段,RReLU使用隨機斜率,而在測試階段,通常會使用一個固定的斜率(通常是訓練階段隨機斜率的期望值)。這種從隨機到確定性的轉換可能會導致測試時的性能與訓練時略有差異。
- 可能的過擬合風險:由于RReLU引入了額外的隨機性,如果數據集較小或模型復雜度較高,可能會增加過擬合的風險。
pytorch中的RReLU函數
-
代碼
這里僅僅演示訓練階段 α \alpha α 為隨機值的時候
l o w e r = 1 / 8 \mathrm lower = 1/8 lower=1/8
u p p e r = 1 / 3 \mathrm upper = 1/3 upper=1/3
# 定義 RReLU 函數 f = torch.nn.RReLU(lower=0.125,upper=0.333) # PyTorch 提供的 RReLU 激活函數模塊 x = torch.randn(2) # 生成一個隨機張量作為輸入rrelu_x = f(x) # 應用 RReLU 函數print(f"x: \n{x}") print(f"rrelu_x:\n{rrelu_x}")"""輸出"""
tensorflow 中的RReLU函數
-
代碼
python: 3.10.9
tensorflow: 2.18.0
rrelu并不是tensorflow標準庫的一部分,為此我們實現一個RReLU函數,包含訓練階段和推理階段
這里僅僅演示訓練階段 α \alpha α 為隨機值的時候
l o w e r = 1 / 8 \mathrm lower = 1/8 lower=1/8
u p p e r = 1 / 3 \mathrm upper = 1/3 upper=1/3
import tensorflow as tfclass RReLU(tf.keras.layers.Layer):def __init__(self, lower=0.125, upper=0.333, **kwargs):super(RReLU, self).__init__(**kwargs)self.lower = lowerself.upper = upperdef call(self, inputs, training=None):if training:# 在訓練模式下,隨機選擇一個斜率alpha = tf.random.uniform(shape=inputs.shape, minval=self.lower, maxval=self.upper)else:# 在推理模式下,使用平均斜率alpha = (self.lower + self.upper) / 2.0return tf.where(inputs >= 0, inputs, alpha * inputs)# 創建 RReLU 激活函數層 rrelu = RReLU()# 生成隨機輸入 x = tf.random.normal([2])# 應用 RReLU 激活函數 rrelu_x = rrelu(x, training=True)print(f"x: \n{x}") print(f"rrelu_x:\n{rrelu_x}")"""輸出""" x: [-0.97807205 0.9327775 ] rrelu_x: [-0.26978785 0.9327775 ]