Dropout首选是在《ImageNet Classification with Deep Convolutional》这篇论文里提出来为了防止神经网络的过拟合。它的主要思想是让隐藏层的节点在每次迭代时(包括正向和反向传播)有一定几率(keep-prob)失效。这样来预防过拟合。它主要避免对某个节点的强依赖,让反向传播的修正值可以更加平衡的分布到各个参数上。还有如果一些节点失效,实际上也和我们减少网络复杂度是一样的道理。所以可以防止过拟合。


在使用Dropout防止过拟合时需要注意几点:
1. 在我们计算每个神经元经过激励函数后的输出值的时候要除以keep-prob。这是为了平衡因为某些神经元的失效对输出值期望的影响。
2. 一般只在隐藏层进行dropout。
3. 测试时和模型build好之后都需要去掉dropout。
4. dropout在神经元节点比较多的情况下效果明显,神经元少的情况下效果一般。

具体实现:


keepProb = 0.8
def aFunc(i,test=False):
    listA[i]=1.0 / (1 + np.exp(-listZ[i]))
    if((not test) and  i!= deep-1):
        mask = np.random.binomial(n=1,p=keepProb,size=listA[i].shape) //按keepProb概率生成0,1矩阵
        #print("mask",mask)
        listA[i]*=mask/keepProb //dropout并且修正

完整代码:


import numpy as np
deep = 3
loop = 10000
rate = 2

data = np.loadtxt("C:\data\mnist_train.csv",delimiter=",")
testData = np.loadtxt("C:\data\mnist_test.csv",delimiter=",")
fd = data[:,1:]
testFD = testData[:,1:]
testLabels = testData[:,0]
rows = fd.shape[0]
testRows = testFD.shape[0]
labels = data[:,0]
keepProb = 0.8

listW = []
listB = []
listA = []
listZ = []
listDA = []
listDZ = []
listDW = []
listDB = []
cells = np.array([784,15,20,10])
ld = np.zeros((rows,cells[-1]))

for i in range(rows):
    ld[i,int(labels[i])]=1

for i in range(deep):
    listW.append(np.random.randn(cells[i],cells[i+1]))
    listDW.append(np.zeros((cells[i],cells[i+1])))
    listB.append(np.random.randn(cells[i+1],1))
    listDB.append(np.zeros((cells[i+1],1)))
    listA.append(np.zeros((rows,cells[i+1])))
    listDA.append(np.zeros((rows,cells[i+1])))
    listZ.append(np.zeros((rows,cells[i+1])))
    listDZ.append(np.zeros((rows,cells[i+1])))

def zFunc(i,test=False):
    if(i==0):
        if(test):
            listZ[i]=testFD.dot(listW[i])
        else:
            listZ[i]=fd.dot(listW[i])
    else:
        listZ[i]=(listA[i-1].dot(listW[i]))+listB[i].T
       
def aFunc(i,test=False):
    listA[i]=1.0 / (1 + np.exp(-listZ[i]))
    if((not test) and  i!= deep-1):
        mask = np.random.binomial(n=1,p=keepProb,size=listA[i].shape)
        #print("mask",mask)
        listA[i]*=mask/keepProb
       
def fp(test=False):
    for i in range(deep):
        zFunc(i,test)
        aFunc(i,test)
       
def dA(i):
    if(i==deep-1):
        listDA[i] = - ld/listA[i] + (1-ld)/(1-listA[i])
    else:
        listDA[i] = listDZ[i+1].dot(listW[i+1].T)

def dZ(i):
        listDZ[i]=listDA[i]* listA[i] *(1-listA[i])

def dW(i):
    if (i==0):
        listDW[i]=fd.T.dot(listDZ[i])/rows
    else:
        listDW[i]=listA[i-1].T.dot(listDZ[i])/rows

def dB(i):
    listDB[i]=listDZ[i].mean(axis=0).reshape(cells[i+1],1)

def bp():
    #print("bp")
    for i in range(deep-1,-1,-1):
        dA(i)
        dZ(i)
        dB(i)
        dW(i)
def error(test=False):
    pred = np.argmax(listA[deep-1],axis=1)
    err = np.array([1,1])
    if test:
        err = pred-testLabels
        return err[err!=0].size/testRows
    else:
        err = pred-labels
        return err[err!=0].size/rows
    return err[err!=0].size
   
for i in range(loop):
    print("loop------",i,"-----------")
    fp()
    bp()
    for d in range(deep):
        listW[d] = listW[d] - rate*listDW[d]
        listB[d] = listB[d] - rate*listDB[d]
   
    pred = np.argmax(listA[deep-1],axis=1)
    print("Training Error at loop",i,":",error())
#Test
fp(test=True)
print("Test error:",error(test=True))

发表评论

电子邮件地址不会被公开。 必填项已用*标注

%d 博主赞过: