天天看点

深度学习 :神经网络学习总结(上)sigmoid激活函数

  • 激活函数

    激活函数的存在,是神经网络与感知机不同的地方。

    神经网络的激活函数必须使用非线性函数!

    1. sigmoid函数

g(x)=1/(1+exp(−x))g(x)=1/(1+exp(-x) ) g(x)=1/(1+exp(−x))

![sigmoid函数表达式为:g(x)=1/(1+e^(-x) );](https://secure1.wostatic.cn/static/81mgxiAPGXreqKe11SLQfY/sigmoid.jpg)

Sigmoid函数其定义域在全体实数,值域在[0,1]之间,并且在0点位置为0.5。 当x的取值为[-∞,0]时,g(x)<=0; 当x的取值为[0,+∞]时,g(x)>=0; Sigmoid函数具有两个非常好的性质: (1):当x趋近于正无穷时,g(x)趋近于1,当x趋近于负无穷时,g(x)趋近于0.这一点非常适合做分类概率模型。 (2):除此之外,sigmoid函数还具有一个很到的导数性质,即sigmoid函数时任意阶可导的凸函数。

** 2. ReLu函数**

ReLu函数是最近才开始使用的函数,**ReLu函数在输入大于0时,直接输出该值;在输出小于等于0时,输出0。**
           
  1. softmax函数

softmax函数一般用于神经网络的输出层,softmax函数的性质是:softmax函数的输出是0.0~1.0之间的实数,并且softmax函数的输出值的总和是1**。**因此我们可以把softmax函数的输出解释为“概率”。

即便是使用softmax函数,输出值最大的神经元的位置也不会改变。

sigmoid激活函数

def sigmoid(x):

  return 1/(1+np.exp(-x))

#ReLu激活函数

def ReLu(x):

  if x < 0:

    return 0

  else:

    return x

#softmax激活函数(输出层)

def softmax(x):

  exp_x = np.exp(x)

  sum_exp_x = np.sum(exp_x)

  y = exp_x/sum_exp_x

  return y
           
  • 损失函数

    神经网络以某个指标为线索寻找最优权重参数。神经网络的学习中所用的指标成为损失函数(loss function)。这个损失函数可以使用任意的函数表示,但是一般来说都使用均方误差和交叉熵误差等。

    在寻找最优参数(权重和偏置)时,要寻找使得损失函数的值尽可能小的参数。为了寻找到使得损失函数的值尽可能小的地方,需要计算参数的导数(确切地将时梯度),然后以这个导数为指引,逐步更新参数的值。

#均方误差损失函数

def mean_squared_error(y,t):

  return 0.5*np.sum((y-t)**2)

#交叉熵损失函数

def cross_entropy_error(y,t):

  delta = 1e-7

  return -np.sum(np.array(t)*np.log(np.array(y)+delta))
           
  • 梯度

    变量的偏导数汇总而成的向量称为梯度(gradient)。

    机器学习的主要任务是在学习中寻找最优参数。同样地,神经网络也必须在学习时找到最优参数(权重和偏置)。这里所说的最优参数是指损失函数取最小值时的参数。

    通过梯度来寻找函数最小值(或者尽可能小的值)的方法就是梯度法。

    寻找最小值的梯度法为梯度下降法,寻找最大值的梯度法称为梯度上升法。(神经网络学习中,梯度法主要是指梯度下降法)。

    ![](https://secure1.wostatic.cn/static/5dJy2FASPV6sm1b79jPcPU/捕获 1.jpg)

其中η表示更新量,在神经网络的学习中,称为学习率(learning rate)。(学习率过大或者过小都无法得到好结果)

#求梯度

def numerical_gradient(f,x):

  h = 1e-4

  grad = np.zeros_like(x)

  for i in range(x.size):

    tmp = x[i]

    x[i] = tmp + h

    fxh1 = f(x)

    x[i] = tmp - h

    fxh2 = f(x)

    grad[i] = (fxh1 - fxh2) / (h*2)

    x[i] = tmp

  return grad

#梯度下降法

def gradient_descent(f, init_x, lr=0.01, step_num=100):

  x = init_x

  for i in range(step_num):

    grad = numerical_gradient(f, x)

    x -= lr * grad

  return x
           
  • 总结 学习算法的实现

    前提

    神经网络存在合适的权重和偏置,调整权重和偏置以便拟合训练数据的

    过程称为“学习”。神经网络的学习分成下面4个步骤。

    步骤1( mini-batch)

    从训练数据中随机选出一部分数据,这部分数据称为mini-batch。我们

    的目标是减小mini-batch的损失函数的值。

    步骤2(计算梯度)

    为了减小mini-batch的损失函数的值,需要求出各个权重参数的梯度。

    梯度表示损失函数的值减小最多的方向。

    步骤3(更新参数)

    将权重参数沿梯度方向进行微小更新。

    步骤4(重复)

    重复步骤1、步骤2、步骤3。

  • 两层神经网络编程实现(采用前向传播)
变量 说明
params 保存神经网络的参数的字典型变量(实例变量)。 params['W1']是第1层的权重, params['b1']是第1层的偏置。 params['W2']是第2层的权重, params['b2']是第2层的偏置
grads 保存梯度的字典型变量( numerical_gradient()方法的返回值)。grads['W1']是第1层权重的梯度, grads['b1']是第1层偏置的梯度。grads['W2']是第2层权重的梯度, grads['b2']是第2层偏置的梯度。
方法 说明
init(self, input_size,hidden_size, output_size) 进行初始化。 参数从头开始依次表示输入层的神经元数、隐藏层的神经元数、输出层的神经元数
predict(self, x) 进行识别(推理)。 参数x是图像数据。
loss(self, x, t) 计算损失函数的值。 参数 x是图像数据, t是正确解标签(后面3个方法的参数也一样)。
accuracy(self, x, t) 计算识别精度。
numerical_gradient(self, x, t) 计算权重参数的梯度。
gradient(self, x, t) 计算权重参数的梯度。
**权重的初始化使用符合高斯分布的随机数进行初始化,偏置使用0进行初始化**
           
  • mini-batch的实现

    mini-batch学习就是i从训练数据中,随机选择一部分数据(这部分数据称之为mini-batch),再以这部分数据为对象,使用梯度法更新参数。

#2层神经网络的分类
#输入层激活函数sigmoid
def sigmoid(x):
    return 1/(1+np.exp(-x))
#输出层激活函数softmax
def softmax(x):
    exp_x = np.exp(x)
    sum_exp_x = np.sum(exp_x)
    y = exp_x/sum_exp_x
    return y
#交叉熵损失函数
def cross_entropy_error(y,t):
    delta = 1e-7
    return -np.sum(np.array(t)*np.log(np.array(y)+delta))
#求梯度
def numerical_gradient(f,x):
  h = 1e-4
  grad = np.zeros_like(x)

  for i in range(x.size):
    tmp = x[i]
    x[i] = tmp + h
    fxh1 = f(x)

    x[i] = tmp - h
    fxh2 = f(x)

    grad[i] = (fxh1 - fxh2) / (h*2)
    x[i] = tmp
  return grad
class twolayernet:
    def __init__(self,input_size,hidden_size,output_size,weight_init_std=0.01):
        #初始化权重
        self.params = {}
        self.params['w1'] = weight_init_std * np.random.randn(input_size,hidden_size)
        self.params['b1'] = np.zeros(hidden_size)
        self.params['w2'] = weight_init_std * np.random.randn(hidden_size,output_size)
        self.params['b2'] = np.zeros(output_size)
    def predict(self,x):
        w1,w2 = self.params['w1'],self.params['w2']
        b1,b2 = self.params['b1'],self.params['b2']
        a1 = np.dot(x,w1)+b1
        z1 = sigmoid(a1)
        a2 = np.dot(z1,w2)+b2
        y = softmax(a2)
        return y
    def loss(self,x,t):
        y = self.predict(x)
        return cross_entropy_error(y,t)
    def accuracy(self,x,t):
        y = self.predict(x)
        y = np.argmax(y,axis=1)
        t = np.argmax(t,axis=1)
        accuracy = np.sum(y == t) / float(x.shape[0])
        return accuracy
    #x:输入数据 y:监督数据
    def numerical_gradient(self,x,t):
        loss_w = lambda w:self.loss(x,t)

        grads = {}
        grads['w1'] = numerical_gradient(loss_w,self.params['w1'])
        grads['b1'] = numerical_gradient(loss_w, self.params['b1'])
        grads['w2'] = numerical_gradient(loss_w, self.params['w2'])
        grads['b2'] = numerical_gradient(loss_w, self.params['b2'])
        return grads
           

继续阅读