机器学习——BP神经网络算法应用(上)

来源:互联网 发布:变老相机软件 编辑:程序博客网 时间:2024/05/23 16:55

1、关于非线性转化方程(non-linear transformation function)

sigmoid函数(S曲线)用来作为activation function

(1)双曲函数(tanh function)

   

双曲函数的导数:

(2)逻辑函数(logistic function)

逻辑函数的导数:

2、利用Python实现简单的神经网络算法

#!/usr/bin/env python# -*- coding:utf-8 -*-# Author:ZhengzhengLiuimport numpy as np#定义双曲函数def tanh(x):    return np.tanh(x)#定义双曲函数的导数def tanh_deriv(x):    return 1.0 - np.tanh(x)*np.tanh(x)#定义逻辑函数def logistic(x):    return 1 / (1 + np.exp(-x))#定义逻辑函数的导数def logistic_deriv(x):    return logistic(x) * (1 - logistic(x))class  NeuralNetwork:    # 构造函数,self参数:指向当前类的指针,相当于c++里面的this指针    def __init__(self,layers,activation='tanh'):        '''        :param layers: A list containing the number of units in each layer        (用一个列表包含每层的神经单元个数)should be at least two values        :param activation:The activation function to be used,can be 'logistic' or 'tanh'        非线性转化函数,在不指明时,默认情况下采用tanh        '''        if activation == 'logistic':            self.activation = logistic    #将当前的非线性转化函数赋值给前面定义的logistic函数            self.activation_deriv = logistic_deriv        elif activation == 'tanh':            self.activation = tanh            self.activation_deriv = tanh_deriv        self.weights = []        #定义一个列表存放权重weight        #循环从1开始,相当于以第二层为基准,进行权重weight的初始化        for i in range(1,len(layers)-1):            #对当前神经结点的前续赋值            self.weights.append((2*np.random.random((layers[i-1]+1,layers[i]+1))-1)*0.25)            #对当前神经结点的后续赋值            self.weights.append((2 * np.random.random((layers[i] + 1, layers[i+1])) - 1) * 0.25)    #训练函数,X:训练集(二维矩阵),每行对应一个实例,每列对应实例特征值维度    #y:函数对实例进行分类的标记(class label),learning_rate为学习率,epochs:抽样的方法对神经网络进行更新的最大次数    def fit(self,X,y,learning_rate = 0.2,epochs = 10000):        X = np.atleast_2d(X)    #确定X至少是二维数据        temp = np.ones([X.shape[0],X.shape[1]+1])    #初始化元素全为1的矩阵,行数与X相同,列数比X多1        temp[:,0:-1] = X    #取X所有行,第1列至倒数第2列,进行偏向的赋值        X = temp        y = np.array(y)     #将分类标记由list转换成numpy数组        for k in range(epochs):          #抽样梯度下降epochs抽样            #随机抽取一行,对神经网络进行更新            # randint生成指定范围的整数,从X的行数(实例)中随机取一个整数:即随机取一行,随机取一个实例            i = np.random.randint(X.shape[0])            a = [X[i]]           #随机从X中取一个实例            #完成所有的正向更新            for l in range(len(self.weights)):                # dot:內积,对应实例的值与权重乘积再求和,最后进行非线性转化                a.append(self.activation(np.dot(a[l],self.weights[l])))            error = y[i] - a[-1]     #对于顶层,y[i]:真实的分类标记值,a[-1]:最后一层预测的分类标记值            deltas = [error*self.activation_deriv(a[-1])]       #输出层误差            #开始反向计算误差,更新权重            for l in range(len(a)-2,0,-1):   #从最后一层到第2层倒着循环                deltas.append(deltas[-1].dot(self.weights[l].T)*self.activation_deriv(a[l]))                deltas.reverse()                for i in range(len(self.weights)):                    layer = np.atleast_2d(a[i])                    delta = np.atleast_2d(deltas[i])    #权重更新                    self.weights[i] += learning_rate*layer.T.dot(delta)    #预测函数    def predict(self,x):        x = np.array(x)        temp = np.ones(x.shape[0]+1)        temp[0:-1] = x        a = temp        for l in  range(0,len(self.weights)):            a = self.activation(np.dot(a,self.weights[l]))        return a

原创粉丝点击