
我们来说一下步骤:
初始化网络参数
前向传播
2.1 计算一层的中线性求和的部分
2.2 计算激活函数的部分(ReLU使用L-1次,Sigmod使用1次)
2.3 结合线性求和与激活函数
计算误差
反向传播
4.1 线性部分的反向传播公式
4.2 激活函数部分的反向传播公式
4.3 结合线性部分与激活函数的反向传播公式
更新参数
请注意,对于每个前向函数,都有一个相应的后向函数。 这就是为什么在我们的转发模块的每一步都会在cache中存储一些值,cache的值对计算梯度很有用, 在反向传播模块中,我们将使用cache来计算梯度。 现在我们正式开始分别构建两层神经网络和多层神经网络。
本文会提到**[LINEAR-> ACTIVATION]转发函数,比如我有一个多层的神经网络,结构是输入层->隐藏层->隐藏层->···->隐藏层->输出层**,在每一层中,我会首先计算Z = np.dot(W,A) + b,这叫做【linear_forward】线性部分,然后再计算A = relu(Z) 或者 A = sigmoid(Z),这叫做【linear_activation_forward】激活部分,合并起来就是这一层的计算方法,所以每一层的计算都有两个步骤,先是计算Z,再计算A
具体步骤 :
一.初始化参数:
二.前向传播函数:

cache - 一个包含“linear_cache”和“activation_cache”的字典,我们需要存储它以有效地计算后向传递
线性部分【LINEAR】
参数 linear_forward(A,W,b)
返回Z,cache = (A,W,b)
线性激活部分【LINEAR - >ACTIVATION】
参数linear_activation_forward(A_prev,W,b,activation):A_prev - 来自上一层(或输入层)的激活,维度为(上一层的节点数量,示例数)activation - 选择在此层中使用的激活函数名,字符串类型,【"sigmoid" | "relu"】
返回 A,cache = (linear_cache,activation_cache) 其中 1.inear_cache = linear_forward(A_prev, W, b) 中的cache(AWB) 2.activation_cache = relu(Z)/sigmoid(Z)
多层模型的前向传播计算模型
def L_model_forward(X,parameters):
parameters - initialize_parameters_deep()的输出
返回:
AL - 最后的激活值
caches - 包含以下内容的缓存列表:
linear_relu_forward()的每个cache(有L-1个,索引为从0到L-2)
linear_sigmoid_forward()的cache(只有一个,索引为L-1)
三.计算成本
def compute_cost(AL,Y):
返回cost = -np.sum(np.multiply(np.log(AL),Y) + np.multiply(np.log(1 - AL), 1 - Y)) / m 交叉熵成本

四 .反向传播:
同正向传播,也分线性和激活两部分
线性部分【LINEAR backward】
def linear_backward(dZ,cache):
dZ - 相对于(当前第l层的)线性输出的成本梯度
cache - 来自当前层前向传播的值的元组(A_prev,W,b)
返回:
dA_prev - 相对于激活(前一层l-1)的成本梯度,与A_prev维度相同
dW - 相对于W(当前层l)的成本梯度,与W的维度相同
db - 相对于b(当前层l)的成本梯度,与b维度相同
相当于接收一个cash,返回一个dA[L-1] dw db用来进行梯度下降
线性激活部分【LINEAR -> ACTIVATION backward】

两种反向激活函数在别处实现
def linear_activation_backward(dA,cache,activation="relu"):
参数:
dA - 当前层l的激活后的梯度值
cache - 我们存储的用于有效计算反向传播的值的元组(值为linear_cache,activation_cache)
activation - 要在此层中使用的激活函数名,字符串类型,【"sigmoid" | "relu"】
返回:
dA_prev - 相对于激活(前一层l-1)的成本梯度值,与A_prev维度相同
dW - 相对于W(当前层l)的成本梯度值,与W的维度相同
db - 相对于b(当前层l)的成本梯度值,与b的维度相同
而这一部分则是计算dz(既 所谓激活层 其实就是说在正向计算从z到A,而反向计算从dA到dZ)

dAL = - (np.divide(Y, AL) - np.divide(1 - Y, 1 - AL))
构建多层模型反向传播:
def L_model_backward(AL,Y,caches): 对[LINEAR-> RELU] *(L-1) - > LINEAR - > SIGMOID组执行反向传播,就是多层网络的向后传播
参数:
AL - 概率向量,正向传播的输出(L_model_forward())
Y - 标签向量(例如:如果不是猫,则为0,如果是猫则为1),维度为(1,数量)
caches - 包含以下内容的cache列表:
linear_activation_forward("relu")的cache,不包含输出层 这里头装的是
linear_activation_forward("sigmoid")的cache
返回:
grads - 具有梯度值的字典
grads [“dA”+ str(l)] = ...
grads [“dW”+ str(l)] = ...
grads [“db”+ str(l)] = ...
更新参数
def update_parameters(parameters, grads, learning_rate):
"""
使用梯度下降更新参数
参数:
parameters - 包含你的参数的字典
grads - 包含梯度值的字典,是L_model_backward的输出
返回:
parameters - 包含更新参数的字典
参数[“W”+ str(l)] = ...
参数[“b”+ str(l)] = ...
正式搭建

两层神经网络:
def two_layer_model(X,Y,layers_dims,learning_rate=0.0075,num_iterations=3000,print_cost=False,isPlot=True):
参数:
X - 输入的数据,维度为(n_x,例子数)
Y - 标签,向量,0为非猫,1为猫,维度为(1,数量)
layers_dims - 层数的向量,维度为(n_y,n_h,n_y)
learning_rate - 学习率
num_iterations - 迭代的次数
print_cost - 是否打印成本值,每100次打印一次
isPlot - 是否绘制出误差值的图谱
返回:
parameters - 一个包含W1,b1,W2,b2的字典变量
(n_x,n_h,n_y) = layers_dims
parameters = initialize_parameters(n_x, n_h, n_y) 初始化参数
for i in range(0,num_iterations): 迭代多少次在这决定
#前向传播
A1, cache1 = linear_activation_forward(X, W1, b1, "relu")
A2, cache2 = linear_activation_forward(A1, W2, b2, "sigmoid")
#计算成本
#后向传播
##初始化后向传播
dA2 = - (np.divide(Y, A2) - np.divide(1 - Y, 1 - A2))
##向后传播,输入:“dA2,cache2,cache1”。 输出:“dA1,dW2,db2;还有dA0(未使用),dW1,db1”。
##向后传播完成后的数据保存到grads
#更新参数
#打印成本值,如果print_cost=False则忽略
#迭代完成,根据条件绘制图
#返回parameters
经网络
都整完了 可以编预测函数啊
先略过 因为和多重一样,直接用多重当例子
def L_layer_model(X, Y, layers_dims, learning_rate=0.0075, num_iterations=3000, print_cost=False,isPlot=True): """ 实现一个L层神经网络:[LINEAR-> RELU] *(L-1) - > LINEAR-> SIGMOID。 参数: X - 输入的数据,维度为(n_x,例子数) Y - 标签,向量,0为非猫,1为猫,维度为(1,数量) layers_dims - 层数的向量,维度为(n_y,n_h,···,n_h,n_y) learning_rate - 学习率 num_iterations - 迭代的次数 print_cost - 是否打印成本值,每100次打印一次 isPlot - 是否绘制出误差值的图谱 返回: parameters - 模型学习的参数。 然后他们可以用来预测。 """ np.random.seed(1) costs = [] parameters = initialize_parameters_deep(layers_dims) for i in range(0,num_iterations): AL , caches = L_model_forward(X,parameters) 前进 cost = compute_cost(AL,Y) 代价函数计算 grads = L_model_backward(AL,Y,caches) 反向传播计算梯度 parameters = update_parameters(parameters,grads,learning_rate) 更新各项参数 #打印成本值,如果print_cost=False则忽略 if i % 100 == 0: #记录成本 costs.append(cost) #是否打印成本值 if print_cost: print("第", i ,"次迭代,成本值为:" ,np.squeeze(cost)) #迭代完成,根据条件绘制图 if isPlot: plt.plot(np.squeeze(costs)) plt.ylabel('cost') plt.xlabel('iterations (per tens)') plt.title("Learning rate =" + str(learning_rate)) plt.show() return parameters
图像数据集的处理:
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
预测函数
def predict(X, y, parameters): """ 该函数用于预测L层神经网络的结果,当然也包含两层 参数: X - 测试集 y - 标签 parameters - 训练模型的参数 返回: p - 给定数据集X的预测 """ m = X.shape[1] n = len(parameters) // 2 # 神经网络的层数 p = np.zeros((1,m)) #根据参数前向传播 probas, caches = L_model_forward(X, parameters) for i in range(0, probas.shape[1]): if probas[0,i] > 0.5: p[0,i] = 1 else: p[0,i] = 0 print("准确度为: " + str(float(np.sum((p == y))/m))) return p
训练加预测
#训练 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) #预测 pred_train = predict(train_x, train_y, parameters) #训练集 pred_test = predict(test_x, test_y, parameters) #测试集
分析
可以用来查看到底哪些数据被判定错了
def print_mislabeled_images(classes, X, y, p): """ 绘制预测和实际不同的图像。 X - 数据集 y - 实际的标签 p - 预测 """ a = p + y#由数学基础得,只有实际与预测不符的时候,a==1 mislabeled_indices = np.asarray(np.where(a == 1)) #np.where(condition, x, y) #满足条件(condition),输出x,不满足输出y。 #只有条件 (condition),没有x和y,则输出满足条件 (即非0) 元素的坐标 (等价于 #numpy.nonzero)。这里的坐标以tuple的形式给出,通常原数组有多少维,输出 #的tuple中就包含几个数组,分别对应符合条件元素的各维坐标。 plt.rcParams['figure.figsize'] = (40.0, 40.0) # set default size of plots num_images = len(mislabeled_indices[0]) for i in range(num_images): index = mislabeled_indices[1][i] plt.subplot(2, num_images, i + 1) plt.imshow(X[:,index].reshape(64,64,3), interpolation='nearest') plt.axis('off') plt.title("Prediction: " + classes[int(p[0,index])].decode("utf-8") + " \n Class: " + classes[y[0,index]].decode("utf-8")) print_mislabeled_images(classes, test_x, test_y, pred_test)
plt.rcParams[]
pylot使用rc配置文件来自定义图形的各种默认属性,称之为rc配置或rc参数。通过rc参数可以修改默认的属性,
包括窗体大小、每英寸的点数、线条宽度、颜色、样式、坐标轴、坐标和网络属性、文本、字体等。
浙公网安备 33010602011771号