机器学习入门(12)— 激活函数层 ReLU、Sigmoid 层的实现
1. ReLU 函數層
激活函數 ReLU(Rectified Linear Unit)由下式(5.7)表示。
通過式(5.7),可以求出 y 關于 x 的導數,如式(5.8)所示。
在式(5.8)中,如果正向傳播時的輸入 x 大于0,則反向傳播會將上游的值原封不動地傳給下游。反過來,如果正向傳播時的 x 小于等于0,則反向傳播中傳給下游的信號將停在此處。用計算圖表示的話,如圖5-18 所示。
在神經網絡的層的實現中,一般假定 forward() 和 backward() 的參數是 NumPy 數組。如下代碼所示:
class Relu:def __init__(self):self.mask = Nonedef forward(self, x):self.mask = (x <= 0)out = x.copy()out[self.mask] = 0return outdef backward(self, dout):dout[self.mask] = 0dx = doutreturn dx
Relu 類有實例變量 mask 。這個變量 mask 是由 True / False 構成的 NumPy 數組,它會把正向傳播時的輸入 x 的元素中小于等于 0 的地方保存為 True ,其他地方(大于0 的元素)保存為 False 。
如下例所示,mask 變量保存了由 True / False 構成的 NumPy 數組。
In [3]: x = np.array( [[1.0, -0.5], [-2.0, 3.0]] )In [4]: x
Out[4]:
array([[ 1. , -0.5],[-2. , 3. ]])In [5]: mask = (x<=0)In [6]: mask
Out[6]:
array([[False, True],[ True, False]])In [7]:
如圖 5-18 所示,如果正向傳播時的輸入值小于等于 0,則反向傳播的值為 0。因此,反向傳播中會使用正向傳播時保存的 mask ,將從上游傳來的 dout 的mask 中的元素為 True 的地方設為0。
2. Sigmoid 層
sigmoid 函數由式(5.9)表示:
用計算圖表示式(5.9)的話,則如圖5-19 所示。
exp節點會進行y = exp(x)的計算;/節點會進行 y=1xy=\frac{1}{x}y=x1? 的計算;
反向傳播流程:
/節點表示 y=1xy=\frac{1}{x}y=x1?,它的導數可以解析性地表示為下式。
根據式(5.10),反向傳播時,會將上游的值乘以?y2(正向傳播的輸出的平方乘以?1后的值)后,再傳給下游。計算圖如下所示。
+節點將上游的值原封不動地傳給下游。計算圖如下所示。
exp節點表示y = exp(x),它的導數由下式表示。
計算圖中,上游的值乘以正向傳播時的輸出(這個例子中是exp(?x))后,再傳給下游。
×節點將正向傳播時的值翻轉后做乘法運算。因此,這里要乘以 ?1。
根據上述內容,圖5-20的計算圖可以進行Sigmoid層的反向傳播。從圖 5-20 的結果可知,反向傳播的輸出為 ?L?yy2exp(?x)\frac{\partial L}{\partial y} y^2exp(-x)?y?L?y2exp(?x),這個值會傳播給下游的節點。
這里要注意, 這個值 ?L?yy2exp(?x)\frac{\partial L}{\partial y} y^2exp(-x)?y?L?y2exp(?x) 只根據正向傳播時的輸入x和輸出y就可以算出來。
因此,圖5-20的計算圖可以畫成圖5-21的集約化的sigmoid節點。
圖5-20 的計算圖和簡潔版的圖5-21 的計算圖的計算結果是相同的,但是,簡潔版的計算圖可以省略反向傳播中的計算過程,因此計算效率更高。此外,通過對節點進行集約化,可以不用在意 Sigmoid 層中瑣碎的細節,而只需要專注它的輸入和輸出,這一點也很重要。
另外, ?L?yy2exp(?x)\frac{\partial L}{\partial y} y^2exp(-x)?y?L?y2exp(?x) 可以進一步整理如下。
因此,圖5-21 所表示的 Sigmoid 層的反向傳播,只根據正向傳播的輸出就能計算出來。
用代碼實現結果如下:
class Sigmoid:def __init__(self):self.out = Nonedef forward(self, x):out = sigmoid(x)self.out = outreturn outdef backward(self, dout):dx = dout * (1.0 - self.out) * self.outreturn dx
這個實現中,正向傳播時將輸出保存在了實例變量 out 中。然后,反向傳播時,使用該變量 out 進行計算。
參考:《深度學習入門:基于Python的理論與實現》
總結
以上是生活随笔為你收集整理的机器学习入门(12)— 激活函数层 ReLU、Sigmoid 层的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器学习入门(11)— 反向传播的加法节
- 下一篇: 机器学习入门(13)— Affine 仿