在吴恩达老师DL系列课程的学习过程中,跟随做的一些小练习,在看懂别人代码基础上,整理的一些小笔记。
源代码参考:https://blog.csdn.net/u013733326/article/details/79767169
DL中的列表、元组与字典
在DL的算法中,需要将一些参数存储起来,方便在下一次的前向传播与反向传播过程中,直接调用。
据观察,参考代码中,常常将存储变量定义为列表、元组或字典类型。
1、在初始化函数initialize_parameters_deep中,将参数存储于字典变量parameters
返回parameters为字典类型:
parameters - 包含参数“W1”,“b1”,...,“WL”,“bL”的字典:
W1 - 权重矩阵,维度为(layers_dims [1],layers_dims [1-1])
b1 - 偏向量,维度为(layers_dims [1],1)
①先创建空字典
parameters = {}
②再赋值
for l in range(1,L):
parameters["W" + str(l)] = np.random.randn(layers_dims[l], layers_dims[l - 1]) / np.sqrt(layers_dims[l - 1])
parameters["b" + str(l)] = np.zeros((layers_dims[l], 1))
③调用
print("W1 = " + str(parameters["W1"]))
print("b1 = " + str(parameters["b1"]))
2、在前向传播函数的线性部分linear_forward中,将参数存储于元组变量cache
def linear_forward(A,W,b):
Z = np.dot(W,A) + b
assert(Z.shape == (W.shape[0],A.shape[1]))
cache = (A,W,b)
print(type(cache)) #tuple类型
return Z,cache
3、在前向传播函数的线性激活部分linear_activation_forward中,先将参数各自存储于两个中间变量linear_cache和activation_cache(元组类型)中,再添加至元组变量cache中
def linear_activation_forward(A_prev,W,b,activation):
if activation == "sigmoid":
Z, linear_cache = linear_forward(A_prev, W, b) # linear_cache中,存储的为A_pre(X),w,b,前向传播函数线性部分时的输入参数,计算后的结果为Z
A, activation_cache = sigmoid(Z) # activation_cache中,存储的为Z,前向传播函数线性激活部分时的输入参数,计算后的结果为A
elif activation == "relu":
Z, linear_cache = linear_forward(A_prev, W, b)
A, activation_cache = relu(Z)
cache = (linear_cache,activation_cache) #将 linear_cache 与 activation_cache 放入新元组 cache 中
return A,cache
# 元组的妙用:因为元组不可修改,所以对元组反复赋值时,并不是修改元组自身,而是创建了新的元组
4、多层神经网络的前向传播函数L_model_forward中,将元组类型的存储变量cache,添加至列表类型的存储变量caches中
def L_model_forward(X,parameters):
caches = [] #列表型变量
A = X
L = len(parameters) // 2
for l in range(1,L):
A_prev = A
A, cache = linear_activation_forward(A_prev, parameters['W' + str(l)], parameters['b' + str(l)], "relu")
caches.append(cache) #将元组类型的变量放入列表中,在列表末尾添加新变量
AL, cache = linear_activation_forward(A, parameters['W' + str(L)], parameters['b' + str(L)], "sigmoid")
caches.append(cache)
return AL,caches
DL的反向传播
与前向传播类似,我们有需要使用三个步骤来构建反向传播
- LINEAR 后向计算:单层实现反向传播的线性部分(输入dZ)
- LINEAR -> ACTIVATION 后向计算,其中ACTIVATION 计算Relu或者Sigmoid 的结果:单层实现LINEAR -> ACTIVATION层的后向传播(输入dA,求dZ但不输出dZ,dZ为中间变量)
- [LINEAR -> RELU] × \times × (L-:1) -> LINEAR -> SIGMOID 后向计算 (整个模型):输入AL(概率向量yhat,正向传播的输出)
L_model_backward(AL,Y,caches)
linear_activation_backward(dA,cache,activation="relu")
linear_backward(dZ,cache)
函数 | 输入 | 输出 | cache | 作用 |
L_model_backward() | AL,Y,caches | grads - 具有梯度值的字典 grads [“dA”+ str(l)] = ... grads [“dW”+ str(l)] = ... grads [“db”+ str(l)] = ... | caches - 包含“relu”和“sigmiod”两激活函数linear_activation_forward的cache的列表; linear_relu_forward()的每个cache(有L-1个,索引为从0到L-2)
linear_activation_forward 的 cache - 包含“linear_cache” 和 “activation_cache” 的元组; cache = (linear_cache,activation_cache)
linear_cache - 里面存储的为线性传播部分的A,w,b; activation_cache - 里面存储的为线性运算后的结果Z; | L层反向传播参数的计算 |
linear_activation_backward() | dA,cache,activation="relu" | dA_prev,dW,db | 存储的用于有效计算反向传播的值的元组(值为linear_cache,activation_cache),即linear_activation_forward的cache。 | 单层反向传播参数的计算 |
linear_backward() | dZ,cache | dA_prev,dW,db | cache - 来自当前层前向传播的值的元组(A_prev,W,b) | 单层反向传播的线性部分计算,不包括dZ的计算 |