吴恩达机器学习作业3:Multi-class Classification and Neural Networks python实现
一 、 多分类器
1.数据可视化
#加载数据
path1 = r'C:\Users\郑思铭\Desktop\py\hw_3\ex3data1.mat'
data1 = scio.loadmat(path1)
x = data1['X']
y = data1['y']
#数据可视化
m = x.shape[0]
random = np.random.permutation(range(m))
temp = random[0:100]
select = x[temp, :]
displaydata(select)
数据可视化的难点是将x矩阵的每个example(1 * 200)恢复成 (20 *20)的格式,然后以 (20 *20)的格式嵌入每个显示图片的小格子中,一共显示100个example,小格子结构为( 10 *10)。
然而在实现的过程中一直有个转置的点无法理解:
import matplotlib.pyplot as plt
import numpy as np
def displaydata(x):
#计算每个example的尺寸
m, n = x.shape
height = np.sqrt(n).astype(int)
width = (n / height).astype(int)
#计算display example的行个数、列个数
rows = np.sqrt(m).astype(int)
cols = (m / rows).astype(int)
#设置example之间的间隙大小
pad = 1
#初始化display图像的矩阵
dis_mat = np.zeros((pad + rows*(pad + width), pad + cols*(pad + height)))
#将x的每一行信息输入example矩阵中
for i in range(rows):
for j in range(cols):
max_val = x[i*10 + j, :].max()
temp = x[i*10 + j, :].reshape(width, height) / max_val
#无法理解这里为什么不用转置!!!!!!!!!!!!!!!
dis_mat[pad + i*(pad + height) + np.arange(height), pad + j*(pad + width) + np.arange(width)[:, np.newaxis]] = \
temp.reshape(width, height)
plt.figure()
plt.imshow(dis_mat, cmap='gray', extent=[-1, 1, -1, 1])
plt.axis('off')
plt.title('Random Seleted Digits')
plt.show()
代码中:
dis_mat[pad + i*(pad + height) + np.arange(height), pad + j*(pad + width) + np.arange(width)[:, np.newaxis]] = \
temp.reshape(width, height)
这样选取的位置矩阵应该为:
[(0,) (1,) (2,) (3,)…(19,)]
[(0,) (1,) (2,) (3,)…(19,)]
…
[(0,) (1,) (2,) (3,)…(19,)] (行坐标)
[(,0) (,1) (,2) (,3)…(,19)]
[(,0) (,1) (,2) (,3)…(,19)]
…
[(,0) (,1) (,2) (,3)…(,19)] (列坐标)
组合成的位置矩阵:
[ (0,0) (1,0) (2,0)…(19,0)]
[ (0,1) (1,1) (2,1)…(19,1)]
[ (0,2) (1,2) (2,2)…(19,2)]
…
[(0,19) (1,19) (2,19)…(19,19)]
reshape过结构为(20*20)的example按位置矩阵的坐标对应入座。然而位置矩阵是正常矩阵的转置形式,比如example的第一行第二点像素(0,1)在位置矩阵相同位置找到的坐标是(1,0),所以会去第二行的第一点组成图像。这么一来,所有的example形成的图像也是转置过的!
然而问题来了,每个数字并没有转置:
原因是:matlab的reshape和python的reshape是不一样的。
matlab的reshape的按列排序,而python的reshape的按行排列!!!!
因此mat格式的每个example(1 * 400)并不是在(20 * 20)的图像依次取一行拼成一行400个点,而是取一列20点依次拼接成400点!
2.代价函数、梯度下降
代价函数
import numpy as np
from Sigmod import sigmod
def costfunction(theta, x, y, mylambda):
m = x.shape[0]
hx = sigmod(np.dot(x, theta))
y = y.flatten()
temp1 = np.multiply(y, np.log(hx))
temp2 = np.multiply(1-y, np.log(1-hx))
temp3 = mylambda / (2 * m) * np.sum(np.power(theta[1:], 2))
cost = -np.mean(temp1 + temp2) + temp3
return cost
梯度下降:
import numpy as np
from Sigmod import sigmod
def gradinet(theta, x, y, mylambda):
m = x.shape[0]
hx = sigmod(np.dot(x, theta))
y = y.flatten()
grad = np.dot(x.T, hx - y)/m
temp = mylambda/m * np.array(theta[1:])
grad[1:] = grad[1:] + temp
return grad
梯度下降注意返回值是一维数组,否则在优化函数传入时会报错
3.分类器的构建
其实就是求10个theta ,每个theta用来计算某个example的是某个数字的概率有多大。
比如,我拿到一个example,用这个example的特征和theta0、theta1…theta9 进行计算,然后得到10个概率,选取概率最大的那个对应分类作为识别的结果。
def onevsall(theta, x, y, num_class, mylambda):
m = num_class
n = x.shape[1]
theta_mat = np.zeros([m, n])
for i in range(m):
if i == 0:
y_this_class = np.where(y == 10, 1, 0)
else:
y_this_class = np.where(y == i, 1, 0)
theta_temp = opt.minimize(fun=costfunction, x0=theta,
args=(x, y_this_class, mylambda), method='TNC', jac=gradinet).x
theta_mat[i, :] = theta_temp
return theta_mat
4.预测模块
对每个example进行识别,计算准确率
import numpy as np
from Sigmod import sigmod
def prediction(theta, x, y):
pred_mat = sigmod(np.dot(x, theta.T))
m, n = pred_mat.shape
pred = np.zeros(m)
for i in range(m):
pred[i] = 0
flag = -1
for j in range(n):
if pred_mat[i, j] > flag:
pred[i] = j
flag = pred_mat[i, j]
if pred[i] == 0:
pred[i] = 10
pred = np.array(pred).reshape([m, 1])
temp = np.where(y == pred, 1, 0)
corret = np.mean(temp)
return corret
theta_train = onevsall(initial_theta, x, y, num_class, lambda_test)
corret = prediction(theta_train, x, y)
print(corret)
结果:96.46 % 的准确率
二、神经网络
1.前向传递、准确率预测
在练习中,已经给出神经网络的参数Theta1、Theta2,只需要利用这两个权重矩阵计算 hx 即可。
前向传递:
import numpy as np
from Sigmod import sigmod
def prediction_nn(theta1, theta2, x, y):
m, n = x.shape
pred = np.zeros(m)
#第二层神经网络的激活因子
z2 = np.dot(theta1, x.T)
a2 = sigmod(z2)
one = np.ones([1, m])
a2 = np.vstack([one, a2])
#第三层神经网络的激活因子
z3 = np.dot(theta2, a2)
hx = sigmod(z3).T
#接下
准确率预测
num_class = hx.shape[1]
for i in range(m):
pred[i] = 0
flag = -1
for j in range(num_class):
if hx[i, j] > flag:
pred[i] = j + 1
flag = hx[i, j]
pred = np.array(pred).reshape([m, 1])
temp = np.where(y == pred, 1, 0)
corret = np.mean(temp)
return corret
结果:
本文地址:https://blog.csdn.net/zsiming/article/details/107633623
上一篇: java字符串反转的7种方法
下一篇: JSP/servlet文件上传
推荐阅读
-
吴恩达 机器学习课程 coursera 第一次编程作业(Linear Regression Multi) python实现
-
吴恩达 机器学习课程 coursera 第二次编程作业(Logistic Regression Regularized) python实现
-
吴恩达老师机器学习第一次作业:梯度下降【python实现】
-
吴恩达 机器学习课程 coursera 第四次编程作业(Neural Network Back Propagation) python实现
-
吴恩达 机器学习课程 coursera 第三次编程作业(Neural Network) python实现
-
吴恩达机器学习作业3:Multi-class Classification and Neural Networks python实现
-
吴恩达机器学习作业3:Multi-class Classification and Neural Networks python实现
-
吴恩达 机器学习课程 coursera 第二次编程作业(Logistic Regression) python实现
-
吴恩达 机器学习课程 coursera 第一次编程作业(Linear Regression) python实现