【发布时间】:2021-02-16 13:02:26
【问题描述】:
我最近开始学习深度学习,并尝试从头开始编写正向和反向传播,但我认为我的代码有问题,所以我知道这很难找到问题,你可能会觉得这样做很愚蠢从头开始编写代码而不使用框架,但如果可以的话,请帮助我。 我在 MNIST 数据集上尝试了这段代码,所有 10 个可能的答案的测试软最大值为 0.1 启动 W 和 b 的代码:
def p_init(dim1,dim2):
W=np.random.randn(dim2,dim1)*0.01
b=np.zeros((dim2,1))
return W,b
def mp_init(L_dim):
Lnum=len(L_dim)-1
W={}
b={}
for i in range(Lnum):
W[str(i+1)],b[str(i+1)]=p_init(L_dim[i],L_dim[i+1])
return W,b
relu 及其衍生代码:
def relu(z):
return np.maximum(0,z)
def drelu(z):
return np.greater(z, 0).astype(int)
sigmoid 及其导数 L 的代码
def sigmoid(z):
return expit(z)
def dsigmoid(z):
s=sigmoid(z)
return s*(1-s)
使用 softmax 的最后一层代码:
def softmax(z):
exps=np.exp(z - np.max(z))
return exps/np.sum(exps)
向前的代码:
def forward(W,b,X,L_num,activation):
Z={}
Z['0']=np.array([1])
#print("z0")
A={}
A['0']=X
#print("a0")
for i in range (L_num):
Z[str(i+1)]=np.dot(W[str(i+1)],A[str(i)])+b[str(i+1)]
print('Z['+str(i+1)+']=np.dot(W['+str(i+1)+'],A['+str(i)+'])+b['+str(i+1)+']')
if (activation[i]==0):
A[str(i+1)]=sigmoid(Z[str(i+1)])
print('A['+str(i+1)+']=sigmoid(Z['+str(i+1)+'])')
elif (activation[i]==1):
A[str(i+1)]=relu(Z[str(i+1)])
print('A['+str(i+1)+']=relu(Z['+str(i+1)+'])')
elif (activation[i]==2):
A[str(i+1)]=softmax(Z[str(i+1)])
print('A['+str(i+1)+']=softmax(Z['+str(i+1)+'])')
return Z,A
反向传播代码:(高度怀疑错误):
def backward(A,Y,Z,L_num,activation,m):
dW={}
db={}
dZ={}
dZ[str(L_num)]=A[str(L_num)]-Y
print('dZ['+str(L_num)+']=np.subtract(A['+str(L_num)+'],Y)')
for i in range(1,L_num+1):
dW[str(L_num-i+1)]=np.dot(dZ[str(L_num-i+1)],A[str(L_num-i)].T)/m
print('dW['+str(L_num-i+1)+']=np.dot(dZ['+str(L_num-i+1)+'],A['+str(L_num-i)+'].T)/m')
db[str(L_num-i+1)]=np.sum( dZ[str(L_num-i+1)],axis=1,keepdims=True)/m
print('db['+str(L_num-i+1)+']=np.sum( dZ['+str(L_num-i+1)+'],axis=1,keepdims=True)/m')
if (activation[L_num-(i+1)]==0):
#print(i)
dZ[str(L_num-i)]=np.dot(W[str(L_num-i+1)].T,dZ[str(L_num-i+1)])*dsigmoid(Z[str(L_num-i)])
print('dZ['+str(L_num-i)+']=np.dot(W['+str(L_num-i+1)+'].T,dZ['+str(L_num-i+1)+'])*dsigmoid(Z['+str(L_num-i)+'])')
elif (activation[L_num-(i+1)]==1):
#print(i)
dZ[str(L_num-i)]=np.dot(W[str(L_num-i+1)].T,dZ[str(L_num-i+1)])*drelu(Z[str(L_num-i)])
print('dZ['+str(L_num-i)+']=np.dot(W['+str(L_num-i+1)+'].T,dZ['+str(L_num-i+1)+'])*drelu(Z['+str(L_num-i)+'])')
#elif(activation[L_num-(i+1)]==2):there is no need to compute derivative of softmax
#print(i)
#dZ[str(L_num-i)]=np.dot(W[str(L_num-i+1)].T,dZ[str(L_num-i+1)])*dsoftmax(Z[str(L_num-i)])
return dZ,dW,db
更新代码
def update(W,b,dW,db,L_num,alpha):
for i in range (L_num):
W[str(i+1)]= W[str(i+1)]-(alpha*dW[str(i+1)])
print('W['+str(i+1)+']= W['+str(i+1)+']-(alpha*dW['+str(i+1)+'])')
b[str(i+1)]= b[str(i+1)]-(alpha*db[str(i+1)])
print('b['+str(i+1)+']= b['+str(i+1)+']-(alpha*db['+str(i+1)+'])')
return W,b
交叉熵代码:
def cross_entropy(Y,A,m):
S=Y*np.log(A)
L=np.sum(S)/(-1*m)
return L
启动W和b的代码以及初始参数:
m=60000####
epoch=500
alpha=0.1
L_num=3
L_dim=np.array([784,500,125,10])
activation=np.array([0,1,2])
我的 oneHotEncoder 的代码:
def adjust_y(Y,final_layer):
m=Y.shape[0]
Ya=np.zeros((final_layer,m))
#print(Ya.shape)
for i in range(m):
#print(i)
Ya[int(Y[i])][i]=1#y[i]-1
return Ya
导入 X 和 Y 的代码:
X1=inp.convert_from_file('TrainX')
X=np.reshape(X1,(60000,784)).T
Y1=inp.convert_from_file('TrainY')
Y1=np.reshape(Y1,(60000,1))
Y=adjust_y(Y1,10)
X2=inp.convert_from_file('TestX')
X2=np.reshape(X2,(10000,784)).T
Y2=inp.convert_from_file('TestY')
Y2=np.reshape(Y2,(10000,1))
开始训练的代码:
for i in range (epoch) :
Z,A=forward(W,b,X,L_num,activation)
#print("Cost"+str(i)+" : "+str(costf(Y,A[str(L_num)],m)))
print("CrossEntropy "+str(i)+" : "+str(cross_entropy(Y,A[str(L_num)],m)))
dZ,dW,db=backward(A,Y,Z,L_num,activation,m)
W,b=update(W,b,dW,db,L_num,alpha)
【问题讨论】:
标签: python numpy machine-learning deep-learning backpropagation