前言

梯度下降法是一个最优化算法,通常也称为最速下降法。最速下降法是求解无约束优化问题最简单和最古老的方法之一,虽然现在已经不具有实用性,但是许多有效算法都是以它为基础进行改进和修正而得到的。最速下降法是用负梯度方向为搜索方向的,最速下降法越接近目标值,步长越小,前进越慢。

BP神经网络预测模型_Java



BP神经网络原理

经典的BP神经网络通常由三层组成: 输入层,隐含层与输出层.通常输入层神经元的个数与特征数相关,输出层的个数与类别数相同,隐含层的层数与神经元数均可以自定义.

BP神经网络预测模型_Java_02BP神经网络预测模型_Java_03

上述过程一般称为前馈(Feed-Forward)过程,该过程中神经网络的输入输出与多维函数无异每个隐含层和输出层神经元输出与输入的函数关系为:

BP神经网络预测模型_Java_02

现在我们的问题是如何训练这个神经网络.

作为监督学习算法,BP神经网络的训练过程即是根据前馈得到的预测值和参考值比较,根据误差调整连接权重WijWij的过程.训练过程称为反向传播过程(BackPropagation),数据流正好与前馈过程相反.每一个训练样本都会更新一次整个网络的参数.我们需要额外设置训练终止的条件.最简单的训练终止条件为设置最大迭代次数,如将数据集迭代1000次后终止训练.单纯的设置最大迭代次数不能保证训练结果的精确度,更好的办法是使用损失函数(loss function)作为终止训练的依据.损失函数可以选用输出层各节点的方差:L=∑j(Tj−Oj)2.

为了避免神经网络进行无意义的迭代,我们通常在训练数据集中抽出一部分用作校验.当预测误差高于阈值时提前终止训练.

一个python的例子:

首先实现几个工具函数:

importmath

importrandom

 

random.seed(0)

defrand(a, b):

    return (b - a) * random.random() + a

defmake_matrix(m, n, fill=0.0):

    mat =[]

    for i inrange(m):

        mat.append([fill]* n)

    return mat

 

defsigmoid(x):

    return1.0 / (1.0 + math.exp(-x))

 

defsigmoid_derivative(x):

    return x * (1 - x)

定义BPNeuralNetwork类,使用三个列表维护输入层,隐含层和输出层神经元,列表中的元素代表对应神经元当前的输出值.使用两个二维列表以邻接矩阵的形式维护输入层与隐含层,隐含层与输出层之间的连接权值,通过同样的形式保存矫正矩阵.

classBPNeuralNetwork:

    def__init__(self):

        self.input_n = 0

        self.hidden_n = 0

        self.output_n = 0

        self.input_cells = []

        self.hidden_cells = []

        self.output_cells = []

        self.input_weights = []

        self.output_weights = []

        self.input_correction = []

        self.output_correction = []

 

    defsetup(self, ni, nh, no):

        self.input_n = ni + 1

        self.hidden_n = nh

        self.output_n = no

        # init cells

        self.input_cells = [1.0] * self.input_n

        self.hidden_cells = [1.0] * self.hidden_n

        self.output_cells = [1.0] * self.output_n

        # init weights

        self.input_weights = make_matrix(self.input_n, self.hidden_n)

        self.output_weights = make_matrix(self.hidden_n, self.output_n)

        # random activate

        for i inrange(self.input_n):

            for h inrange(self.hidden_n):

                self.input_weights[i][h] = rand(-0.2, 0.2)

        for h inrange(self.hidden_n):

            for o inrange(self.output_n):

                self.output_weights[h][o] = rand(-2.0, 2.0)

        # init correction matrix

        self.input_correction = make_matrix(self.input_n, self.hidden_n)

        self.output_correction = make_matrix(self.hidden_n, self.output_n)

定义predict方法进行一次前馈,并返回输出:

    defpredict(self, inputs):

        # activate input layer

        for i inrange(self.input_n - 1):

            self.input_cells[i] = inputs[i]

        # activate hidden layer

        for j inrange(self.hidden_n):

            total = 0.0

            for i inrange(self.input_n):

                total += self.input_cells[i] * self.input_weights[i][j]

            self.hidden_cells[j] = sigmoid(total)

        # activate output layer

        for k inrange(self.output_n):

            total = 0.0

            for j inrange(self.hidden_n):

                total += self.hidden_cells[j] * self.output_weights[j][k]

            self.output_cells[k] = sigmoid(total)

        returnself.output_cells[:]

定义back_propagate方法定义一次反向传播和更新权值的过程,并返回最终预测误差:

    defback_propagate(self, case, label, learn, correct):

        # feed forward

        self.predict(case)

        # get output layer error

        output_deltas = [0.0] * self.output_n

        for o inrange(self.output_n):

            error = label[o] - self.output_cells[o]

            output_deltas[o] = sigmoid_derivative(self.output_cells[o]) * error

        # get hidden layer error

        hidden_deltas = [0.0] * self.hidden_n

        for h inrange(self.hidden_n):

            error = 0.0

            for o inrange(self.output_n):

                error += output_deltas[o] * self.output_weights[h][o]

            hidden_deltas[h] = sigmoid_derivative(self.hidden_cells[h]) * error

        # update output weights

        for h inrange(self.hidden_n):

            for o inrange(self.output_n):

                change = output_deltas[o] * self.hidden_cells[h]

                self.output_weights[h][o] += learn * change + correct * self.output_correction[h][o]

                self.output_correction[h][o]= change

        # update input weights

        for i inrange(self.input_n):

            for h inrange(self.hidden_n):

                change = hidden_deltas[h] * self.input_cells[i]

                self.input_weights[i][h] += learn * change + correct * self.input_correction[i][h]

                self.input_correction[i][h]= change

        # get global error

        error = 0.0

        for o inrange(len(label)):

            error += 0.5 * (label[o] - self.output_cells[o]) ** 2

        return error

定义train方法控制迭代,该方法可以修改最大迭代次数,学习率λλ,矫正率μμ三个参数.

    deftrain(self, cases, labels, limit=10000, learn=0.05, correct=0.1):

        for j inrange(limit):

            error = 0.0

            for i inrange(len(cases)):

                label = labels[i]

                case = cases[i]

                error += self.back_propagate(case, label, learn,correct)


往期「精彩内容」,点击回顾

DNA测序历史 | CircRNA数据库 | Epigenie表观综合 | 癌症定位

BWA介绍  |  源码安装R包 | CancerLocator  | lme4 | 450K分析

乳腺癌异质性 |  BS-Seq  | 隐马模型 Circos安装 |  Circos画图

KEGG标记基因 |  GDSC  |  Meta分析  |   R线性回归和相关矩阵

精彩会议及课程,点击回顾

计算表观遗传学大数据前沿学术论坛会议记实

哈尔滨医科大学2017年全国生物信息学暑期学校 

2017龙星课程系列(一)

2017龙星课程系列(二)
2017龙星课程系列(三)

2017龙星课程系列(四)

2017龙星课程系列(五)