编程作业3.1:Multi-class classification(One-vs-all)
题目:
- 在本次练习中,你将使用逻辑回归和神经网络来识别手写数字(从0到9)。
- 今天,自动手写数字识别被广泛使用,从识别信封上的邮政编码到识别银行支票上的金额。这个练习将向你展示如何将你所学的方法用于此分类任务。
- 在第一部分中,将扩展以前的逻辑回归,并将其应用于one-vs-all分类。
- 关于数据:本次的数据是以.mat格式储存的,mat格式是matlab的数据存储格式,按照矩阵保存,与numpy数据格式兼容,适合于各种数学运算,因此这次主要使用numpy进行运算。
- ex3data1中有5000个训练样例,其中每个训练样例是一个20像素×20像素灰度图像的数字,每个像素由一个浮点数表示,该浮点数表示该位置的灰度强度。每个20×20像素的网格被展开成一个400维的向量。这些每个训练样例都变成数据矩阵X中的一行。这就得到了一个5000×400矩阵X,其中每一行都是手写数字图像的训练样例。训练集的第二部分是一个包含训练集标签的5000维向量y,“0”的数字标记为“10”,而“1”到“9”的数字按自然顺序标记为“1”到“9”。
编程实现
1.Visualizing the data
加载数据集。这里的数据为MATLAB的格式,所以要使用SciPy.io的loadmat函数。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.io import loadmat
# 这里的数据为MATLAB的格式,所以要使用SciPy.io的loadmat函数。
def load_data(path):
data = loadmat(path)
X = data['X']
y = data['y']
return X,y
X, y = load_data('D:\BaiduNetdiskDownload\data_sets\ex3data1.mat')
# unique() 统计list中的不同值时,返回的是array;用来看下有几类标签
print(np.unique(y))
X.shape, y.shape
其中有5000个训练样本,每个样本是20*20像素的数字的灰度图像。每个像素代表一个浮点数,表示该位置的灰度强度。20×20的像素网格被展开成一个400维的向量。在我们的数据矩阵X中,每一个样本都变成了一行,这给了我们一个5000×400矩阵X,每一行都是一个手写数字图像的训练样本。
def plot_an_image(X):
"""
随机打印一个数字
"""
pick_one = np.random.randint(0, 5000) # np.random.randint(a,b):用于生成一个指定范围内的整数。其中参数a是下限,参数b是上限,生成的随机数n:a<=n<b,即[a,b)
image = X[pick_one, :]
fig, ax = plt.subplots(figsize=(1, 1))
ax.matshow(image.reshape((20, 20)), cmap='gray_r') # reshape()是数组对象中的方法,用于改变数组的形状。参数cmap='gray_r'是白底黑字的
plt.xticks([]) # 去除刻度,美观
plt.yticks([])
plt.show()
print('this should be {}'.format(y[pick_one]))
plot_an_image(X)
#定义可视化函数
def plot_100_image(X):
"""
随机画100个数字
"""
sample_idx = np.random.choice(np.arange(X.shape[0]), 100) # 随机选100个样本
sample_images = X[sample_idx, :] # (100,400)
fig, ax_array = plt.subplots(nrows=10, ncols=10, sharey=True, sharex=True, figsize=(8, 8))
for row in range(10):
for column in range(10):
ax_array[row, column].matshow(sample_images[10 * row + column].reshape((20, 20)),
cmap='gray_r')
plt.xticks([])
plt.yticks([])
plt.show()
plot_100_image(X)
2.Regularized Cost function
正则化逻辑回归的代价函数如下:
\]
注意: 不惩罚第一项\(\theta_0\)
def sigmoid(z):
return 1 / (1 + np.exp(-z))
# 定义带正则项的代价函数
def regularized_cost(theta, X, y, l):
"""
don't penalize theta_0
args:
X: feature matrix, (m, n+1) # 插入了x0=1
y: target vector, (m, )
l: lambda constant for regularization
"""
thetaReg = theta[1:] # 将theta的第二列到最后一列的内容赋给theta
first = (-y*np.log(sigmoid(X@theta))) + (y-1)*np.log(1-sigmoid(X@theta))
reg = (thetaReg@thetaReg)*l / (2*len(X))
return np.mean(first) + reg
3.Regularized gradient
因为我们未对\({\theta }_{0}\)进行正则化,所以梯度下降算法将分两种情形:
\]
\]
# 定义正则化梯度值(导数值)
def regularized_gradient(theta, X, y, l):
"""
don't penalize theta_0
args:
l: lambda constant for regularization
return:
a vector of gradient
"""
thetaReg = theta[1:]
first = (1 / len(X)) * X.T @ (sigmoid(X @ theta) - y)
# 这里插入一维0,使得对theta_0不惩罚,方便计算
reg = np.concatenate([np.array([0]), (l / len(X)) * thetaReg]) # 将具有相同结构的array序列结合成一个array
return first + reg
4.One-vs-all Classification
这部分我们将实现一对多分类通过训练多个正则化logistic回归分类器,每个对应数据集中K类中的一个。利用for循环对每种数字习得一个带正则的逻辑回归分类器,然后将10个分类器的参数组成一个参数矩阵all_theta返回。
from scipy.optimize import minimize
#计算K个类别分别训练出来的参数theta
def one_vs_all(X, y, l, K):
"""generalized logistic regression
args:
X: feature matrix, (m, n+1) # with incercept x0=1
y: target vector, (m, )
l: lambda constant for regularization
K: numbel of labels
return: trained parameters
"""
all_theta = np.zeros((K, X.shape[1])) # (10, 401)
for i in range(1, K+1):
theta = np.zeros(X.shape[1])
y_i = np.array([1 if label == i else 0 for label in y]) # 如果y对应的值和i相等就返回1,否则返回0
# minimize是局部最优的解法
# fun: 求最小值的目标函数
# x0:变量的初始猜测值,如果有多个变量,需要给每个变量一个初始猜测值
# args:是传递给优化函数的参数
# method:求极值的方法
# jac:计算梯度向量的方法
# options:A dictionary of solver options.
ret = minimize(fun=regularized_cost, x0=theta, args=(X, y_i, l), method='TNC',
jac=regularized_gradient, options={'disp': True})
all_theta[i-1,:] = ret.x
return all_theta
对于这个任务,我们有10个可能的类,并且由于logistic回归只能一次在2个类之间进行分类,每个分类器在“类别 i”和“不是 i”之间决定。 我们将把分类器训练包含在一个函数中,该函数计算10个分类器中的每个分类器的最终权重,并将权重返回shape为(k, (n+1))数组,其中 n 是参数数量。
def predict_all(X, all_theta):
# compute the class probability for each class on each training instance
# 这里的h共5000行,10列,每行代表一个样本,每列是预测对应数字的概率。
h = sigmoid(X @ all_theta.T) # 注意的这里的all_theta需要转置
# create array of the index with the maximum probability
# Returns the indices of the maximum values along an axis.
h_argmax = np.argmax(h, axis=1) # 返回h矩阵中每一行的最大索引
# because our array was zero-indexed we need to add one for the true label prediction
h_argmax = h_argmax + 1 #概率最大对应的index加1就是我们分类器最终预测出来的类别
return h_argmax
这里的h共5000行,10列,每行代表一个样本,每列是预测对应数字的概率,是一个5000乘10的预测概率矩阵。我们取概率最大对应的index加1就是我们分类器最终预测出来的类别。返回的h_argmax是一个array,包含5000个样本对应的预测值。
5.Learning θ parameters
raw_X, raw_y = load_data('D:\BaiduNetdiskDownload\data_sets\ex3data1.mat')
X = np.insert(raw_X, 0, 1, axis=1) # 为X添加了一列常数项 1,(5000, 401)
y = raw_y.flatten() # 这里消除了一个维度,方便后面的计算 or .reshape(-1) (5000,)
all_theta = one_vs_all(X, y, 1, 10)
all_theta # 每一行是一个分类器的一组参数
6.Evaluating logistic regression
y_pred = predict_all(X, all_theta)
accuracy = np.mean(y_pred == y)
print ('accuracy = {0}%'.format(accuracy * 100))
总结
有K个分类器,每个分类要针对其中一种情况进行训练。也就是每个分类分别当做1,不是这个分类的当做0,进行上次作业中的逻辑回归的二分类任务。
参考资料
吴恩达机器学习作业Python实现(三):多类分类和前馈神经网络
编程作业3.1:Multi-class classification(One-vs-all)的更多相关文章
- Stanford coursera Andrew Ng 机器学习课程编程作业(Exercise 2)及总结
Exercise 1:Linear Regression---实现一个线性回归 关于如何实现一个线性回归,请参考:http://www.cnblogs.com/hapjin/p/6079012.htm ...
- stanford coursera 机器学习编程作业 exercise 3(逻辑回归实现多分类问题)
本作业使用逻辑回归(logistic regression)和神经网络(neural networks)识别手写的阿拉伯数字(0-9) 关于逻辑回归的一个编程练习,可参考:http://www.cnb ...
- 吴恩达深度学习第2课第2周编程作业 的坑(Optimization Methods)
我python2.7, 做吴恩达深度学习第2课第2周编程作业 Optimization Methods 时有2个坑: 第一坑 需将辅助文件 opt_utils.py 的 nitialize_param ...
- Coursera公开课-Machine_learing:编程作业3
第四周 编程作业: Multi-class Classification and Neural Networks 这周作业与上一周有许多相同的部分,比如longistic regression中的lr ...
- 11061160_11061151_Pair Project: Elevator Scheduler软件工程结对编程作业总结
软件工程结对编程作业总结 11061160 顾泽鹏 11061151 庞梦劼 一.关于结对编程 这次的软工任务既不是单打独斗的个人任务,也不是集思广益的团队项目,而是人数为两人的结对编程.两个人合 ...
- ufldl学习笔记和编程作业:Feature Extraction Using Convolution,Pooling(卷积和汇集特征提取)
ufldl学习笔记与编程作业:Feature Extraction Using Convolution,Pooling(卷积和池化抽取特征) ufldl出了新教程,感觉比之前的好,从基础讲起.系统清晰 ...
- ufldl学习笔记和编程作业:Softmax Regression(softmax回报)
ufldl学习笔记与编程作业:Softmax Regression(softmax回归) ufldl出了新教程.感觉比之前的好,从基础讲起.系统清晰,又有编程实践. 在deep learning高质量 ...
- 关于Coursera上的斯坦福机器学习课程的编程作业提交问题
学习Coursera上的斯坦福机器学习课程的时候,需要向其服务器提交编程作业,我遇到如下问题: 'Submission failed: unexpected error: urlread: Peer ...
- 吴恩达深度学习第4课第3周编程作业 + PIL + Python3 + Anaconda环境 + Ubuntu + 导入PIL报错的解决
问题描述: 做吴恩达深度学习第4课第3周编程作业时导入PIL包报错. 我的环境: 已经安装了Tensorflow GPU 版本 Python3 Anaconda 解决办法: 安装pillow模块,而不 ...
随机推荐
- (转)解决windows解决windows 7 部分程序图标显示不正常的问题
刚解决计算机的管理选项打开出现问题,又发现系统里部分程序的快捷图标显示不出了, 曾在xp里也出现过同样的问题,常理推断,如果系统没有被病毒破坏那可能就是系统图标缓存出现问题 因此,双管齐下,一边检查系 ...
- css画布
绘制基本图形 绘制直线 <style> .canvas{ } </style> <canvas id="myCanvas1" style=" ...
- 054-for循环
<?php for($i=1;$i<=5;$i++){ echo "$i<br />"; //循环体 } ?>
- Maven的安装和创建项目的过程
一.下载Maven包和配置环境变量 1.将下载好的maven包放到一个目录中:目录中不能有汉字和空格 2.配置环境变量 3.配置path路径 二.配置阿里云私服 1.找到setting目录,配置下载j ...
- junit基础学习之-junit3和4的区别(4)
junit3和junit4的使用区别如下 1.在JUnit3中需要继承TestCase类,但在JUnit4中已经不需要继承TestCase 2.在JUnit3中需要覆盖TestCase中的setUp和 ...
- python转换ascii码
字符转数字 ord("A") 数字转字符 chr(65)
- 每天一点点之vue框架开发 - vue-router路由进阶(路由别名、跳转、默认路由、二级路由、路由守卫)
路由别名 在main.js中的路由中添加name来创建别名 const routes = [ {path:'/footer',name:footerLink,component:Footer} ] ...
- 个人网站一步一步搭建——(20)成功在本地IIS运行
昨天网站都做完了,今天发布.然后在IIS运行成功了. 遇到了很多问题 发布了不低于10次 头都晕了. 问题1:之前写了很多调试代码 console.log(); 慢慢删除完,. 问题2:vue 不能 ...
- 对DataFrame的再理解
1.构造需要从字典构造 cds={'code':["002372.XSHE","002415.XSHE","002304.XSHE",&qu ...
- Maven工程配置依赖
1.下载 安装 官网下载maven :http://maven.apache.org/download.cgi ,下载时候注意版本,IDEA旧版本如我用的2017在安装Maven时可能会报错,此时别下 ...