有做货 物的网站吗,个体工商网上年检,打开2345网址,沉默是金吴恩达《机器学习》学习笔记十一——神经网络代码数据准备神经网络结构与代价函数初始化设置反向传播算法训练网络与验证课程链接#xff1a;https://www.bilibili.com/video/BV164411b7dx?fromsearchseid5329376196520099118
数据集链接#xff1a;https://pan.baidu…
吴恩达《机器学习》学习笔记十一——神经网络代码数据准备神经网络结构与代价函数·初始化设置反向传播算法训练网络与验证课程链接https://www.bilibili.com/video/BV164411b7dx?fromsearchseid5329376196520099118
数据集链接https://pan.baidu.com/s/1ZkB_RW9ehEV_w6ryZT64Ag 提取码8utg
这次笔记我们将再次处理手写数字数据集第八次笔记是使用的多分类逻辑回归算法这次使用反向传播的前馈神经网络。 我们将通过反向传播算法实现神经网络成本函数和梯度计算的非正则化和正则化版本。 我们还将实现随机权重初始化和使用网络进行预测的方法。
由于使用的数据集和上次代码练习是相同的我们将重新使用代码来加载数据。
数据准备
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.io import loadmatdata loadmat(ex4data1.mat)
data由于我们以后需要这些并将经常使用它们我们先来创建一些有用的变量。
X data[X]
y data[y]X.shape, y.shape #看下维度我们也需要对我们的y标签进行一次one-hot 编码。 one-hot 编码将类标签nk类转换为长度为k的向量其中索引n为“hot”1而其余为0。 Scikitlearn有一个内置的实用程序我们可以使用这个。
from sklearn.preprocessing import OneHotEncoder
encoder OneHotEncoder(sparseFalse)
y_onehot encoder.fit_transform(y)
y_onehot.shapeone-hot编码后的y会变成如下图这种形式 对应的类别位置设置为1其余位置全部是0。
看一下变换前后的标签尺寸
y[0], y_onehot[0,:]神经网络结构与代价函数·
我们要为此练习构建的神经网络具有与我们的实例数据**400 偏置单元大小匹配的输入层25个单位的隐藏层带有偏置单元的26个以及一个输出层 10个单位对应我们的一个one-hot编码类标签**。 其网络结构如下图所示其中输入层有4001个神经元隐藏层有251个神经元输出层有10个神经元 我们需要实现的第一件是评估一组给定的网络参数的损失的代价函数。神经网络的代价函数若不带正则项就是如下所示的表达式 带正则项的话表达式就会变成 先定义一下sigmoid函数
def sigmoid(z):return 1 / (1 np.exp(-z))如果要计算代价函数则需要前向传播来计算预测结果h(x)所以要先定义前向传播的函数
def forward_propagate(X, theta1, theta2):# INPUT参数值theta数据X# OUTPUT当前参数值下前项传播结果# TODO根据参数和输入的数据计算前项传播结果# STEP1获取样本个数m X.shape[0]# STEP2实现神经网络正向传播 a1 np.insert(X, 0, valuesnp.ones(m), axis1) #给X矩阵插入一行1元素z2 a1 * theta1.Ta2 np.insert(sigmoid(z2), 0, valuesnp.ones(m), axis1) #注意插入1元素z3 a2 * theta2.Th sigmoid(z3)return a1, z2, a2, z3, hdef cost(params, input_size, hidden_size, num_labels, X, y, lamda):# INPUT神经网络参数输入层维度隐藏层维度训练数据及标签正则化参数# OUTPUT当前参数值下的代价函数# TODO根据上面的公式计算代价函数# STEP1获取样本个数m X.shape[0]# STEP2将矩阵X,y转换为numpy型矩阵X np.matrix(X)y np.matrix(y)# STEP3从params中获取神经网络参数并按照输入层维度和隐藏层维度重新定义参数的维度theta1 np.matrix(np.reshape(params[:hidden_size * (input_size 1)], (hidden_size, (input_size 1))))theta2 np.matrix(np.reshape(params[hidden_size * (input_size 1):], (num_labels, (hidden_size 1))))# STEP4调用前面写好的前项传播函数a1, z2, a2, z3, h forward_propagate(X, theta1, theta2)# STEP5初始化代价函数J 0# STEP6根据公式计算代价函数for i in range(m): #遍历每个样本first_term np.multiply(-y[i,:], np.log(h[i,:]))second_term np.multiply((1 - y[i,:]), np.log(1 - h[i,:]))J np.sum(first_term - second_term)J J / m# STEP7计算代价函数的正则化部分J (float(lamda) / (2 * m)) * (np.sum(np.power(theta1[:,1:], 2)) np.sum(np.power(theta2[:,1:], 2)))return J初始化设置
将网络的层数、神经元数目、正则化系数、参数等一些变量进行初始化设置。
# 初始化设置
input_size 400
hidden_size 25
num_labels 10
lamda 1# 随机初始化完整网络参数大小的参数数组
params (np.random.random(sizehidden_size * (input_size 1) num_labels * (hidden_size 1)) - 0.5) * 0.25m X.shape[0]
X np.matrix(X)
y np.matrix(y)# 将参数数组解开为每个层的参数矩阵
theta1 np.matrix(np.reshape(params[:hidden_size * (input_size 1)], (hidden_size, (input_size 1))))
theta2 np.matrix(np.reshape(params[hidden_size * (input_size 1):], (num_labels, (hidden_size 1))))theta1.shape, theta2.shape这边显示的是theta1和theta2的维度要结合与输入X的维度理解。
a1, z2, a2, z3, h forward_propagate(X, theta1, theta2)
a1.shape, z2.shape, a2.shape, z3.shape, h.shape观察一下这些中间变量的维度。
代价函数在计算假设矩阵h之后应用代价函数来计算y和h之间的总误差。
cost(params, input_size, hidden_size, num_labels, X, y_onehot, lamda)这是初始时刻用随机设置的参数计算得到的初始代价函数值。
反向传播算法
接下来是反向传播算法。 反向传播参数更新计算将减少训练数据上的网络误差。 我们需要的第一件事是计算我们之前创建的Sigmoid函数的梯度的函数。
def sigmoid_gradient(z):return np.multiply(sigmoid(z), (1 - sigmoid(z)))它所作的工作如下面这幅图所示后面的计算中会经常使用到这个函数所以提前写出来
现在我们准备好实施反向传播来计算梯度。 由于反向传播所需的计算是代价函数中所需的计算过程我们实际上将扩展代价函数以执行反向传播并返回代价和梯度。梯度的计算过程如下所示
def backprop(params, input_size, hidden_size, num_labels, X, y, lamda):# INPUT神经网络参数输入层维度隐藏层维度训练数据及标签正则化参数# OUTPUT当前参数值下的代价函数# TODO根据上面的公式计算代价函数# STEP1获取样本个数m X.shape[0]# STEP2将矩阵X,y转换为numpy型矩阵X np.matrix(X)y np.matrix(y)# STEP3从params中获取神经网络参数并按照输入层维度和隐藏层维度重新定义参数的维度theta1 np.matrix(np.reshape(params[:hidden_size * (input_size 1)], (hidden_size, (input_size 1))))theta2 np.matrix(np.reshape(params[hidden_size * (input_size 1):], (num_labels, (hidden_size 1))))# STEP4调用前面写好的前项传播函数a1, z2, a2, z3, h forward_propagate(X, theta1, theta2)# STEP5初始化J 0delta1 np.zeros(theta1.shape)delta2 np.zeros(theta2.shape)# STEP6计算代价函数(调用函数)for i in range(m): #遍历每个样本first_term np.multiply(-y[i,:], np.log(h[i,:]))second_term np.multiply((1 - y[i,:]), np.log(1 - h[i,:]))J np.sum(first_term - second_term)J J / m# STEP7实现反向传播这里用到的公式请参考原版作业PDF的第5页for t in range(m): #遍历每个样本a1t a1[t,:] # (1, 401)z2t z2[t,:] # (1, 25)a2t a2[t,:] # (1, 26)ht h[t,:] # (1, 10)yt y[t,:] # (1, 10)d3t ht - ytz2t np.insert(z2t, 0, valuesnp.ones(1)) # (1, 26) d2t np.multiply((theta2.T * d3t.T).T, sigmoid_gradient(z2t)) # (1, 26)delta1 delta1 (d2t[:,1:]).T * a1tdelta2 delta2 d3t.T * a2t# STEP8加入正则化delta1[:,1:] delta1[:,1:] (theta1[:,1:] * lamda) / mdelta2[:,1:] delta2[:,1:] (theta2[:,1:] * lamda) / m # STEP9将梯度矩阵转换为单个数组grad np.concatenate((np.ravel(delta1), np.ravel(delta2)))return J, grad反向传播计算最难的部分除了理解为什么我们正在做所有这些计算是获得正确矩阵维度。 顺便说一下你容易混淆了A * B与np.multiplyAB使用。 基本上前者是矩阵乘法后者是元素乘法除非A或B是标量值在这种情况下没关系。 无论如何让我们测试一下以确保函数返回我们期望的。
J, grad backprop(params, input_size, hidden_size, num_labels, X, y_onehot, lamda)
J, grad.shape参数的数量应该为40125261010285个验证无误。
训练网络与验证
我们终于准备好训练我们的网络并用它进行预测。 这与以往的具有多类逻辑回归的练习大致相似。
from scipy.optimize import minimize# minimize the objective function
fmin minimize(funbackprop, x0params, args(input_size, hidden_size, num_labels, X, y_onehot, lamda), methodTNC, jacTrue, options{maxiter: 250})
fmin用训练好的参数来进行预测
X np.matrix(X)
theta1 np.matrix(np.reshape(fmin.x[:hidden_size * (input_size 1)], (hidden_size, (input_size 1))))
theta2 np.matrix(np.reshape(fmin.x[hidden_size * (input_size 1):], (num_labels, (hidden_size 1))))a1, z2, a2, z3, h forward_propagate(X, theta1, theta2)
y_pred np.array(np.argmax(h, axis1) 1)
y_pred最后再计算一下准确率
correct [1 if a b else 0 for (a, b) in zip(y_pred, y)]
accuracy (sum(map(int, correct)) / float(len(correct)))
print (accuracy {0}%.format(accuracy * 100))