python实现深层神经网络ANN算法
- 吴恩达第四周课后编程作业
- 首先load一些需要使用的包
- 深层神经网络实现流程
- 一.initialize parameters
- 二.forward propagate
- 1.linear forward
- 2.linear activation forward
- 3.forward model
- 三.compute cost
- 四.backward propagate
- 1.linear backward
- 2.linear activation backward
- 3.backward model
- 五.update parameters
- 六.预测函数
- 七.搭建一个多层神经网络模型
- 八.测试结果
吴恩达第四周课后编程作业
首先load一些需要使用的包
import numpy as np
import h5py
import matplotlib.pyplot as plt
import testCases
from dnn_utils import sigmoid, sigmoid_backward, relu, relu_backward
import lr_utils
深层神经网络实现流程
一.initialize parameters
def initialize_parameters_deep(layers_dims):
np.random.seed(3)
L = len(layers_dims)
params = {}
for i in range(1,L):
params["W"+str(i)] = np.random.randn(layers_dims[i],layers_dims[i-1])*0.01
params['b'+str(i)] = np.zeros((layers_dims[i],1))
return params
犯的错/注意事项:
- 在for循环initialize W和b之前没有设定params={}
params = {}
二.forward propagate
linear_forward ➡️ linear_activation_forward ➡️ forward model (后者包含前者)
函数名 | linear_forward | linear_activation_forward | forward model(N-1次relu,1次sigmoid) |
输入 | A_prev,W,b | A_prev,W,b,activations | X, parameters(初始的parameters 以及 forward➡️backward大循环更新后的parameters) |
cache | A_prev,W,b | [(A_prev,W,b), (Z)] | 小循环的cache用于backward |
输出 | Z, linear_cache | A, linear_activation_cache | AL, 小循环linear_activation_cache |
1.linear forward
def linear_forward(A_prev,W,b):
Z = np.dot(W,A_prev) + b
linear_cache = (A_prev,W,b)
assert(Z.shape == (W.shape[0],A_prev.shape[1]))
return Z,linear_cache
犯的错/注意事项:
1.忘记用assert
2.linear activation forward
def linear_activation_forward(A_prev,W,b,activation):
linear_activation_cache = []
if activation =='relu':
Z,linear_cache = linear_forward(A_prev,W,b)
A,activation_cache = relu(Z)
linear_activation_cache = (linear_cache,activation_cache)
if activation == 'sigmoid':
Z,linear_cache = linear_forward(A_prev,W,b)
A,activation_cache = sigmoid(Z)
linear_activation_cache = (linear_cache,activation_cache)
return A,linear_activation_cache
犯的错/注意事项:
1.首先要定义linear_activation_cache用于最后统计linear_cache和activation_cache(其实不定义也可以,但定义了更清晰一些)
3.forward model
def L_model_forward(X,params):
A = X
cache = []
L = len(params)//2
for i in range(1,L):
A,linear_activation_cache = linear_activation_forward(A,params['W'+str(i)],params['b'+str(i)],'relu')
cache.append(linear_activation_cache)
AL,linear_activation_cache = linear_activation_forward(A,params['W'+str(L)],params['b'+str(L)],'sigmoid')
cache.append(linear_activation_cache)
assert(AL.shape == (1,X.shape[1]))
return AL,cache
犯的错/注意事项:
- 将最开始输入的X赋值给A,然后将A带入前N-1次循环,在这个循环中没有记录每次循环A的值,只记录了W,b,Z的值。A的值只用于最后计算AL。
三.compute cost
def compute_cost(AL,y):
m = y.shape[1]
cost =(-1/m)*np.sum( (np.multiply(y,np.log(AL))+np.multiply(1-y,np.log(1-AL))))
cost = np.squeeze(cost)
return cost
犯的错/注意事项:
- cost的计算方式有很多种,这是其中一种
四.backward propagate
linear_backward ➡️ linear_activation_backward ➡️ backward_model
函数名 | linear_backward | linear_activation_backward | backward model(N-1次relu,1次sigmoid) |
输入 | dZ,linear_cache | dA,linear_activation_cache,activations | AL,y(计算dAL),cache) |
cache | A_prev,W,b | [(A_prev,W,b), (Z)] | 用cache计算current_cache |
输出 | dA_prev,dW,db | dZ(用于linear_backward),\n dA_prev,dW,db(linear_backward结果) | grads(包括dA_prev,dW,db) |
1.linear backward
def linear_backward(dZ,linear_cache):
m = dZ.shape[1]
A_prev,W,b = linear_cache
dW = (1/m)*np.dot(dZ,A_prev.T)
db = (1/m)*np.sum(dZ,axis=1,keepdims=True)
dA_prev = np.dot(W.T,dZ)
assert(dW.shape == W.shape)
assert(db.shape == b.shape)
assert(dA_prev.shape == A_prev.shape)
return dA_prev,dW,db
犯的错/注意事项:
- dW不需要用np.sum,db需要用np.sum
- 两者都要除以m,但不用加负号(计算cost才要加负号)
2.linear activation backward
def linear_activation_backward(dA,cache,activation='relu'): ##activation_cache = Z
linear_cache,activation_cache = cache[0],cache[1]
if activation == 'relu':
dZ = relu_backward(dA,activation_cache)
dA_prev,dW,db = linear_backward(dZ,linear_cache)
if activation == 'sigmoid':
dZ = sigmoid_backward(dA,activation_cache)
dA_prev,dW,db =linear_backward(dZ,linear_cache)
return dA_prev,dW,db
犯的错/注意事项:
- relu_backward/sigmoid_backward的输出值dZ是linear_backward的输入值
3.backward model
def L_model_backward(AL,y,cache): ##y用于计算dAL
L = len(cache)
grads = {}
y = y.reshape(AL.shape)
dAL = -np.divide(y,AL) + np.divide(1-y,1-AL)
current_cache = cache[L-1]
grads['dA_prev'+str(L-1)],grads['dW'+str(L)],grads['db'+str(L)] = linear_activation_backward(dAL,current_cache,'sigmoid')
for i in reversed(range(L-1)):
current_cache = cache[i]
grads['dA_prev'+str(i)],grads['dW'+str(i+1)],grads['db'+str(i+1)] = linear_activation_backward(grads['dA_prev'+str(i+1)],current_cache,'relu')
return grads
犯的错/注意事项:
- 注意调用dA_prev,dW,db时应该是grads[‘dA_prev’+str()], grads[‘dW’+str()], grads[‘db’+str()]
五.update parameters
def update_parameters(params,grads,learning_rate ):
L = len(params)//2
for i in range(L):
params['W'+str(i+1)] = params['W'+str(i+1)] - learning_rate*grads['dW'+str(i+1)]
params['b'+str(i+1)] = params['b'+str(i+1)] - learning_rate*grads['db'+str(i+1)]
return params
六.预测函数
def predict(X,y,params):
AL,cache = L_model_forward(X,params)
y_predictions = np.round(AL)
print('准确率为:'+str(float(np.mean(y_predictions==y))*100),'%')
七.搭建一个多层神经网络模型
##搭建L层神经网络
def L_layer_model(X,y,layers_dims,learning_rate = 0.0075,num_iterations=3000,print_cost=False,isPlot=True):
costs = []
params = initialize_parameters_deep(layers_dims)
for i in range(num_iterations):
AL,caches = L_model_forward(X,params)
cost = compute_cost(AL,y)
grads = L_model_backward(AL,y,caches)
params = update_parameters(params,grads,learning_rate)
if i%100==0:
costs.append(cost)
if print_cost:
print('第',i,'次迭代的成本为:'+str(np.squeeze(cost)))
if isPlot:
plt.plot(costs)
plt.show
return params
犯的错/注意事项:
- initialize_parameters_deep在循环外
- 注意if isPlot 和 return 所在的层数 不要放到循环里面了
八.测试结果
train_set_x_orig , train_set_y , test_set_x_orig , test_set_y , classes = lr_utils.load_dataset()
train_x_flatten = train_set_x_orig.reshape(train_set_x_orig.shape[0], -1).T
test_x_flatten = test_set_x_orig.reshape(test_set_x_orig.shape[0], -1).T
train_x = train_x_flatten / 255
train_y = train_set_y
test_x = test_x_flatten / 255
test_y = test_set_y
layers_dims = [12288, 20, 7, 5, 1] # 5-layer model
parameters = L_layer_model(train_x, train_y, layers_dims, num_iterations = 2500, print_cost = True,isPlot=True)
第 0 次迭代的成本为:0.7157315134137129
第 100 次迭代的成本为:0.6358104685472756
第 200 次迭代的成本为:0.624211729336833
第 300 次迭代的成本为:0.5942520895813624
第 400 次迭代的成本为:0.5177020189712547
第 500 次迭代的成本为:0.48029183540093934
第 600 次迭代的成本为:0.4491625467455897
第 700 次迭代的成本为:0.3978139540283668
第 800 次迭代的成本为:0.32885059833709007
第 900 次迭代的成本为:0.230716793378725
第 1000 次迭代的成本为:0.18255839538365654
第 1100 次迭代的成本为:0.07898759604417119
第 1200 次迭代的成本为:0.04898495328260282
第 1300 次迭代的成本为:0.03282016740817885
第 1400 次迭代的成本为:0.02402136845804331
第 1500 次迭代的成本为:0.01844661191200428
第 1600 次迭代的成本为:0.014628746116686056
第 1700 次迭代的成本为:0.011912712622317589
第 1800 次迭代的成本为:0.009927981714222066
第 1900 次迭代的成本为:0.008436457653828871
第 2000 次迭代的成本为:0.00728216755158834
第 2100 次迭代的成本为:0.006373272400546734
第 2200 次迭代的成本为:0.005638518640803364
第 2300 次迭代的成本为:0.005040539895217554
第 2400 次迭代的成本为:0.00454373648094516
pred_train = predict(train_x, train_y, parameters) #训练集
pred_test = predict(test_x, test_y, parameters) #测试集
准确率为:100.0 %
准确率为:74.0 %