题目下载【传送门

题目简述:识别图片中的数字,训练该模型,求参数θ。

出现了一个问题:虽然训练的模型能够有很好的预测准确率,但是使用minimize函数时候始终无法成功,无论设计的迭代次数有多大,如下图:

 import numpy as np
import scipy.io as scio
import matplotlib.pyplot as plt
import scipy.optimize as op # X:5000*400
# Y:5000*10
# a1:5000*401(后5000*400)
# z2:5000*25
# a2:5000*26(后5000*25)
# z3:5000*10
# a3:5000*10
# Theta1:25*401
# Theta2:10*26
# delta3:5000*10
# delta2:5000*25
# bigDelta1:25*401
# bigDelta2:10*26
# Theta1_grad:25*401
# Theta2_grad:10*26 #显示图片数据
def displayData(X):
m = np.size(X, 0) #X的行数,即样本数量
n = np.size(X, 1) #X的列数,即单个样本大小
example_width = int(np.round(np.sqrt(n))) #单张图片宽度
example_height = int(np.floor(n / example_width)) #单张图片高度
display_rows = int(np.floor(np.sqrt(m))) #显示图中,一行多少张图
display_cols = int(np.ceil(m / display_rows)) #显示图中,一列多少张图片
pad = 1 #图片间的间隔
display_array = - np.ones((pad + display_rows * (example_height + pad),
pad + display_cols * (example_width + pad))) #初始化图片矩阵
curr_ex = 0 #当前的图片计数
#将每张小图插入图片数组中
for j in range(0, display_rows):
for i in range(0, display_cols):
if curr_ex >= m:
break
max_val = np.max(abs(X[curr_ex, :]))
jstart = pad + j * (example_height + pad)
istart = pad + i * (example_width + pad)
display_array[jstart: (jstart + example_height), istart: (istart + example_width)] = \
np.array(X[curr_ex, :]).reshape(example_height, example_width) / max_val
curr_ex = curr_ex + 1
if curr_ex >= m:
break
display_array = display_array.T
plt.imshow(display_array,cmap=plt.cm.gray)
plt.axis('off')
plt.show() #计算hθ(z)
def sigmoid(z):
g = 1.0 / (1.0 + np.exp(-z))
return g #初始化Θ,保持在[-ε,ε]
def randInitializeWeights(sizeList):
epsilon_init = 0.12
theta1_lx = sizeList['theta1_lx']
theta1_ly = sizeList['theta1_ly']
theta2_lx = sizeList['theta2_lx']
theta2_ly = sizeList['theta2_ly']
theta_size = theta1_lx * theta1_ly + theta2_lx * theta2_ly
W = np.random.uniform(-epsilon_init, epsilon_init, theta_size)
return W #把一维的矩阵改写为多维
def changeForm(theta_vector, theta1_lx, theta1_ly, theta2_lx, theta2_ly):
theta1 = np.array(theta_vector[0: theta1_lx * theta1_ly]).reshape(theta1_lx, theta1_ly)
theta2 = np.array(theta_vector[theta1_lx * theta1_ly: theta1_lx * theta1_ly + theta2_lx * theta2_ly])\
.reshape(theta2_lx, theta2_ly)
theta = {'Theta1': theta1, 'Theta2': theta2}
return theta #计算正向激励的参数a
def computeA(nn_params, X):
theta1 = nn_params['Theta1']
theta2 = nn_params['Theta2']
m = np.size(X, 0) #第二层计算
one = np.ones(m)
a1 = np.insert(X, 0, values=one, axis=1)
a2 = sigmoid(np.dot(a1, theta1.T))
#第三层计算
one = np.ones(np.size(a2, 0))
a2 = np.insert(a2, 0, values=one, axis=1)
a3 = sigmoid(np.dot(a2, theta2.T))
a_res = {'a1': a1, 'a2': a2, 'a3': a3}
return a_res #计算g'(z)
def sigmoidGradient(z):
g = np.multiply(sigmoid(z), 1 - sigmoid(z))
return g #计算 J
def nnCostFunction(nn_params, X, Y, lamb, sizeList):
theta = changeForm(nn_params,
sizeList['theta1_lx'], sizeList['theta1_ly'],
sizeList['theta2_lx'], sizeList['theta2_ly'])
theta1 = theta['Theta1']
theta2 = theta['Theta2']
m = np.size(X, 0)
a_res = computeA(theta, X)
a3 = a_res['a3']
#计算J
J = 1 / m * np.sum(-np.multiply(Y, np.log(a3)) - np.multiply((1 - Y), np.log(1 - a3)))
#规格化
theta1_copy = theta1[:, 1:]
theta2_copy = theta2[:, 1:]
J = J + lamb / (2 * m) * (np.sum(theta1_copy ** 2) + np.sum(theta2_copy ** 2))
print(J)
return J #计算 D
def nnGradient(nn_params, X, Y, lamb, sizeList):
theta = changeForm(nn_params,
sizeList['theta1_lx'], sizeList['theta1_ly'],
sizeList['theta2_lx'], sizeList['theta2_ly'])
theta1 = theta['Theta1']
theta2 = theta['Theta2']
m = np.size(X, 0)
a_res = computeA(theta, X)
a1 = a_res['a1']
a2 = a_res['a2']
a3 = a_res['a3']
theta1_copy = theta1[:, 1:]
theta2_copy = theta2[:, 1:]
#计算δ
delta3 = a3 - Y
delta2 = np.multiply(np.dot(delta3, theta2_copy), sigmoidGradient(np.dot(a1, theta1.T)))
#计算Δ
bigDeilta1 = np.dot(delta2.T, a1)
bigDeilta2 = np.dot(delta3.T, a2)
#计算D
theta1_grad = bigDeilta1 / m + lamb / m * theta1
theta2_grad = bigDeilta2 / m + lamb / m * theta2
theta1_grad[:, 0] = bigDeilta1[:, 0] / m
theta2_grad[:, 0] = bigDeilta2[:, 0] / m
#当使用高级优化方法来优化神经网络时,需要将多个参数矩阵展开,才能传入优化函数
grad = np.r_[theta1_grad.flatten(), theta2_grad.flatten()]
# print(np.size(grad))
return grad #测试参数的初始化
def debugInitializeWeights(L_out, L_in):
W = np.arange(1, L_out * (L_in + 1)+1)
W = np.sin(W)
W = np.array(W).reshape(L_out, (L_in + 1)) / 10;
return W #数值方法计算梯度
def computeNumericalGradient(theta, X, Y ,lamb, sizeList):
numgrad = np.zeros(np.size(theta))
perturb = np.zeros(np.size(theta))
e = 1e-4
for p in range(0, np.size(theta)):
perturb[p] = e
theta_minus = theta - perturb
theta_plus = theta + perturb
loss1 = nnCostFunction(theta_minus, X, Y, lamb, sizeList)
loss2 = nnCostFunction(theta_plus, X, Y, lamb, sizeList)
numgrad[p] = (loss2 - loss1) / (2 * e)
perturb[p] = 0
return numgrad #梯度检测函数
def checkNNGradients(lamb):
#设置测试参数
input_layer_size = 3;
hidden_layer_size = 5;
num_labels = 3;
lamb = 1
m = 5;
sizeList = {'theta1_lx': hidden_layer_size,
'theta1_ly': input_layer_size + 1,
'theta2_lx': num_labels,
'theta2_ly': hidden_layer_size + 1} # 保存θ大小的参数
theta1 = debugInitializeWeights(hidden_layer_size, input_layer_size)
theta2 = debugInitializeWeights(num_labels, hidden_layer_size)
theta = np.r_[theta1.flatten(), theta2.flatten()]
X = debugInitializeWeights(m, input_layer_size - 1)
y = np.random.randint(0, num_labels, (m, 1))
# 对y进行改写,改为 m*num_labels 规格的矩阵
Y = np.zeros((m, num_labels))
for i in range(0, m):
Y[i, y[i, 0]] = 1
grad = nnGradient(theta, X, Y, lamb, sizeList)
numGrad = computeNumericalGradient(theta, X, Y, lamb, sizeList)
diff = np.linalg.norm(numGrad - grad) / np.linalg.norm(numGrad + grad)
print('check NN Gradient: diff = ', diff) #使用模型进行预测
def predict(theta1, theta2, X):
m = np.size(X,0)
p = np.zeros((np.size(X, 0), 1))
#第二层计算
one = np.ones(m)
X = np.insert(X, 0, values=one, axis=1)
a2 = sigmoid(np.dot(X, theta1.T))
#第三层计算
one = np.ones(np.size(a2,0))
a2 = np.insert(a2, 0, values=one, axis=1)
a3 = sigmoid(np.dot(a2, theta2.T))
p = a3.argmax(axis=1) + 1 #y的值为1-10,所以此处0-9要加1
return p.flatten() # ——————————————主函数————————————————————
#初始化数据
input_layer_size = 400
hidden_layer_size = 25
num_labels = 10
sizeList = {'theta1_lx': hidden_layer_size,
'theta1_ly': input_layer_size + 1,
'theta2_lx': num_labels,
'theta2_ly': hidden_layer_size + 1} #保存θ大小的参数
lamb = 1 #加载数据文件
data = scio.loadmat('ex4data1.mat')
X = data['X']
m = np.size(X, 0)
y = data['y']
# 对y进行改写,改为5000*10规格的矩阵,第0-9个位置分别表示1,2,...,9,0
Y = np.zeros((m, num_labels))
for i in range(0, m):
Y[i, y[i, 0] - 1] = 1
rand_indices = np.random.randint(0, m, 100)
sel = X[rand_indices, :]
displayData(sel) #测试数据θ
theta = scio.loadmat('ex4weights.mat')
theta1 = theta['Theta1']
theta2 = theta['Theta2']
nn_theta = np.r_[theta1.flatten(), theta2.flatten()] #测试nnCostFunction
# J = nnCostFunction(nn_theta, X, Y, 3, sizeList)
# print(J) #测试nnGradient
print(nnGradient(nn_theta, X, Y, lamb, sizeList)) #初始化参数
nn_params = randInitializeWeights(sizeList) # 梯度检测
# checkNNGradients(lamb) # 训练模型
res = op.minimize(fun=nnCostFunction,
x0=nn_params,
args=(X, Y, lamb, sizeList),
method='TNC',
jac=nnGradient,
options={'maxiter': 100})
print(res) #计算准确率
all_theta = changeForm(res.x, sizeList['theta1_lx'], sizeList['theta1_ly'],
sizeList['theta2_lx'], sizeList['theta2_ly'])
res_theta1 = all_theta['Theta1']
res_theta2 = all_theta['Theta2']
pred = predict(res_theta1, res_theta2, X)
acc = np.mean(pred == y.flatten())*100
print('Training Set Accuracy:',acc,'%') #显示中间隐藏层
displayData(res_theta1[:, 1:])

隐藏层显示:

机器学习作业(四)神经网络参数的拟合——Python(numpy)实现的更多相关文章

  1. 机器学习作业(二)逻辑回归——Python(numpy)实现

    题目太长啦!文档下载[传送门] 第1题 简述:实现逻辑回归. 此处使用了minimize函数代替Matlab的fminunc函数,参考了该博客[传送门]. import numpy as np imp ...

  2. 机器学习作业(四)神经网络参数的拟合——Matlab实现

    题目下载[传送门] 题目简述:识别图片中的数字,训练该模型,求参数θ. 第1步:读取数据文件: %% Setup the parameters you will use for this exerci ...

  3. 菜鸟之路——机器学习之BP神经网络个人理解及Python实现

    关键词: 输入层(Input layer).隐藏层(Hidden layer).输出层(Output layer) 理论上如果有足够多的隐藏层和足够大的训练集,神经网络可以模拟出任何方程.隐藏层多的时 ...

  4. 只需十四步:从零开始掌握 Python 机器学习(附资源)

    分享一篇来自机器之心的文章.关于机器学习的起步,讲的还是很清楚的.原文链接在:只需十四步:从零开始掌握Python机器学习(附资源) Python 可以说是现在最流行的机器学习语言,而且你也能在网上找 ...

  5. 只需十四步:从零开始掌握Python机器学习(附资源)

    转载:只需十四步:从零开始掌握Python机器学习(附资源) Python 可以说是现在最流行的机器学习语言,而且你也能在网上找到大量的资源.你现在也在考虑从 Python 入门机器学习吗?本教程或许 ...

  6. 机器学习(四)正则化与过拟合问题 Regularization / The Problem of Overfitting

    文章内容均来自斯坦福大学的Andrew Ng教授讲解的Machine Learning课程,本文是针对该课程的个人学习笔记,如有疏漏,请以原课程所讲述内容为准.感谢博主Rachel Zhang 的个人 ...

  7. Stanford机器学习---第四讲. 神经网络的表示 Neural Networks representation

    原文 http://blog.csdn.net/abcjennifer/article/details/7749309 本栏目(Machine learning)包括单参数的线性回归.多参数的线性回归 ...

  8. 机器学习之支持向量机(四):支持向量机的Python语言实现

    注:关于支持向量机系列文章是借鉴大神的神作,加以自己的理解写成的:若对原作者有损请告知,我会及时处理.转载请标明来源. 序: 我在支持向量机系列中主要讲支持向量机的公式推导,第一部分讲到推出拉格朗日对 ...

  9. 【pytorch】学习笔记(四)-搭建神经网络进行关系拟合

    [pytorch学习笔记]-搭建神经网络进行关系拟合 学习自莫烦python 目标 1.创建一些围绕y=x^2+噪声这个函数的散点 2.用神经网络模型来建立一个可以代表他们关系的线条 建立数据集 im ...

随机推荐

  1. 新手必看:PyCharm安装教程,Python开发者的有力工具

    PyCharm是由JetBrains打造的一款Python IDE,VS2010的重构插件Resharper就是出自JetBrains之手. 同时支持Google App Engine,PyCharm ...

  2. .NET Core 3 Web Api Cors fetch 一直 307 Temporary Redirect

    .NET Core 3 Web Api Cors fetch 一直 307 Temporary Redirect 继上一篇 .net core 3 web api jwt 一直 401 为添加JWT- ...

  3. Javascript 基础学习(六)js 的对象

    定义 对象是JS中的引用数据类型.对象是一种复合数据类型,在对象中可以保存多个不同数据类型的属性.使用typeof检查一个对象时,会返回object. 分类 内置对象 由ES标准定义的对象,在任何ES ...

  4. Eclipse+ADT+Android SDK搭建安卓开发环境

    第一步:打开[Android.rar]压缩包,如图所示[评论区回复我,压缩包地址] 第二步:配置环境变量 (1) 解压[android-sdk_r24.4.1-windows.zip]压缩包 (2)  ...

  5. 【python数据挖掘】使用词云分析来分析豆瓣影评数据

    概述: 制作词云的步骤: 1.从文件中读取数据 2.根据数据追加在一个字符串里面,然后用jieba分词器将评论分开 3.设置WordCloud词云参数 4.保存最后的结果 数据:使用爬取的豆瓣影评数据 ...

  6. JAVA面向对象 - 抽象类、接口

    抽象类 用abstract关键字来修饰一个类时,这个类就叫抽象类,用abstract关键字来修饰一个方式时,这个方法就是抽象方法.当一个类继承的父类是抽象类的话,需要我们把抽象类中的所有抽象方法全部实 ...

  7. C#通过文件路径获取文件名

    string fullPath = @"\WebSite1\Default.aspx"; string filename = System.IO.Path.GetFileName( ...

  8. Charles抓包工具的破解以及使用

    一.破解 官网下载Charles 下载Charles.jar ,然后按照后在Charles→lib中替换掉Charles.jar 链接:https://pan.baidu.com/s/1XZ-aZI5 ...

  9. PTA 符号配对 —— C++

    请编写程序检查C语言源程序中下列符号是否配对:/*与 */.(与 ).[与].{与}. 输入格式: 输入为一个C语言源程序.当读到某一行中只有一个句点.和一个回车的时候,标志着输入结束.程序中需要检查 ...

  10. Node.js核心模块-http

    通过node中的http模块可以创建编写服务器 引入 const http = require('http') http举例使用: const http = require('http') //引入 ...