计算机视觉与机器学习实验报告
1、二维码识别检测
使用OpenCV相关API实现
主要代码
import cv2 as cv
import numpy as np
src = cv.imread("D:/pythonwork/11.jpg")
cv.imshow("image", src)
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
qrcoder = cv.QRCodeDetector()
codeinfo, points, straight_qrcode = qrcoder.detectAndDecode(gray)
print(points)
print(points[0][0])
result = np.copy(src)
#cv.putText(result,'%s'%codeinfo,tuple(points[2][0]),cv.FONT_HERSHEY_SIMPLEX, 0.8,(0, 0, 255))
cv.drawContours(result, [np.int32(points)], 0, (0, 0, 255), 2)
print("qrcode : %s"% codeinfo)
cv.imshow("result", result)
code_roi = np.uint8(straight_qrcode)
cv.imshow("qrcode roi", code_roi)
cv.waitKey(0)
cv.destroyAllWindows()
实验效果

2、高斯模糊
实现高斯模糊图像和高斯滤波性能测试
代码实现
import cv2 as cv
import numpy as np
#均值模糊 使图片模糊
def get_mean_burry(image):
cv.imshow('iamge',image)
dst=cv.blur(image,(5,5))
cv.imshow('burry',dst)
src=cv.imread('D:/pythonwork/33.png')
get_mean_burry(src)
cv.waitKey(0)
cv.destroyAllWindows()
实验效果

3、线性回归
实现简单示例函数
通过代码实现返回一个5*5的对角矩阵
import numpy as np
a = np.eye(5)
a
实验结果

实现数据集显示的函数
对数据集使用散点图进行可视化
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os
%matplotlib inline
# 数据存储路径
path = 'ex1data1.txt'
# 读入相应的数据文件
data = pd.read_csv(path, header=None,names=['Population','Profit'])
#查看数据的前五条
data.head(5)
实验结果

实现数据的可视化
data.plot(kind='scatter', x='Population', y='Profit',c='red', figsize=(12,8))
结果

计算线性回归成本的函数
在执行梯度下降最小化成本函数 𝐽(𝜃) 时,通过计算成本来监视收敛状态是有帮助的。
在该部分练习任务中,你需要实现一个计算成本 𝐽(𝜃) 的函数computeCost,用于检查梯度下降实现的收敛性。
其中,X和y不是标量值,而是矩阵,其行代表训练集中的示例。
主要代码
def computeCost(X, y, theta):
inner = np.power(((X * theta.T) - y), 2)
return np.sum(inner) / (2 * len(X))
theta = np.matrix(np.array([0,0]))
computeCost(X, y, theta)
结果

运行梯度下降的功能函数
接下来,我们将实现梯度下降,给出的代码已经实现了循环结构,你只需要在每次的迭代中提供 𝜃 的更新。
在进行代码实现时,请确保你了解要优化的内容,和正在更新的内容。
请记住,成本 𝐽(𝜃) 为参数-被向量 𝜃 终止,而不是 𝑋 和 𝑦 。也就是说,我们将 𝐽(𝜃) 的值最小化通过改变矢量 𝜃 的值,而不是通过改变 𝑋 或 𝑦 。
验证梯度下降是否正常工作的一种好方法是查看 𝐽(𝜃) 的值,并检查该值每步是否减小。每次迭代时,代码都会调用computeCost函数并打印成本。假设你实现了梯度下降,正确地计算成本, 𝐽(𝜃) 值永远不会增加,并且应该在算法结束时收敛到稳定值。
x = np.linspace(data.Population.min(), data.Population.max(), 100)
f = g[0, 0] + (g[0, 1] * x)
fig, ax = plt.subplots(figsize=(12,8))
ax.plot(x, f, 'b', label='Prediction')
ax.scatter(data.Population, data.Profit, c='red',label='Traning Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')

4、多分类问题
1.3 逻辑回归的向量化
在该部分练习中,你需要将逻辑回归的实现修改为完全向量化(即没有可替换的 𝑓𝑜𝑟 循环)。这是因为向量化代码除了简洁外,还能够利用线性代数优化,并且通常比迭代代码快得多。但是,如果从练习2中看到我们的代价函数已经完全向量化实现了,所以我们可以在这里重复使用相同的实现。
1.3.1 代价函数的向量化
你需要编写代码实现代价函数的向量化。我们已经知道,代价函数是:
𝐽(𝜃)=1𝑚∑𝑖=1𝑚[−𝑦(𝑖)log(ℎ𝜃(𝑥(𝑖)))−(1−𝑦(𝑖))log(1−ℎ𝜃(𝑥(𝑖)))]
为了计算求和中的每个元素,我们需要计算对于每个样本 𝑖 的 ℎ𝜃(𝑥(𝑖)) 。其中,
ℎ𝜃(𝑥)=𝑔(𝜃𝑇𝑋)
并且 sigmoid函数为:
𝑔(𝑧)=11+𝑒−𝑧
事实证明,对于所有例子,我们都可以通过矩阵乘法来快速计算。我们定义 𝑋 和 𝜃 为:
然后,进行矩阵乘法 𝑋𝜃 ,计算得到:
在最后一个等式中,如果 𝑎 和 𝑏 都是向量,我们就可以利用 𝑎𝑇𝑏=𝑏𝑇𝑎 的事实,并且可以在一行代码中计算所有例子的乘积 𝜃𝑇𝑥(𝑖)
def sigmoid(z):
return 1 / (1 + np.exp(-z))
def cost(theta, X, y):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
first = np.multiply(-y, np.log(sigmoid(X * theta.T)))
second = np.multiply((1 - y), np.log(1 - sigmoid(X * theta.T)))
return np.sum(first - second) / len(X)
1.3.2 梯度的向量化
我们知道,要使用梯度下降法令这个代价函数最小化。回顾一下,逻辑回归代价函数的梯度是一个向量,其第 𝑗 个元素定义为 ∂𝐽∂𝜃𝑗=1𝑚∑𝑖=1𝑚[ℎ𝜃(𝑥(𝑖))−𝑦(𝑖)]𝑥(𝑖)𝑗
为了对该操作进行向量化,我们需要把所有 𝜃𝑗 的偏导都写出来:
其中,
注意 𝑥(𝑖) 是一个向量,而 (ℎ𝜃(𝑥(𝑖))−𝑦(𝑖)) 是一个标量(数字)。
𝛽𝑖=(ℎ𝜃(𝑥(𝑖))−𝑦(𝑖)) 可以这么理解:
在对操作进行向量化之后,我们知道可以不需要使用LOOP循环就可以进行偏导的计算。接下来你需要编写代码实现上述代码的向量化形式。
def gradient(theta, X, y):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
parameters = int(theta.ravel().shape[1])
error = sigmoid(X * theta.T) - y
grad = ((X.T * error) / len(X)).T
return grad
1.3.3 正则化逻辑回归的向量化
在练习2中,我们实现正则化逻辑回归算法的代价函数和梯度计算函数。其代价函数为:
𝐽(𝜃)=1𝑚∑𝑖=1𝑚[−𝑦(𝑖)log(ℎ𝜃(𝑥(𝑖)))−(1−𝑦(𝑖))log(1−ℎ𝜃(𝑥(𝑖)))]+𝜆2𝑚∑𝑗=1𝑛𝜃2𝑗
注意不需要对 𝜃𝑜 进行正则化,其用于偏差的计算。 对应地,其梯度的计算公式如下:
𝑅𝑒𝑝𝑒𝑎𝑡 𝑢𝑛𝑡𝑖𝑙 𝑐𝑜𝑛𝑣𝑒𝑟𝑔𝑒𝑛𝑐𝑒 { 𝜃0:=𝜃0−𝑎1𝑚∑𝑖=1𝑚[ℎ𝜃(𝑥(𝑖))−𝑦(𝑖)]𝑥(𝑖)0 𝜃𝑗:=𝜃𝑗−𝑎1𝑚∑𝑖=1𝑚[ℎ𝜃(𝑥(𝑖))−𝑦(𝑖)]𝑥(𝑖)𝑗+𝜆𝑚𝜃𝑗 } 𝑅𝑒𝑝𝑒𝑎𝑡
接下来,你需要编写代码实现正则化逻辑回归算法的代价函数和梯度的向量化实现。
def costReg(theta, X, y, learningRate):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
first = np.multiply(-y, np.log(sigmoid(X * theta.T)))
second = np.multiply((1 - y), np.log(1 - sigmoid(X * theta.T)))
reg = (learningRate / (2 * len(X))) * np.sum(np.power(theta[:,1:theta.shape[1]], 2))
return np.sum(first - second) / len(X) + reg
def gradientReg(theta, X, y, learningRate):
theta = np.matrix(theta)
X = np.matrix(X)
y = np.matrix(y)
parameters = int(theta.ravel().shape[1])
error = sigmoid(X * theta.T) - y
grad = ((X.T * error) / len(X)).T + ((learningRate / len(X)) * theta)
# intercept gradient is not regularized
grad[0, 0] = np.sum(np.multiply(error, X[:,0])) / len(X)
return np.array(grad).ravel()
1.4 多分类-分类器
现在我们已经定义了代价函数和梯度函数,现在我们需要构建一个分类器。对于手写字识别,我们有10个可能的类(0-9),但逻辑回归是一个二分类问题。
在本练习中,你的任务是实现一对一全分类方法,其中具有 𝑘 个不同类的标签就有 𝑘 个分类器,每个分类器在“类别 𝑖 ”和“不是 𝑖 ”之间决定。我们将把分类器训练包含在一个函数中,该函数计算10个分类器中的每个分类器的最终权重,并将权重返回为 [𝑘,𝑛+1] 的数组,其中 𝑛 是参数数量。
需要注意的是:
需要添加 𝜃0 以计算截距项。
将 𝑦 从类标签转换为每个分类器的二进制(要么是类i,要么不是类i)。
使用scipy库的优化类的minimize函数来最小化每个分类器的代价函数。
将寻找到的最优参数分配给参数数组,并返回形状为 [𝑘,𝑛+1] 的参数数组。
其中,实现向量化代码最重要的地方是要保证正确地写入所有的矩阵,保证其维度正确。
from scipy.optimize import minimize
def one_vs_all(X, y, num_labels, learning_rate):
rows = X.shape[0]
params = X.shape[1]
# k个分类器的参数,形状为(k,n+1)
all_theta = np.zeros((num_labels, params + 1))
# 插入值为1的列,用于计算截距项
X = np.insert(X, 0, values=np.ones(rows), axis=1)
# 将分类标签转换为0-1标识
for i in range(1, num_labels + 1):
theta = np.zeros(params + 1)
y_i = np.array([1 if label == i else 0 for label in y])
y_i = np.reshape(y_i, (rows, 1))
# 使用minimize函数最小化代价函数
fmin = minimize(fun=costReg, x0=theta, args=(X, y_i, learning_rate), method='TNC', jac=gradientReg)
all_theta[i-1,:] = fmin.x
return all_theta
我们来检查下需要初始化的变量,以及变量的形状:
rows = data['X'].shape[0]
params = data['X'].shape[1]
all_theta = np.zeros((10, params + 1))
X = np.insert(data['X'], 0, values=np.ones(rows), axis=1)
theta = np.zeros(params + 1)
y_0 = np.array([1 if label == 0 else 0 for label in data['y']])
y_0 = np.reshape(y_0, (rows, 1))
X.shape, y_0.shape, theta.shape, all_theta.shape
实验结果

1.5 使用分类器进行预测
我们现在准备好最后一步,你需要使用训练完毕的分类器预测每个图像的标签。
对于这一步,我们将计算每个类的类概率,对于每个训练样本(使用向量化代码),并将输出类标签为具有最高概率的类。
def predict_all(X, all_theta):
rows = X.shape[0]
params = X.shape[1]
num_labels = all_theta.shape[0]
# 与之前一样,需要插入一列确保矩阵形状
X = np.insert(X, 0, values=np.ones(rows), axis=1)
# 将其转换为矩阵
X = np.matrix(X)
all_theta = np.matrix(all_theta)
# 计算每个训练样本所属每个类别的概率
h = sigmoid(X * all_theta.T)
# 创建具有最大概率的索引数组
h_argmax = np.argmax(h, axis=1)
# 因为我们的数组是零索引的,所以我们需要为真正的标签预测+1
h_argmax = h_argmax + 1
return h_argmax
y_pred = predict_all(data['X'], all_theta)
correct = [1 if a == b else 0 for (a, b) in zip(y_pred, data['y'])]
accuracy = (sum(map(int, correct)) / float(len(correct)))
print ('accuracy = {0}%'.format(accuracy * 100))
实验结果

更多推荐

所有评论(0)