天天看點

Sigmoid函數的特性及硬體實作方法--含matlab代碼及講解1. 簡介2. sigmoid函數的特性介紹3. 硬體實作方案4. matlab代碼實作及講解

sigmoid函數的特性及硬體實作方法--含matlab代碼實作及講解

  • 1. 簡介
  • 2. sigmoid函數的特性介紹
    • 2.1 sigmoid(x)與sigmoid(-x)的關系
    • 2.2 sigmoid函數與tanh函數的關系
    • 2.3 sigmoid函數的n階導數
    • 2.4 當x=n*ln2時的數值
    • 2.5 其他關系式
  • 3. 硬體實作方案
  • 4. matlab代碼實作及講解

1. 簡介

sigmoid是神經網絡中常用的一種激活函數,在機械學習和很多降噪濾波算法中也常常會用到這個函數。sigmoid函數的表達式如下:

y = s i g m o i d ( x ) = 1 1 + e x p ( − x ) y=sigmoid(x)=\frac {1} {1+exp(-x)} y=sigmoid(x)=1+exp(−x)1​

本文主要會介紹一些sigmoid函數常用的特性。并且基于sigmoid函數特有的性質,我會給出一種硬體實作sigmoid函數的方法(不是多項式拟合法),為了友善讀者了解,我還用matlab模拟了sigmoid函數的實作。有興趣的小夥伴可以直接到我下面的連結中下載下傳代碼。

https://download.csdn.net/download/qq_35721810/10885213

2. sigmoid函數的特性介紹

2.1 sigmoid(x)與sigmoid(-x)的關系

sigmoid(x)與sigmoid(-x)的具有下面的關系:

s i g m o i d ( − x ) = 1 − s i g m o i d ( x ) sigmoid(-x) = 1 - sigmoid(x) sigmoid(−x)=1−sigmoid(x)

推導過程如下:

1 − s i g m o i d ( x ) = 1 − 1 1 + e x p ( − x ) = e x p ( − x ) 1 + e x p ( − x ) = 1 1 + e x p ( x ) = s i g m o i d ( − x ) 1-sigmoid(x) = 1-\frac {1} {1+exp(-x)}=\frac {exp(-x)} {1+exp(-x)}=\frac {1} {1+exp(x)}= sigmoid(-x) 1−sigmoid(x)=1−1+exp(−x)1​=1+exp(−x)exp(−x)​=1+exp(x)1​=sigmoid(−x)

2.2 sigmoid函數與tanh函數的關系

tanh(x)為雙曲餘弦函數,其表達式如下

t a n h ( x ) = e x p ( x ) − e x p ( − x ) e x p ( x ) + e x p ( − x ) tanh(x)=\frac {exp(x)-exp(-x)} {exp(x)+exp(-x)} tanh(x)=exp(x)+exp(−x)exp(x)−exp(−x)​

sigmoid(x)與tanh(x)函數的關系如下:

s i g m o i d ( x ) = t a n h ( x 2 ) + 1 2 sigmoid(x) =\frac {tanh(\frac {x} {2})+1} {2} sigmoid(x)=2tanh(2x​)+1​

推導過程如下:

t a n h ( x 2 ) + 1 2 = e x p ( x / 2 ) − e x p ( − x / 2 ) e x p ( x / 2 ) + e x p ( − x / 2 ) + 1 2 = e x p ( x / 2 ) ( e x p ( x / 2 ) + e x p ( − x / 2 ) ) = 1 1 + e x p ( − x ) = s i g m o i d ( x ) \frac {tanh(\frac {x} {2})+1} {2}=\frac{\frac {exp(x/2)-exp(-x/2)} {exp(x/2)+exp(-x/2)}+1}{2}=\frac {exp(x/2)} {(exp(x/2)+exp(-x/2))}=\frac {1} {1+exp(-x)}=sigmoid(x) 2tanh(2x​)+1​=2exp(x/2)+exp(−x/2)exp(x/2)−exp(−x/2)​+1​=(exp(x/2)+exp(−x/2))exp(x/2)​=1+exp(−x)1​=sigmoid(x)

2.3 sigmoid函數的n階導數

sigmoid函數求導有一個非常好的特殊性質,即導數的結果是可以完全表達成y的函數,與x無關。 假設 y = s i g m o i d ( x ) = 1 1 + e x p ( − x ) y=sigmoid(x)=\frac {1} {1+exp(-x)} y=sigmoid(x)=1+exp(−x)1​

d y d x = e x p ( − x ) [ 1 + e x p ( − x ) ] 2 = ( 1 − 1 1 + e x p ( − x ) ) 1 1 + e x p ( − x ) = y ( 1 − y ) \frac{dy}{dx}=\frac {exp(-x)} {[1+exp(-x)]^2}=\left( 1-\frac {1} {1+exp(-x)}\right)\frac {1} {1+exp(-x)}=y(1-y) dxdy​=[1+exp(−x)]2exp(−x)​=(1−1+exp(−x)1​)1+exp(−x)1​=y(1−y)

即 d y d x \frac{dy}{dx} dxdy​隻是y的函數。如果要求二階導數可以直接對 d y d x \frac{dy}{dx} dxdy​再次求導

d 2 y d x 2 = d d x ( d y d x ) = ( 1 − 2 y ) d y d x = y ( 1 − y ) ( 1 − 2 y ) \frac{d^2y}{dx^2}=\frac{d}{dx}\left(\frac{dy}{dx}\right)=(1-2y)\frac{dy}{dx}=y(1-y)(1-2y) dx2d2y​=dxd​(dxdy​)=(1−2y)dxdy​=y(1−y)(1−2y)

根據上述方法,sigmoid函數的前n-1階導數一定一個隻含有y的函數,對y求導再乘以y(1-y)就是sigmoid函數的n階導數。這裡我沒有推導出sigmoid函數的n階導數的緊湊表達式。有興趣的同學可以自己推導試一下,也歡迎大神留言給出正解。

另一種求解sigmoid函數n階導數的方法,就是利用它與tanh(x)的關系。由于 s i g m o i d ( x ) = t a n h ( x 2 ) + 1 2 sigmoid(x) =\frac {tanh(\frac {x} {2})+1} {2} sigmoid(x)=2tanh(2x​)+1​,是以sigmoid(x)的n階導數其實就是 1 2 t a n h ( x 2 ) \frac{1}{2}tanh(\frac{x}{2}) 21​tanh(2x​)的n階導。tanh(x)的n階導數有一些複雜,國内的高等數學教材中并沒有提到,最後我還是在一篇NASA的技術筆記[1]中找到的,這裡我直接給出tanh(x)函數的n階導數結果:

d 2 n t a n h ( x ) d x 2 n = t a n h ( x ) ∑ k = 1 n − 1 ( − 1 ) n − k W 2 ( n − k ) , k [ 2 ( n − k ) ] ! s e c h ( x ) 2 ( n − k ) \frac{d^{2n}tanh(x)}{dx^{2n}}=tanh(x)\sum_{k=1}^{n-1} {(-1)^{n-k}W_{2(n-k),k}[2(n-k)]!sech(x)^{2(n-k)}} dx2nd2ntanh(x)​=tanh(x)k=1∑n−1​(−1)n−kW2(n−k),k​[2(n−k)]!sech(x)2(n−k)

d 2 n + 1 t a n h ( x ) d x 2 n + 1 = t a n h ( x ) ∑ k = 0 n ( − 1 ) n − k W 2 ( n − k + 1 ) , k [ 2 ( n − k ) + 1 ] ! s e c h ( x ) 2 ( n − k + 1 ) \frac{d^{2n+1}tanh(x)}{dx^{2n+1}}=tanh(x)\sum_{k=0}^{n} {(-1)^{n-k}W_{2(n-k+1),k}[2(n-k)+1]!sech(x)^{2(n-k+1)}} dx2n+1d2n+1tanh(x)​=tanh(x)k=0∑n​(−1)n−kW2(n−k+1),k​[2(n−k)+1]!sech(x)2(n−k+1)

上式中的 W 2 n , k W_{2n,k} W2n,k​可以通過下面的遞推公式得到

W 2 , k = 2 2 k W_{2,k}=2^{2k} W2,k​=22k

W 4 , k = ∑ m = 0 k 2 2 ( k + m ) W_{4,k}=\sum_{m=0}^{k}{2^{2(k+m)}} W4,k​=m=0∑k​22(k+m)

W 2 n , k = ( 2 n ) 2 W 2 n , k − 1 + W 2 ( n − 1 ) , k W_{2n,k}=(2n)^{2}W_{2n,k-1}+W_{2(n-1),k} W2n,k​=(2n)2W2n,k−1​+W2(n−1),k​

是以根據tanh(x)的n階導數可以得到sigmoid(x)的n階導數,具體形式如下

d 2 n s i g m o i d ( x ) d x 2 n = 1 2 2 n + 1 t a n h ( x 2 ) ∑ k = 1 n − 1 ( − 1 ) n − k W 2 ( n − k ) , k [ 2 ( n − k ) ] ! s e c h ( x 2 ) 2 ( n − k ) \frac{d^{2n}sigmoid(x)}{dx^{2n}}=\frac{1}{2^{2n+1}}tanh(\frac{x}{2})\sum_{k=1}^{n-1} {(-1)^{n-k}W_{2(n-k),k}[2(n-k)]!sech(\frac{x}{2})^{2(n-k)}} dx2nd2nsigmoid(x)​=22n+11​tanh(2x​)k=1∑n−1​(−1)n−kW2(n−k),k​[2(n−k)]!sech(2x​)2(n−k)

d 2 n + 1 s i g m o i d ( x ) d x 2 n + 1 = 1 2 2 n + 2 t a n h ( x 2 ) ∑ k = 0 n ( − 1 ) n − k W 2 ( n − k + 1 ) , k [ 2 ( n − k ) + 1 ] ! s e c h ( x 2 ) 2 ( n − k + 1 ) \frac{d^{2n+1}sigmoid(x)}{dx^{2n+1}}=\frac{1}{2^{2n+2}}tanh(\frac{x}{2})\sum_{k=0}^{n} {(-1)^{n-k}W_{2(n-k+1),k}[2(n-k)+1]!sech(\frac{x}{2})^{2(n-k+1)}} dx2n+1d2n+1sigmoid(x)​=22n+21​tanh(2x​)k=0∑n​(−1)n−kW2(n−k+1),k​[2(n−k)+1]!sech(2x​)2(n−k+1)

2.4 當x=n*ln2時的數值

這個特性其實非常有趣,當 x = n ∗ l n 2 x=n*ln2 x=n∗ln2(n可以為任意非0的整數,可正可負)時,sigmoid函數可以變成

s i g m o i d ( n ∗ l n 2 ) = 1 1 + 2 − n sigmoid(n*ln2)=\frac{1}{1+2^{-n}} sigmoid(n∗ln2)=1+2−n1​

1 1 + 2 − n \frac{1}{1+2^{-n}} 1+2−n1​的機械數是非常有規律的.

下面給一個幾個例子

當 n = 1 n=1 n=1時,

1 1 + 2 − 1 = ( 0.10101010... ) 2 \frac{1}{1+2^{-1}}=(0.10101010...)_2 1+2−11​=(0.10101010...)2​

上式中 ( ) 2 ()_2 ()2​代表2進制表示。

當 n = 2 n=2 n=2時,

1 1 + 2 − 2 = ( 0.1100110011001100... ) 2 \frac{1}{1+2^{-2}}=(0.1100110011001100...)_2 1+2−21​=(0.1100110011001100...)2​

當 n = 3 n=3 n=3時,

1 1 + 2 − 3 = ( 0.111000111000111000111000... ) 2 \frac{1}{1+2^{-3}}=(0.111000111000111000111000...)_2 1+2−31​=(0.111000111000111000111000...)2​

以此類推,當n大于0時,sigmoid函數的結果的機器數為n個1和0交替。

當 n = − 1 n=-1 n=−1時,

1 1 + 2 1 = ( 0.01010101... ) 2 \frac{1}{1+2^{1}}=(0.01010101...)_2 1+211​=(0.01010101...)2​

當 n = − 2 n=-2 n=−2時,

1 1 + 2 2 = ( 0.0011001100110011... ) 2 \frac{1}{1+2^{2}}=(0.0011001100110011...)_2 1+221​=(0.0011001100110011...)2​

當 n = − 3 n=-3 n=−3時,

1 1 + 2 3 = ( 0.000111000111000111000111... ) 2 \frac{1}{1+2^{3}}=(0.000111000111000111000111...)_2 1+231​=(0.000111000111000111000111...)2​

當n小于0時,sigmoid函數的結果的機器數為n個0和1交替。

根據上述性質,我們可以很容易通過硬體實作 x = n ∗ l n 2 x=n*ln2 x=n∗ln2時的sigmoid函數值。

2.5 其他關系式

sigmoid函數有一個非常類似柯西中值定理的關系式:

s i g m o i d ( x 1 ) − s i g m o i d ( x 2 ) = 1 1 + e x p ( − x 1 ) − 1 1 + e x p ( − x 2 ) = e x p ( x 2 ) − e x p ( x 1 ) [ 1 + e x p ( − x 1 ) ] [ 1 + e x p ( x 2 ) ] sigmoid(x_1)-sigmoid(x_2)=\frac {1} {1+exp(-x_1)}-\frac {1} {1+exp(-x_2)}=\frac {exp(x_2)-exp(x_1)} {[1+exp(-x_1)][1+exp(x_2)]} sigmoid(x1​)−sigmoid(x2​)=1+exp(−x1​)1​−1+exp(−x2​)1​=[1+exp(−x1​)][1+exp(x2​)]exp(x2​)−exp(x1​)​

s i g m o i d ( x 1 ) − s i g m o i d ( x 2 ) e x p ( − x 1 ) − e x p ( − x 2 ) = − s i g m o i d ( x 1 ) s i g m o i d ( x 2 ) \frac {sigmoid(x_1)-sigmoid(x_2)} {exp(-x_1)-exp(-x_2)}=-sigmoid(x_1)sigmoid(x_2) exp(−x1​)−exp(−x2​)sigmoid(x1​)−sigmoid(x2​)​=−sigmoid(x1​)sigmoid(x2​)

公式的左邊與柯西中值定理很像

f ( x 1 ) − f ( x 2 ) g ( x 1 ) − g ( x 2 ) = f ′ ( ξ ) g ′ ( ξ ) \frac {f(x_1)-f(x_2)} {g(x_1)-g(x_2)}=\frac{f'(\xi)}{g'(\xi)} g(x1​)−g(x2​)f(x1​)−f(x2​)​=g′(ξ)f′(ξ)​

3. 硬體實作方案

sigmoid函數的硬體實作很多是通過分區多項式拟合法得到的。這裡我給大家介紹一種基于泰勒級數展開的硬體實作方法。并且在下文中我會給出matlab版本的實作。

首先泰勒級數展開的方法如下:

f ( x 0 + Δ x ) = f ( x 0 ) + d f ( x 0 ) d x Δ x + 1 2 ! d 2 f ( x 0 ) d x 2 ( Δ x ) 2 + . . . + 1 n ! d n f ( x 0 ) d x n ( Δ x ) n f(x_0+\Delta x)=f(x_0)+\frac{df(x_0)}{dx}\Delta x+\frac{1}{2!}\frac{d^2f(x_0)}{dx^2}(\Delta x)^2+...+\frac{1}{n!}\frac{d^nf(x_0)}{dx^n}(\Delta x)^n f(x0​+Δx)=f(x0​)+dxdf(x0​)​Δx+2!1​dx2d2f(x0​)​(Δx)2+...+n!1​dxndnf(x0​)​(Δx)n

需要指出的是泰勒級數展開其實隻能适用于一個 Δ x \Delta x Δx很小的區域範圍。對于從負無窮到正無窮範圍取值的sigmoid函數,我們很難僅通過零點展開對其進行近似。

如果可以找到在任意 x x x附近的一個 x 0 x_0 x0​,并且我們可以得到 f ( x 0 ) f(x_0) f(x0​), d f ( x 0 ) d x \frac{df(x_0)}{dx} dxdf(x0​)​,…, d n f ( x 0 ) d x n \frac{d^nf(x_0)}{dx^n} dxndnf(x0​)​,那麼就可以計算泰勒級數的展開結果。對于硬體實作其實 1 n ! \frac{1}{n!} n!1​可以認為是一個預先算好的系數。

回憶第2節中我們提到兩個sigmoid的性質。當 x = n ∗ l n 2 x=n*ln2 x=n∗ln2時,sigmoid函數的機械數是很容易計算的,其次如果sigmoid函數的任意n階導數隻是sigmoid函數值的函數,即我們可以很容易得到 x = n ∗ l n 2 x=n*ln2 x=n∗ln2時,sigmoid函數的任意n階導數。根據上述方法我們可以得到一種基于泰勒級數展開的硬體實作方案。其基本思想如下:

1. 輸入任意x,找到距離x最近的 x 0 = n ∗ l n 2 x_0=n*ln2 x0​=n∗ln2。

2. 計算 x 0 = n ∗ l n 2 x_0=n*ln2 x0​=n∗ln2時的函數值,以及n階導數, 1 n ! \frac{1}{n!} n!1​可以預先計算好輸入。

3. 利用泰勒級數展開公式對sigmoid函數進行計算。

4. matlab代碼實作及講解

下面我會給出泰勒級數展開法實作sigmoid函數的matlab代碼。可以點選下面的連結下載下傳我的代碼:

https://download.csdn.net/download/qq_35721810/10885213

Sigmoid函數的特性及硬體實作方法--含matlab代碼及講解1. 簡介2. sigmoid函數的特性介紹3. 硬體實作方案4. matlab代碼實作及講解

圖 1 matlab代碼

解壓sigmoid_function.rar裡面有四個.m檔案。test.m是一個測試案例。sigmoid_hw.m是主要的實作函數。buildRefVal.m是用來計算 x 0 = n l n 2 x0=nln2 x0=nln2時的結果。sigmoidTaylor.m是sigmoid的泰勒展系數的計算方法。下面我會依次介紹這幾個檔案。

1. test.m

其代碼如下:

clear
% 計算x0 = nln2時,f(x0)的機械數的最大長度
byteNum = 64;
% 泰勒級數展開的階數
taylorNum = 2;

% 生成x
dx = 0.01;
x = 0:dx:5;

% 計算golden數值
golden = 1 ./ (1 + exp(-x));

% 周遊每一個x 用泰勒級數展開法計算sigmoid函數
for i = 1:length(x)
    [result_hw(i),~] = sigmoid_hw(x(i),byteNum,taylorNum);
end

% 顯示結果
disp('the max error is ')
disp(max(abs(result_hw-golden)))

plot(x,golden)
hold on
plot(x,result_hw,'--r')
           

byteNum是當 x 0 = n l n 2 x_0=nln2 x0​=nln2的最大機械數的長度,taylorNum是泰勒級數展開的階數。計算中的golden直接通過matlab的函數直接實作。byteNum是當 x 0 = n l n 2 x_0=nln2 x0​=nln2的最大機械數的長度,taylorNum是泰勒級數展開的階數。計算中的golden直接通過matlab的函數直接實作。sigmoid_hw是實作泰勒級數展開發的核心函數。

2. sigmoid_hw.m

代碼如下:

% 這個函數采用泰勒級數展開法計算函數sigmoid
% 輸入:
% x 需要計算的sigmoid(x)的結果
% byteNum 為計算x0 = nln2時,f(x0)的機械數的最大長度
% taylorNum 為泰勒級數展開階數
% 輸出:
% val為最後結果
% taylorSeries 是一個n階向量,它代表x0 = nln2時的n階泰勒級數計算結果

function [val,taylorSeries] = sigmoid_hw(x,byteNum,taylorNum)
% 計算ln2 
ln2 =  log(2);
% 得到距離x最近的x0,refX就是x0
n = round(-x/ln2);
refX = -n * ln2;

% 計算x0 = nln2時的機器數,并且轉化為10進制數
refVal = buildRefVal(n,byteNum);
% 計算dx
dx = x - refX;

% 計算x0 = nln2時的n階泰勒級數計算結果
taylorSeries = sigmoidTaylor(refVal,taylorNum);

% 計算dx^n
for i = 1:length(taylorSeries)
    if i == 1
       dxn(i) =  dx;
    else
       dxn(i) =  dxn(i-1)*dx;
    end
end

% 泰勒級數n階求和
val  = dot(taylorSeries,dxn) + refVal;
end
           

函數sigmoid_hw輸入的是剛才提到的byteNum,taylorNum還有需要計算的點x。輸出的結果是最後泰勒級數展開法計算得到的結果val以及泰勒級數的系數taylorSeries 。首先先找到裡x最近的 x 0 = n l n 2 x_0=nln2 x0​=nln2。這裡 n = r o u n d ( x / l n 2 ) n=round(x/ln2) n=round(x/ln2)。buildRefVal函數是根據得到的n計算 s i g m o i d ( x 0 ) sigmoid(x_0) sigmoid(x0​),也就是上文提到的一串循環重複的0,1序列。得到 s i g m o i d ( x 0 ) sigmoid(x_0) sigmoid(x0​)之後,根據sigmoidTaylor函數計算n階泰勒級數展開的系數。buildRefVal和sigmoidTaylor會在下面講解。

3. buildRefVal.m

代碼如下:

% 本函數用于産生 1 / (1 + 2^n)的結果
% 當 n = 1, 1 / (1 + 2^n) = 01010101...
% 當 n = 2, 1 / (1 + 2^n) = 001100110011...
% 當 n = -1, 1 / (1 + 2^n) = 101010101...
% 當 n = -2, 1 / (1 + 2^n) = 110011001100...
% 輸入
% n 是1 / (1 + 2^n)中的n
% threshold 最大的二進制長度
% 輸出
% val 為1/(1 + 2^n)的十進制結果

function val = buildRefVal(n,threshold)
if n == 0
    val = 0.5;
    return
end

val = 0;
counter = 1;
if n > 0 
   while(counter <= threshold)
        binary = mod(fix((counter-1)/n),2);
        val = val + binary*1/2^counter;
        counter = counter + 1;
   end
else
    while(counter <= threshold)
        binary = 1-mod(fix((counter-1)/-n),2);
        val = val + binary*1/2^counter;
        counter = counter + 1;
    end
end
end
           

當 x 0 = n l n 2 x_0=nln2 x0​=nln2時,sigmoid函數等于

s i g m o i d ( − n l n 2 ) = 1 1 + 2 n sigmoid(-nln2)=\frac{1}{1+2^{n}} sigmoid(−nln2)=1+2n1​

buildRefVal函數則是計算 1 1 + 2 n \frac{1}{1+2^{n}} 1+2n1​的結果。如上文提到的 1 1 + 2 n \frac{1}{1+2^{n}} 1+2n1​是一串n個連續循環的01序列,當n>0時,先0後1;當n<0時先1後0。buildRefVal函數中輸出的結果是以十進制形式表示的,其基本實作是設定一個counter,當counter-1整除n為奇數時輸出0(或者1),反之則輸出1(或者0)。同僚counter數有可以表示2進制數小數點後的位數,是以當結果為1時,在結果val中加上1/2^counter。

4. sigmoidTaylor

代碼如下:

% 計算sigmoid的n階泰勒級數展開項
% 輸入
% valY 是f(x0)
% n 代表泰勒級數展開項
% 輸出
% z 是一個n維向量, 代表[df/dx, d2f/dx2, ...,dnf/dxn]

function [z] = sigmoidTaylor(valY,n)
% 這裡通過matlab的符号運算直接求導計算,在硬體實作過程中,可以實作知道函數的形式
syms t
for i = 1:n
    if i == 1
        % y0 代表df/dx
        y0 = t*(1-t);
        y = y0;
        % 将y值帶入方程
        z(i) = double(subs(y,t,valY));
    else
        %對上一次的結果求導
        y = diff(y,t)*y0;
        z(i) = double(subs(y,t,valY));
        %除以n的階乘
        z(i) = z(i)/factorial(n);
    end
end
end
           

sigmoidTaylor函數用于求解n階導數系數。這裡為了提升函數的通用性我直接用符号運算中的求導來計算。事實上在硬體實作過程中這些函數,包括1/n!可以預先算好。求導的方法根據上文2.3節中提到的sigmoid函數n階導數的求解方法即可。

最後給讀者一張2階精度拟合下的結果圖。可以看到泰勒級數展開法的拟合結果與matlab裡直接計算的golden結果還是比較貼近的,最大的誤差為8.0948e-04。

Sigmoid函數的特性及硬體實作方法--含matlab代碼及講解1. 簡介2. sigmoid函數的特性介紹3. 硬體實作方案4. matlab代碼實作及講解

[1] formulas for nth order derivatives of hyperbolic and trigonometric functions, Edwin G. Wintucky, 1971.

繼續閱讀