フレームワークなしで基本人工ニューラルネットワークによるMNISTデータセットの識別を実現

3693 ワード

先辈からもらった宿题ですが、検索してみると无枠组みで人工神経ネットワークを実现している资料はあまりないようで、MNISTの识别にもTensorflowが多く使われています.作られたのは比較的悪いモデルで,正規化は行われず,1000回の訓練後に88%程度の正解率があった.全部で3層のネットワークで、第1層はデータセットの入力で、ここではボリュームではなく、28 x 28の階調ピクチャを784次元のベクトル入力モデルに展開し、第1層から第2層まではtanhアクティブ関数、第2層から第3層まではsoftmaxを使用します.しかし、第1層から第2層へのtanhは、いくつかの勾配が消失する問題がある可能性がある.(すでにデータを正規化処理していますが、この現象はまだ存在します)ということで、ソフトmax関数に置き換えたいと思っていたのですが、どうしても資料が乏しく、数学力が限られているので自分で導くことができないので、今はしばらくtanh+ソフトmaxという組み合わせです.勾配降下については、もともと呉恩達先生が機械学習教程で教えていた累積勾配降下、つまりデータセットを1回巡回した後、勾配降下を行います.しかし、効果が悪いため、周志華先生の「機械学習」のニューラルネットワークに関する章を調べたところ、累積勾配の低下はデータ量が大きい場合、標準勾配の低下よりも効果が悪い可能性があることが分かったので、ここでは標準勾配の低下を採用した.正規化については,コード内で実現した後にlambdaの値が変化したことを発見してから低下する効果はあまりよくなく,またlambdaは大きな本を取る際に警告や誤りを投げ出すため,コード内でlambdaを0にする.これは効果の悪いモデルで、人工神経ネットワークを実現するためにフレームワークが必要な学生を助けることを望んでいるだけだ.正規化方法や私のコードの誤りや改善できるところを知っている方はqwqを教えてください
コードは次のとおりです.
import numpy as np
import os
import struct
import random
def softmax(X):
    X=X-np.max(X)
    expX=np.exp(X)
    softmaxX=expX/np.sum(expX)
    return softmaxX


def Normalization(X):
    X=X-np.average(X)
    X=X/X.max()
    return X
def LoadData(path,kind):
    labelPath=os.path.join(path,'%s-labels.idx1-ubyte'%kind)
    imagePath=os.path.join(path,'%s-images.idx3-ubyte'%kind)
    with open(labelPath,'rb') as lb:
        magic,n=struct.unpack('>II',lb.read(8))
        labels=np.fromfile(lb,dtype=np.uint8)
    with open(imagePath,'rb') as ib:
        magic, num, rows, cols = struct.unpack('>IIII',ib.read(16))
        images = np.fromfile(ib,dtype=np.uint8).reshape(len(labels), 784)
    labelsResult=[]
    for i in range(labels.shape[0]):
        y = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        y[labels[i]]=1
        labelsResult.append(y)
    labelsResult=np.array(labelsResult)
    images=Normalization(images)
    return images,labelsResult

def RandomInitial(x,y):
    w=np.random.rand(x,y)
    b=random.random()
    b=b*np.ones((1,y))
    return w,b

def Learning(X_train,y_train,learningRate,learningTimes,mylambda):
    w1,b1=RandomInitial(784,50)
    w2,b2=RandomInitial(50,10)
    num=y_train.shape[0]
    for times in range(learningTimes):
        DW1 = np.zeros((784, 50))
        DW2 = np.zeros((50, 10))
        DB1 = np.zeros((1, 50))
        DB2 = np.zeros((1, 10))
        cost = 0
        for i in range(num):
            X=X_train[i].reshape(1,784)
            y=y_train[i]

            #FB
            z2=np.dot(X,w1)+b1
            a2=np.tanh(z2)

            z3=np.dot(a2,w2)+b2
            h=softmax(z3)

            #BP
            delta3=h-y
            DW2=np.dot(a2.T,delta3)/num+mylambda*w2
            DB2=delta3.sum()/num
            delta2=np.multiply(np.dot(delta3,w2.T),np.power(a2,2))
            DW1=np.dot(X.T,delta2)/num+mylambda*w1
            DB1=delta2.sum()/num
            #      
            w2=w2-learningRate*DW2
            w1=w1-learningRate*DW1
            b1=b1-learningRate*DB1
            b2=b2-learningRate*DB2
            #Cost
            J=np.multiply(-y,np.log(h)).sum()/num
            cost=cost+J
        print('Cost:',times+1,cost)
        #      
        #w2=w2-learningRate*DW2
        #w1=w1-learningRate*DW1
        #b1=b1-learningRate*DB1
        #b2=b2-learningRate*DB2
    return w1,w2,b1,b2
def HProcess(X):
    max=X[0][0]
    index=0
    for i in range(X.shape[1]):
        if max