逻辑回归之sigmoid/tanh/relu激活函数

逻辑回归,就是在线性回归的基础上加入了激活函数。
常见的激活函数有:

  • 1、sigmoid函数
  • 2、tanh函数
  • 3、relu函数
sigmoid函数

sigmoid就是一个将输出映射到[0,1]之间的函数了。函数公式

y = 1 1 + e z
图像:
这里写图片描述
和之前计算梯度一样,我们需要的是计算loss对各个w和b的偏导数就可以了。原线性函数:
z = ω T x + b

加入激活函数后的loss:
l o s s = i = 1 n ( y i y ^ ) 2 = i = 1 2 ( ω T x i + b y ^ ) 2

求偏导数的时候,需要用到复合导数计算的链式法则:
l o s s ω 1 = l o s s y y z z ω 1

l o s s y = 2 i = 1 n ( y i y ^ )

y z = e z ( 1 + e z ) 2

z ω 1 = x 1

联合起来也就是:
l o s s ω 1 = 2 i = 1 n ( y i y ^ i ) e z ( 1 + e z ) 2 x i 1

这样我们发现和普通梯度函数的区别就是多了一个激活函数的梯度,也就是说逻辑回归的方法相当于在一个神经元的基础上加入了一个sigmoid的激活函数。
代码如下:

import numpy as np
import math
import time

def sigmoid(x):
    return 1.0/(1.0 + math.exp(-x))


def grad_sigmoid(x):
    return math.exp(-x)/((1+math.exp(-x))**2)

#随机梯度下降+sigmoid输出方法
sample = 100
num_input = 5

#加入训练数据
normalRand = np.random.normal(0,0.1,sample)
weight = [8,100,-1,-400,0.05]
x_train = np.random.random((sample,num_input))
y_train = np.zeros((sample,1))

for i in range(0,len(x_train)):
    total = 0
    for j in range(0,len(x_train[i])):
        total += weight[j]*x_train[i,j]
    y_train[i] = sigmoid(total + normalRand[i])

#训练

weight = np.random.random(num_input + 1)
rate = 0.01
batch = 3

def train(x_train,y_train):
    #计算loss
    global weight,rate
    predictZ = np.zeros((len(x_train),))
    predictY = np.zeros((len(x_train,)))

    for i in range(0,len(x_train)):
        predictZ[i] = np.dot(x_train[i],weight[0:num_input]) + weight[num_input]
        predictY[i] = sigmoid(predictZ[i])

    loss = 0
    for i in range(0,len(x_train)):
        loss += (predictY[i] - y_train[i])**2

    #计算梯度并更新
    for i in range(0,len(weight)-1):
        grade = 0
        for j in range(0,len(x_train)):
            grade += (predictY[j] - y_train[j])*grad_sigmoid(predictZ[j])*x_train[j,i]
        weight[i] = weight[i] - rate * grade

    grade = 0
    for j in range(0,len(x_train)):
        grade += (predictY[j] - y_train[j])
    weight[num_input] = weight[num_input] - rate * grade

    return loss

start = time.clock()
for epoch in range(0,100):
    begin = 0
    while begin < len(x_train):
        end = begin + batch
        if end > len(x_train):
            end = len(x_train)

        loss = train(x_train[begin:end],y_train[begin:end])
        begin = end
    print("epoch:%d-loss:%f"%(epoch,loss))

    if loss < 0.5:
        end = time.clock()
        print("收敛用时%s ms"%str(end - start))
        break

print(weight)
tanh函数

与sigmoid函数类似,tanh也是常见的激活函数,公式如下:

t a n h ( x ) = e x e x e x + e x
函数求导:
t a n h ( x ) = 1 t a n h 2 ( x )
图像:
这里写图片描述
tanh就是将输出映射到[-1,1]的范围里。

relu函数

公式:

f ( u ) = m a x ( 0 , u )

图像:
这里写图片描述
relu可谓是打开了新世界的大门,2012年AlexNet碾压ImageNet时就是使用了relu作为激活函数,它的优点是梯度易于计算(不是1,就是0,只有两种),而且梯度不会像sigmoid一样在边缘处梯度接近为0(梯度消失)。

猜你喜欢

转载自blog.csdn.net/legalhighhigh/article/details/81367638
今日推荐