BP神經網絡-前向傳播

前言

本文是接着上一文多層感知機所寫的。上一文說的瞭如何初始化一個MLP。本文簡單介紹一下前向傳播的概念以及代碼實現。
上文:http://blog.csdn.net/skullfang/article/details/78609851

回顧

還是從一個簡單的多層感知器入手,這個感知器只有兩層(輸入層不算)。輸入層——隱藏層——輸出層
模型:
這裏寫圖片描述

其中w是 權重。b 是偏置。(注意隱藏層和輸出層中w和b各不相同

前向傳播

每個神經元有兩部分組成一部分是根據權重w和偏置b計算出值z。通過激勵函數sigmoid刺激之後產生一個輸出y。而這個y就是下一層的輸入,然後下一層又產生一個輸出作爲下下一層的輸入,一直到最後一層。

由模型可以看出隱藏層的輸出yh就是輸出層的輸入。

這裏寫圖片描述

每一層的輸出 作爲 下一層的輸入。從而一層一層的傳播下去就叫做前向傳播

同樣有個概念叫反向傳播(更新)。就是我們輸出層產生輸出之後yo要與y的真實值進行比較學習之後。反向一層一層的更新w和b。詳細的緊接着一篇博文會說到。

回到前向傳播
概念很簡單
直接就看代碼部分了。

# -*- coding: utf-8 -*-
# @Time    : 2017/11/23 上午10:21
# @Author  : SkullFang
# @Email   : [email protected]
# @File    : TwoDemo.py
# @Software: PyCharm
import numpy as np
class Network(object):
    def __init__(self,sizes):
        """
        sizes表示 網絡的結構
        :param sizes: 
        """
        #網絡層數
        self.num_layers=len(sizes) #層數
        #神經元的個數
        self.sizes=sizes
        #初始化每一層的偏置 z=wx+b 就是b的值
        self.baises=[np.random.randn(y,1) for y in sizes[1:]]
        #等同與
        """
        baises=[]
        #意思就是生成一個符合正態分佈的 y*1的數組
        for y in sizes[1:]:
            biases.append(np.random.randn(y, 1))
        結果
        [array([[ 1.05154644],
       [-0.02986238]]), array([[-0.88098138]])]

        """

        #初始化權重W
        self.weights=[np.random.randn(y,x) for x,y in zip(sizes[:-1],sizes[1:])]
        """
        產生一個y*x 符合正態的
        weights=[]
        for x,y in zip(sizes[:-1],sizes[1:]):
            weights.appenf(np.random.randn(y,x))
        pass
        >>> weights
        [array([[-0.22826557, -0.54427902,  0.19502928],
       [ 0.21433594,  0.72849057,  0.12851307]]), array([[ 0.27181857, -0.55032853]])]

        """
    #梯度下降
    def GD(self,training_data,epochs):
        """
        這個是梯度下降
        :param training_data: 訓練數據
        :param epochs:  訓練次數 
        :return: 
        """
        for j in xrange(epochs):
            #洗牌 就是打亂訓練數據
            random.shuffle(training_data)

            #訓練每一個數據
            for x,y in training_data:
                self.update(x,y)

            print "Epoch {0} complete".format(j)
    #前向傳播
    def update(self,x,y):
        """
        :param x: 
        :param y: 
        :return: 
        """
        # 保存每一層的偏導
        nabla_b = [np.zeros(b.shape) for b in self.baises]
        nabla_w = [np.zeros(b.shape) for b in self.weights]

        #保存輸入數據
        #第一層的activation
        activation=x

        #保存每一層的激勵值a=sigmoid(z)
        activations=[x]

        #zs保存每一層的z=wx+b
        zs=[]

        #要做前向傳播
        for b,w in zip(self.baises,self.weights):
            #計算每一層的z,
            # 這裏的activation就是上一層的輸出。
            # 從而達到傳播的效果
            z=np.dot(w,activation)+b

            #保存每一層的z
            zs.append(z)

            #計算每一層的a(其實就是y)
            activation=sigmoid(z)

            #保存每一層的a
            #做個記錄反向傳播有用
            activations.append(activation)




#sigmoid
def sigmoid(z):
    """
    激活函數
    :param z: 
    :return:
    sigmoid(z)=1/(1+e^-z)
    """
    return 1.0/(1.0+np.exp(-z))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章