バックプロパゲーションニューラルネットワークの学習と分析

序文

     昨年、2年生、私は突然、ニューラルネットワークの学習と深い学習を試してみたいです。結局のところ、ブロガーがしたいコンピュータビジョン後、彼は私のメンターを見ている方法を学習に関連するビットをかぐ、その教師は、プロジェクトを予測することは私に裁判官牧場の動物の行動を与えました。正直に言うと、最初は私の心はまだかなり的外れ、すべての後、私はその結果ではないだろう、ああTOTです。しかし、人々はそれを強化するために、0-1からの質的な変化ではありませんか?だから、私は本の束を買いました。ここで私はより多くを推奨しています

  1. 「中国水パワープレス」劉氏Yuの「Pythonプログラミング」
  2. 「中国水パワープレス」江氏紫陽の「TensorFlowが深い学習アルゴリズムと戦闘の原則をプログラミングします。」
  3. 「人々のポストを押して」ミスターカン李斎藤「ディープラーニングポータル」
  4. 「人々のポストを押して」ミスタータリク・ラシッド「Pythonのニューラルネットワークプログラミング。」
  5. 「人々のポストを押して」IANグッドフェロー、ヨシュア・ベンジオ、3共同書いた「DEEP LEARNING」とAARON COURVILLE

     ビデオコースについて、私はB駅のMoトラブルのPython、氏アンドリュー・ウビデオ、および3Blue1Brownなどにお勧めします。

一つの様々なライブラリの取り付け

     実際に、私は言ったブログの多くは、Pythonのブログやライブラリは、独自のBaiduの学生をインストールするか、私に読まれていない場合の前を持っています。

import numpy as np#numpy做矩阵运算十分方便
import math#math函数用来设置一些激活函数
import random#需要随机数来做初始权重
import string
import matplotlib as mpl#如果你需要作图就用上
import matplotlib.pyplot as plt
import sys#需要保存最后的合理权重
import xlrd#因为我的数据集是从excel里面读出来的
from sklearn import preprocessing#需要对数据集做高斯分布或归一化的可以用这个

読み取りデータ

     私はここにある牧場へのExcelについては内部からのデータセットを使用することで、それがある場合は、他のソースからの友人やMNISTデータセットは、このステップをスキップすることができます。ほぼ3次元データ、Iアレイにデータの500セット挙動の二種類から取り、そしてそれらを与えるたびに0または1を標識した[[[954]、[4652]、[--456] [1] ]これは、取り付けられたラベルに続く、三次元のリストの前に、ほとんどです。

def read_excel():
    # 打开Excel
    workbook = xlrd.open_workbook('all.xls')
    # 进入sheet
    eating = workbook.sheet_by_index(0)
    sleeping=workbook.sheet_by_index(1)
    # 获取行数和列叔
    Srows_num=sleeping.nrows
    Scols_num=sleeping.ncols
    ListSleep=[]
    
    Erows_num = eating.nrows
    Ecols_num = eating.ncols
    ListEat=[]
    ListEatT=[]
    ListSleepT=[]
    ListT=[]
    i = 1
    while i <= 500:
        if Erows_num > 10 or Srows_num>10:
            # 生成随机数
            random_numE = random.randint(1, Erows_num - 1)
            E_X = eating.row(random_numE)[1].value
            E_Y = eating.row(random_numE)[3].value
            E_Z = eating.row(random_numE)[5].value
            ListEat.append([[int(E_X),int(E_Y),int(E_Z)],[1]])
            random_numS = random.randint(1, Srows_num - 1)
            S_X = sleeping.row(random_numS)[1].value
            S_Y = sleeping.row(random_numS)[3].value
            S_Z = sleeping.row(random_numS)[5].value
            ListSleep.append([[int(S_X),int(S_Y),int(S_Z)],[0]])
            i = i + 1
        else:
            print("数据不足,请添加")
            break
    List=ListEat+ListSleep
    
    print(List)
read_excel()

II。活性化関数

      ここで最も重要なステップであり、このネットワークの機能を有効にするには、あなたの決断の良質を適用します。

      1 シグモイド関数

       シグモイド関数曲線次のように:

         入力値が小さい場合、現実的なシグモイド活性化関数は、出力が0に近いある入力値が大きい場合、出力値は1に近いです。しかし、シグモイド活性化関数は、大きな欠点は、主に二つのことですがあります。

(1)傾向勾配が消え。入力値が小さい又は大きい場合、勾配は0になる傾向があり、ゼロに向かって左右両端導関数曲線に対応する機能。

(2)非ゼロの中心は、勾配降下のダイナミックスに影響を与えます。

def sigmoid(x):
    '''
    定义sigmoid函数
    '''
    return 1.0/(1.0+np.exp(-x))
def derived_sigmoid(x):
    '''
    定义sigmoid导函数
    '''
    return sigmoid(x)*(1-sigmoid(x))

     2、TANH機能

     TANH関数曲線次のように:

     シグモイドと比べて、出力は[-1、1]の範囲の中心に0となります。しかし、勾配の消失はまだ存在しています。

def tanh(x):
    '''
    定义tanh函数
    '''
    return (np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x))
def derived_tanh(x):
    '''
    定义tanh导函数
    '''
    return 1-tanh(x)*tanh(x)

     3、Relu機能

     補正部は、線形Reluニューラルネットワークは、最も使用される活性化関数であり、多くの利点を有しています。

     関数曲線は次の通り:

利点:(1)勾配が速く収束消えることはありません。

          計算量の前(2)が小さい場合、必要にのみMAX(0、X)をカウントし、シグモイド指標の計算は存在しません。

          (3)バックプロパゲーション計算を迅速、簡単誘導体計算は、インデックスが開始算出されていません。

          (4)いくつかのニューロンは、オーバーフィッティングを低減することができ、ネットワークはsaprse特性を有するように、0です。

短所:(1)研修で「死」、バックプロパゲーション引数が0である場合に比較的脆弱では、後者のパラメータが更新されません。ケースを弱体化する適切な学習率を使用してください。

def relu(x):
    '''relu函数'''
    return np.where(x<0,0,x)
 
def derivedrelu(x):
    '''relu的导函数'''
    return np.where(x<0,0,1)

     図4に示すように、リークRelu機能

     入力値が0未満で、αは小さい定数であり、αはxの出力値である場合、リークRelu Reluは、欠点を改良したものです。このような状況下、「ダイ」の広がりを逆にする傾向がないです。

def leakyrelu(x,a=0.01):
    '''
    定义leakyrelu函数
    leakyrelu激活函数是relu的衍变版本,主要就是为了解决relu输出为0的问题
    '''
    return np.where(x<0,a*x,x)
 
def derived_leakyrelu(x,a=0.01):
    '''
    定义leakyrelu导函数
    '''
    return np.where(x<0,a,1)
 
 

     4、ELU機能

 # 定义elu函数elu和relu的区别在负区间,relu输出为0,而elu输出会逐渐接近-α,更具鲁棒性。
def elu(x,a=0.01):
 #elu激活函数另一优点是它将输出值的均值控制为0(这一点确实和BN很像,BN将分布控制到均值为0,标准差为1)
    return np.where(x<0,a*(np.exp(x)-1),x)
 
def derived_elu(x,a=0.01):
    '''
    定义elu导函数
    '''
    return np.where(x<0,a*np.exp(x),1)

 また、多くの派生活性化機能があり、自分が出土してください。

三つ。正規化されたデータ処理

  データ入力と出力の前処理:スケーリング。また、スケールは正規化または標準化を変化させると称する、変換処理は、入力および出力データ・ネットワークを指すが、[0,1]または[1,1]間隔等に限定されます。三つの理由の変換があります。

 1)。それぞれの入力データ・ネットワークは、多くの場合、別の意味と異なる物理的な寸法を有します。全ての成分をスケーリングすることは、ネットワークのトレーニングは、入力コンポーネントに等しい重要性のそれぞれを置くことによって開始されるように、範囲内で変化しています。

 2) BPニューラルネットワークのニューロン上のシグモイド関数を使用する場合、変換は、重み調整は、次に平面エラー表面領域に入るように、飽和ニューロン出力の正味入力が大きすぎる絶対値に起因することを防止できます。

 3)。区間[0,1] TANH関数内[1,1]におけるシグモイド関数の出力または、所望しない場合、出力データ変換処理は、誤差の絶対値を作るために結合されている大成分、小さな絶対誤差値の成分小さな、短い、最良のデータを正規化します。

2、(0,1)標準:

  これは、塩基(すなわち、最小= 0、最大= 1)正規化データとして最大最小によって、レコードの最大値と最小各データトラバーサル特徴ベクトルを通る単純で最も簡単な考えられる方法であります治療:

                     

Python実装:

def MaxMin(x,Max,Min):
    x = (x - Min) / (Max - Min);
    return x

2、Zスコアは、正規化されました。

標準化されたデータの生データの平均値(平均値)と標準偏差(標準偏差)を投与するこの方法。データ標準正規分布、0および標準偏差1の平均処理、ここで複合キーは、標準正規分布です。

 

                     

Python実装:

def Z_Score(x,mu,sigma):
    x = (x - mu) / sigma;
    return x

3、平均正規化

正規化方法における分母最大最大最小と分母のような2つの方法、正規化方法に

 

def average():
    # 均值
    average = float(sum(data))/len(data)
 
    # 均值归一化方法
    data2_1 = [(x - average )/max(data) for x in data]
    data2_2 = [(x - average )/(max(data) - min(data)) for x in data]

ストア。Error関数/損失関数

     平均二乗誤差平均二乗誤差

YKがNNの出力である
TKはラベルであり、ラベルは唯一の正解であり、他は0 Kであり、データの次元である
NNの各要素は、タグの正しいデータを出力するための二乗差の平均二乗誤差が算出されるように、その後、合計を求めます。

def get_standard_deviation(records):
    """
    标准差 == 均方差 反映一个数据集的离散程度
    """
    variance = get_variance(records)
    return math.sqrt(variance)

     第二に、平均的な平均

def get_average(records):
    """
    平均值
    """
    return sum(records) / len(records)

    第三に、クロスエントロピー誤差クロスエントロピーエラー

クロスエントロピー誤差個々のトレーニングデータ出力にラベルの自然対数の唯一の正解を求めます。

YKは、ラベルが一つだけ正解であるNNのTKラベルの出力であり、他方は0であり、kは次元であります

正解NN出力yの確率が1である場合したがって、クロスエントロピー損失は0であり、負の値に減少Y正解確率が0に減少すると、クロスエントロピー損失が減少され(、損失の値は、実際に増加)

def cross_entropy(a, y):
    return np.sum(np.nan_to_num(-y*np.log(a)-(1-y)*np.log(1-a)))
 
# tensorflow version
loss = tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y), reduction_indices=[1]))
 
# numpy version
loss = np.mean(-np.sum(y_*np.log(y), axis=1))

 

キブ。ニューラルネットワークを構築するには

   上記のこの図は、0または1の裁判官の近くに、最後にソフトマックスマルチ分類勧告の行動によって判断する私の最後の点出力のみ1出力、単なる一例です。初期の重みは、ここで私はそれが2の倍数を設定することが最善である、とGPUアクセラレーション学生に、特に何かを言う必要があります。
 

# 构造三层BP网络架构
class BPNN:
    def __init__(self, num_in, num_hidden, num_out):
        # 输入层,隐藏层,输出层的节点数
        self.num_in = num_in + 1  # 增加一个偏置结点
        self.num_hidden = num_hidden + 1  # 增加一个偏置结点
        self.num_out = num_out
        # 激活神经网络的所有节点(向量)
        self.active_in = [1.0] * self.num_in
        self.active_hidden = [1.0] * self.num_hidden
        self.active_out = [1.0] * self.num_out
        # 创建权重矩阵
        self.wight_in = makematrix(self.num_in, self.num_hidden)
        self.wight_out = makematrix(self.num_hidden, self.num_out)
        # 对权值矩阵赋初值

        for i in range(self.num_in):
            for j in range(self.num_hidden):
                self.wight_in[i][j] = random_number(-2.4, 2.4)
        for i in range(self.num_hidden):
            for j in range(self.num_out):
                self.wight_out[i][j] = random_number(-0.2, 0.2)
        # 最后建立动量因子(矩阵)
        self.ci = makematrix(self.num_in, self.num_hidden)
        self.co = makematrix(self.num_hidden, self.num_out)

     このデータとの間のあまり差があるように、私は、ここでは最大値と最小悪く、このギャップと10003を持つデータがなければならないので、順方向伝搬は、ここでIは、データの正規化された初期セットとしてシグモイドを使用しました正規化。隠された層としてTANH活性化関数、隠された層のデータは[-1,1]の間で統一されています。最後に、このデータはシグモイド出力0に近いまたは1に近いことによって決定されます。

   def update(self, inputs):
        print(len(inputs))
        if len(inputs) != self.num_in - 1:
            raise ValueError('输入层节点数有误')
            # 数据输入输入层
        for i in range(self.num_in - 1):
            self.active_in[i] = sigmoid(inputs[i])  #在输入层进行数据处理归一化

            self.active_in[i] = inputs[i]  # active_in[]是输入数据的矩阵
            # 数据在隐藏层的处理
        for i in range(self.num_hidden - 1):
            sum = 0.0
            for j in range(self.num_in):
                sum = sum + self.active_in[i] * self.wight_in[j][i]

            self.active_hidden[i] = tanh(sum)  # active_hidden[]是处理完输入数据之后存储,作为输出层的输入数据

            # 数据在输出层的处理
        for i in range(self.num_out):
            sum = 0.0
            print(self.wight_out)
            for j in range(self.num_hidden):

                sum = sum + self.active_hidden[j] * self.wight_out[j][i]
            self.active_out[i] = sigmoid(sum)  # 与上同理
        return self.active_out[:]
 

     逆伝搬

# 误差反向传播
    def errorback(self, targets, lr, m):  # lr是学习率, m是动量因子
        if len(targets) != self.num_out:
            raise ValueError('与输出层节点数不符!')
            # 首先计算输出层的误差
        out_deltas = [0.0] * self.num_out
        for i in range(self.num_out):
            error = targets[i] - self.active_out[i]
            out_deltas[i] = derived_sigmoid(self.active_out[i]) * error

            # 然后计算隐藏层误差
        hidden_deltas = [0.0] * self.num_hidden
        for i in range(self.num_hidden):
            error = 0.0
            for j in range(self.num_out):
                error = error + out_deltas[j] * self.wight_out[i][j]
            hidden_deltas[i] = derived_tanh(self.active_hidden[i]) * error

            # 首先更新输出层权值
        for i in range(self.num_hidden):
            for j in range(self.num_out):
                change = out_deltas[j] * self.active_hidden[i]
                self.wight_out[i][j] = self.wight_out[i][j] + lr * change + m * self.co[i][j]
                self.co[i][j] = change
            # 然后更新输入层权值
        for i in range(self.num_in):
            for j in range(self.num_hidden):
                change = hidden_deltas[j] * self.active_in[i]
                self.wight_in[i][j] = self.wight_in[i][j] + lr * change + m * self.ci[i][j]
                self.ci[i][j] = change
            # 计算总误差
        error = 0.0
        for i in range(len(targets)):
            error = error + 0.5 * (targets[i] - self.active_out[i]) ** 2

        return error

勾配の減少で、学習率も最高に低減されるため、3次元、Jのリストを入力するJ [0] [1]は、単にトレーニングを学ぶ人のように、各リストのラベルのための学習率、LRであります初めは多くを学ぶために、そして最終的には罰金を学ぶことです。

 

改善されたBPアルゴリズムはMOMENTUMMETHOD Mが使用されてもよい
モーメンタム方法は重み更新相標準BPアルゴリズム運動量因子α(0 <α<1)で導入された 、 一定の慣性と補正量の値、すなわち誤差がどのことができない、実質的に変更すること総誤差エネルギーと総エラー状態よりも小さいが大きなに信号値戻りの調整は、トレーニングセットをもたらすことができます。この時間は、フィードバックエラー信号が再び振動アップニューロンの重みの値を生じさせるに寄与する運動量因子を添加しました。元の重量調整式、運動量係数、及び時間の変化量に対する添加量です。それだけでなく、方向と大きさに関連する最後の更新と、これだけで得られる勾配を算出し、運動量更新を添加することを、この重み値の方向と大きさを示しています。勢いは、tは減衰効果を果たした時のために調整以前に蓄積された経験の調整を反映しています。エラー表面急激な変動が発生した場合、衝撃はトレーニング速度を改善する傾向を低減させることができます。

 

  def train(self, pattern, itera=200000, lr=0.1, a=0.5):
        for i in range(itera):
            error = 0.0
            for j in pattern:
                input = j[0]
                targ = j[1]
                self.update(input)
                error = error + self.errorback(targ, lr, m)
            if i % 200 == 0:
                lr*=0.99
                print('误差 %-.5f' % error)
 txtのドキュメントに保存された最終重量を記録します
    def weights(self):
        f = open("getwights.txt", "w")
        weightin = []
        weightout = []
        print("输入层权重")
        for i in range(self.num_in):
            print(self.wight_in[i])
            weightin.append(self.wight_in[i])

        print("输入矩阵", weightin)
        print("输出层权重")
        for i in range(self.num_hidden):
            print(self.wight_out[i])
            weightout.append(self.wight_out[i])

        print("输出矩阵", weightout)
        f.write(str(weightin))
        f.write("\n")
        f.write(str(weightout))
        f.close()

そして、ニューラルネットワークを作成するには、3X3X1タイプでない場合、また、独自のを修正し、クラスで使用することができるノードの数が同じで、それを変更することができます

def BP():
# 创建神经网络,3个输入节点,3  个隐藏层节点,1个输出层节点
    n = BPNN(3, 3, 1)
    # 训练神经网络
    n.train(List)
    # 保存权重值
    n.weights()
if __name__ == '__main__':
    BP()

今、私たちが使用する最後のコースの後に重いトレーニングを保持する権利を有すること。そして、実際には前と同じではありません、初期重量は、もはや乱数私たちの以前に保存され、その後、前方にのみ伝播されています。
 

class BPNN:
    def __init__(self, num_in, num_hidden, num_out):
        # 输入层,隐藏层,输出层的节点数
        self.num_in = num_in + 1  # 增加一个偏置结点
        self.num_hidden = num_hidden + 1  # 增加一个偏置结点
        self.num_out = num_out
        # 激活神经网络的所有节点(向量)
        self.active_in = [1.0] * self.num_in
        self.active_hidden = [1.0] * self.num_hidden
        self.active_out = [1.0] * self.num_out
        # 创建权重矩阵
        self.wight_in = makematrix(self.num_in, self.num_hidden)
        self.wight_out = makematrix(self.num_hidden, self.num_out)
        # 对权值矩阵赋初值
        f = open("getwights.txt", "r")
        a = f.readline()
        b = f.readline()
        listone = eval(a)
        listtwo = eval(b)
        f.close()
        for i in range(len(listone)):
            for j in range(len(listone[i])):
                self.wight_in[i][j] = listone[i][j]
        for i in range(len(listtwo)):
            for j in range(len(listtwo[i])):
                self.wight_out[i][j] = listtwo[i][j]

        self.co = makematrix(self.num_hidden, self.num_out)
        # 信号正向传播

    def update(self, inputs):
        if len(inputs) != self.num_in - 1:
            raise ValueError('与输入层节点数不符')
        # 数据输入输入层
        for i in range(self.num_in - 1):
            # self.active_in[i] = sigmoid(inputs[i])  #或者先在输入层进行数据处理
            self.active_in[i] = inputs[i]  # active_in[]是输入数据的矩阵
        # 数据在隐藏层的处理
        for i in range(self.num_hidden - 1):
            sum = 0.0
            for j in range(self.num_in):
                sum = sum + self.active_in[i] * self.wight_in[j][i]
            self.active_hidden[i] = tanh(sum)  # active_hidden[]是处理完输入数据之后存储,作为输出层的输入数据
        # 数据在输出层的处理
        for i in range(self.num_out):
            sum = 0.0
            for j in range(self.num_hidden):
                sum = sum + self.active_hidden[j] * self.wight_out[j][i]
            self.active_out[i] = sigmoid(sum)  # 与上同理
        return self.active_out[:]
    # 测试
    def test(self, patterns):
        distingish=[]
        List_update=[]
        num=0
        sum=0
        for i in patterns:
            List_update.append(self.update(i[0]))
        sum=np.sum(List_update,axis=0)
        average=sum/(len(patterns))
        #print(average)
        for i in patterns:
            num += 1
            if (num <= testnums and self.update(i[0]) > average):
                distingish.append(True)
            if (num > testnums and self.update(i[0]) < average):
                distingish.append(True)
            print(i[0], '->', self.update(i[0]))
        print("正确率", len(distingish) / num)


# 实例
def BP():

    # 创建神经网络,3个输入节点,3个隐藏层节点,1个输出层节点
    n = BPNN(3, 3, 1)
    # 测试神经网络
    n.test(ListT)
if __name__ == '__main__':
    BP()

 オーダー後

私は、データの可視化についてです、興味を持っている友人が行くと見ることができるPyechartsについての記事を書きました

https://blog.csdn.net/weixin_43341045/article/details/104137445

データああのソースについては、それは非常に多くのことができ、私は爬虫類を導入するためにここにいます。セレンに爬虫類を書いて、多くのライブラリがある爬虫類https://blog.csdn.net/weixin_43341045/article/details/104014416

9列Bピクチャ(BeautifulSoup4)をクロール停止線があります

https://blog.csdn.net/weixin_43341045/article/details/104411456

     それは意見がこの国に集まり、だけでなく、あなたが上級専門家を指しているの多くを許し願って専門家を書くことだけ平凡な二年生の奨学金の浅い出ていました。私たちは、私たちの研究グループ交換コードに参加する国を招待:871 352 155(あなたかどうかをC / C ++やJava、PythonやPHPを......私たちは、あなたが参加する歓迎されている興味を持っているが、また、ご記入くださいプラスグループ内のグループ情報は、議長は、アップpereiopodないでくださいアドバタイズ、現在は主に大学生です。私たちは地域社会に入ろうとして早期の子牛の方向を案内するための勧告を行うことができます先見の明高齢者があると思っています。)

 

 

 

 

公開された13元の記事 ウォン称賛39 ビュー10000 +

おすすめ

転載: blog.csdn.net/weixin_43341045/article/details/105243732