我在训练一个简单的神经网络时遇到了麻烦

时间:2017-12-26 23:44:50

标签: python machine-learning neural-network backpropagation gradient-descent

我正在学习制作神经网络,我已经推导出以下反向传播方程式。这有什么不对,因为我似乎无法接受神经网络训练。我在python中编码,我得到的准确度大约是10(即使我不训练我的网络也能得到这个)。但是,每次迭代的错误都在减少。

另外,我目前正在按尺寸识别矩阵以执行点积,Hadamard积和换位,有点像打击和试用。有一个更好的方法吗?

根据我的理解,我们试图找到合适的权重,以便最大限度地降低成本。因此,为此,我们采用偏导数,它可以衡量一个组件的微小变化将对系统的总体成本产生多大影响。因此,我得出了这个,但我不明白为什么网络没有训练。请帮忙......

它是一个3层神经网络(输入层,1个隐藏层,输出层)。首先,我通过神经网络向前输入输入,然后计算成本,最后使用反向传播来更新权重。这里,x是输入数据,w是权重(第1层为w1,第2层为w2),z(a,w)是从左层到右层的数据传输,{ {1}}是激活函数(使用Sigmoid函数),g(z)是图层的输出,a(z)是成本函数(使用的平均误差)。

这是我的神经网络的前馈方程式:

Feed forward

这是权重E(a,y)w1(第1层的偏差),w1bw2(第2层的偏差)的反向传播梯度的推导。

derivation of gradients

我的python代码: (我使用w2b作为列表在序列p中的函数之间传递权重。此外,我稍后添加了正则化项,因此不包括在派生中。但它遵循相同的部分原则代码是用Jupyter Notebook编写的,每个函数都有自己的块。)

w1,w1b,w2,w2b

以下是我执行所有操作的主体。它已被分解为块以解释块的作用。代码块组合起来形成我的主体,其中所有上述函数都被调用。

alpha=0.12
lmda=1

def feedForward(p,x):
    a1=x
    z2=np.dot(a1,p[0])+p[1]
    a2=g(z2)
    z3=np.dot(a2,p[2])+p[3]
    a3=g(z3)    
    return [a1,a2,a3],[z2,z3]

from scipy.special import expit
def g(z):
    return expit(z)

def gPrime(z):
    s=g(z)
    return np.multiply(s,(1-s))


def cost(p,x,y):
    [a,z]=feedForward(p,x)
    h=a[-1]
    lmda_sum=(lmda*0.5/x.shape[0])*(sum(sum(np.square(p[0])))+sum(sum(np.square(p[2])))
    return sum(sum(np.square(y-h)))*0.5/x.shape[0]+lmda_sum

def backpropagate(p,x,y):    
    [a,z]=feedForward(p,x)
    h=a[-1]
    dz=[]
    m=x.shape[0] 
    dz4=np.divide((-(y-h)),m)
    dz3=np.multiply(dz4,gPrime(z[-1]))
    dw2=np.dot(a[-2].T,dz3) + np.multiply(lmda/m,p[2])
    dw2b=np.sum(dz3,0)

    dz2=np.multiply(np.dot(dz3,p[2].T),gPrime(z[-2]))
    dw1=np.dot(a[-3].T,dz2) + np.multiply(lmda/m,p[0])
    dw1b=np.sum(dz2,0)
    return [dw1,dw1b,dw2,dw2b]

def costPrime(p,x,y):
    grad=backpropagate(p,x,y)
    p[0] =p[0]-np.multiply(alpha,grad[0])
    p[1] =p[1]-np.multiply(alpha,grad[1])
    p[2] =p[2]-np.multiply(alpha,grad[2])
    p[3] =p[3]-np.multiply(alpha,grad[3])
    return p

def train(p,x,y,iteration):
    E=[]
    for i in range(iteration):
        E.append(cost(p,x,y))
        p=costPrime(p,x,y)
    return p,E

def predict(p,x,y):
    [pred,z]=feedForward(p,x)
    a=pred[-1].argmax(axis=1)
    a=np.reshape(a,(y.shape[0],1))
    b=np.argmax(y,axis=1) # gets index of max element for every row
    return a, np.mean(a==b)*100  
#     return pred, np.mean(np.sum(pred,0) == np.sum(y,0)) * 100

def randomInitialize(params):
    epsilion = 0.12
    m=len(params)
    for i in range(m):
        s=params[i].shape
        params[i]=np.multiply(np.random.rand(s[0],s[1]),2*epsilion)-epsilion
    return params

在这里,我从matlab导出的矩阵中导入输入和输出数据,并将它们存储在%matplotlib inline import matplotlib.pyplot as plot import random import numpy as np import scipy.io as io X中。

y

这里将向量data=io.loadmat('ex4data1.mat') X=data['X'] y=data['y'] (它是一个向量,例如mx1)转换为矩阵(mx10)。每行都将被转换,例如:如果y,则行中的第3个元素将为y=3,其余为1,即0。对于[0 0 1 0 0 0 0 0 0 0],它被映射到第10个索引,即y=0

[0 0 0 0 0 0 0 0 0 1]

所有加载的数据都用于训练网络

y_train=np.zeros((y.shape[0],10))
for i in range(1,11):
    c=np.zeros((1,10))
    if i==10:
        c[0][0]=1
    else:
        c[0][i]=1 
    y_train[np.where(y==i)[0]] = c
y=y_train

从集xtrain=X ytrain=y w1=np.zeros((400,26)) w1b=np.zeros((1,26)) w2=np.zeros((26,10)) w2b=np.zeros((1,10)) p=[w1,w1b,w2,w2b] p=randomInitialize(p) [p,E]=train(p,X,y,50) plot.plot(E) X中随机选择200行,然后使用to作为测试集。我知道不应该这样做,因为所有的数据都用于训练,但我只是想检查一下这个程序是否训练有素。如果它已经成功训练,它将比10更精确。

y

这是我在绘制randList=np.random.randint(X.shape[0],size=(1,200)) xtest=np.reshape(X[randList],(200,-1)) ytest=np.reshape(y[randList],(200,10)) [pred,acc]=predict(p,xtest,ytest) print acc 返回的E后得到的费用图。

enter image description here

0 个答案:

没有答案