一、Multi-class Classification
可视化直接抄了大佬代码,多分类,根本上就是多个二分类逻辑回归
ML_exe03_MultiClass.py
import numpy as np
import scipy.io as sio #加载matlab的数据
from plotData import *
from oneVsAll import *
from predictOneVsAll import *
#加载训练集数据
data = sio.loadmat('ex3data1.mat')
X=data['X']
y = data['y']
#10-0
y = y%10
#样本数量
m = X.shape[0]
#随机取图片的index可视化(low,high]
rand = np.random.randint(low=0,high=m,size=100,dtype=int)
#得到index对应的样本
sample = X[rand,:]
#可视化随机样本
displayData(sample)
#计算theta
lamd = 0.3
#label的数量
labels = 10
#计算所有的theta
thetas = oneVsAll(X,y,labels,lamd)
#预测
prediction = predictOneVsAll(thetas,X)
acRate = np.mean(prediction == y.flatten())*100
print("AC rate:",acRate,'%')
plotData.py
import numpy as np
import matplotlib.pyplot as plt
#显示图片数据
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()
sigmoid.py
import numpy as np
def sigmoid(z):
return 1/(1+np.exp(-z))
costFunction.py
import numpy as np
from sigmoid import *
#cost计算函数
def costFunction(theta, X, y, lamb):
#向量成矩阵
theta = np.array(theta).reshape((np.size(theta), 1))
#样本数
m = y.shape[0];
#计算sigmod
h = sigmoid(np.dot(X, theta))
# 正则化项去掉theta 0
theta2 = theta[1:, 0]
#计算J
J = 1/m*(-np.dot(y.T, np.log(h)) - np.dot((1-y.T), np.log(1-h)))+lamb/(2*m)*np.dot(theta2,theta2)
#矩阵铺平成向量
return J.flatten()
#求梯度
def gradient(theta, X, y, lamb):
#向量成矩阵
theta = np.array(theta).reshape((np.size(theta), 1))
# 样本数
m = y.shape[0];
h = sigmoid(np.dot(X, theta))
# 正则化项去掉theta 0
theta[0, 0] = 0
grad = 1/m*np.dot(X.T, h - y)+lamb/m*theta
# 矩阵铺平成向量
return grad.flatten()
oneVsAll.py
import numpy as np
import scipy.optimize as op
from costFunctino import *
#计算多个分类模型的theta
def oneVsAll(x,y,lables,lamd):
#样本数量
m = x.shape[0]
#特征数量
n = x.shape[1]
#所有的theta,行数为二分类theta的数量,列数为label数量+1
thetas = np.zeros((lables,n+1))
#插入x0特征
# x = np.c_[np.ones(m),x]
x = np.insert(x, 0, values=np.ones(m), axis=1)
#每一个label训练出一套theta
for i in range(0,lables):
#初始theta,加上theta0
initial_theta = np.zeros(n+1)
#y=(y==i)会报错,因为y一直在变,会影响下一次迭代结果
ynew = (y==i)
#得出最优解
result = op.minimize(fun=costFunction,x0=initial_theta,args=(x,ynew,lamd),method='TNC',jac=gradient)
#将该部分theta加入所有的theta中
thetas[i,:] = result.x
return thetas
predictOneVsAll.py
import numpy as np
from sigmoid import *
#计算准确率
def predictOneVsAll(thetas,x):
#测试集数量
m = x.shape[0]
#labels的数量
labels = thetas.shape[0]
#存储测试集在各个二分类模型中的结果
result_all = np.zeros((m,labels))
#存储最后的结果
result = np.zeros((m,1))
#测试集插入x0
x = np.insert(x, 0, values=np.ones(m), axis=1)
for label in range(0,labels):
result_all[:,label] = sigmoid(np.dot(x,thetas[label,:].T))
#统计函数,得到每行的最大值
result = result_all.argmax(axis=1)
#将矩阵展开成向量
return result.flatten()
二、Neural Networks
已知神经网络参数,只是模拟正向传播而已
- ML_exe03_NN.py 主运行程序,load数据,预测,可视化
- nnPlotData.py 可视化
- predict.py 预测
- sigmoid.py 激活函数
ML_exe03_NN.py
import scipy.io as scio
import numpy as np
from predict import *
from nnPlotData import *
#加载训练数据
data = scio.loadmat('ex3data1.mat')
X = data['X']
y = data['y']
#样本数量
m = y.shape[0]
#加载神经网络theta数据
theta = scio.loadmat('ex3Weights.mat')
#第一层的网络参数
theta1 = theta['Theta1']
#第二层的网络参数
theta2 = theta['Theta2']
#预测
result = predict(theta1,theta2,X)
print('AC Rate:',np.mean(result==y.flatten())*100,'%')
#识别单张图片
for i in range(0, m):
#随机挑选一张样本下标
it = np.random.randint(0, m, 1)
#可视化该图片
plotData(X[it[0]:it[0]+1, :])
#预测结果
result = predict(theta1, theta2, X[it[0]:it[0]+1, :])
print('Neural Network Prediction:', result)
print('input q to exit:')
c = input()
if c == 'q':
break
nnPlotData.py
import matplotlib.pyplot as plt
import numpy as np
#显示图片数据
def plotData(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()
predict.py
from sigmoid import *
import numpy as np
#预测
def predict(theta1,theta2,X):
#样本数量
m = X.shape[0];
#第二层计算,插入一列X0
X = np.insert(X,0,np.ones(m),axis=1)
#计算隐藏层unit,sigmoid作为激活函数
a2 = sigmoid(np.dot(X,theta1.T))
#第三层计算,插入偏移单元
a2 = np.insert(a2,0,np.ones(a2.shape[0]),axis=1)
#计算输出层unit,sigmoid作为激活函数
a3 = sigmoid(np.dot(a2,theta2.T))
# 0~9====1~10
p = a3.argmax(axis=1) +1
#矩阵展开成向量
return p.flatten()
sigmoid.py
import numpy as np
def sigmoid(z):
return 1/(1+np.exp(-z))