Répertoire d'articles
Ecrire devant
Ce blog est un enregistrement des travaux de reconnaissance de formes, qui implémente l'algorithme de perceptron par lots, l'algorithme Ho Kashyap et la méthode d'extension multi-classes MSE, veuillez vous référer au manuel [1] \ color {# 0000FF} {[1]}[ 1 ] . Les données utilisées sont les suivantes:
Algorithme de perceptron par lots
De a = 0 \ mathbf a = 0une=Commencer l'itération à 0 , classerω 1 \ omega_1ω1Et ω 2 \ omega_2ω2Et calculez le vecteur de solution finale, enregistrez le nombre d'étapes de convergence.
"""批感知器算法"""
import matplotlib.pyplot as plt
import numpy as np
import math
data = np.loadtxt('data.txt')
trn_data1 = data[0:20, 0:2] # 问题一(1)
trn_lable1 = data[0:20, 2]
# trn_data1 = data[10:30, 0:2] # 问题一(1)
# trn_lable1 = data[10:30, 2]
plt.scatter(trn_data1[0:10, 0], trn_data1[0:10, 1], color='blue', marker='o', label=''r'$\omega_1$')
plt.scatter(trn_data1[10:20, 0], trn_data1[10:20, 1], color='red', marker='x', label=''r'$\omega_2$')
plt.xlabel(''r'$x_1$')
plt.ylabel(''r'$x_2$')
plt.legend(loc='upper left')
plt.title('Original Data')
plt.show()
X = np.hstack((np.ones((trn_data1.shape[0], 1)), trn_data1))
X1 = X[0:10, :]
X2 = -1 * X[10:20, :]
X = np.vstack((X1, X2)) # 规范化增广样本
w = np.zeros((3, 1), dtype='float32')
step = 0
for i in range(100):
if i == 0:
y_pred = np.where(np.dot(X, w) == 0)[0] # 统计分类错误的点数
else:
y_pred = np.where(np.dot(X, w) < 0)[0]
step += 1
print('第%2d次更新,分类错误的点个数:%2d' % (step, len(y_pred)))
if len(y_pred) > 0:
w += (np.sum(X[y_pred, :], axis=0)).reshape((3, 1))
else:
break
print('解向量为:', w)
x1 = np.array([-5, 8])
x2 = -1 * (w[1]*x1 + w[0])/w[2]
plt.scatter(trn_data1[0:10, 0], trn_data1[0:10, 1], color='blue', marker='o', label=''r'$\omega_1$')
plt.scatter(trn_data1[10:20, 0], trn_data1[10:20, 1], color='red', marker='x', label=''r'$\omega_2$')
plt.plot([x1[0], x1[1]], [x2[0], x2[1]], 'black')
plt.xlabel(''r'$x_1$')
plt.ylabel(''r'$x_2$')
plt.legend(loc='upper left')
plt.title('classified Data')
plt.show()
L'algorithme converge dans la 24ème mise à jour, et le vecteur solution a = (34.0, - 30.4, 34.1) \ mathbf {a} = (34.0, −30.4, 34.1)une=( 3 4 . 0 ,- 3 0 . 4 ,3 4 . 1 )
Arithmétique Ho Kashyap
"""Ho Kashyap算法"""
import matplotlib.pyplot as plt
import numpy as np
import math
data = np.loadtxt('data.txt')
trn_data1 = data[0:10, 0:2] # 问题二(1)
trn_lable1 = data[0:10, 2]
temp = data[20:30, 0:2]
temp_lb = data[20:30, 2]
# trn_data1 = data[10:20, 0:2] # 问题二(2)
# trn_lable1 = data[10:20, 2]
# temp = data[30:40, 0:2]
# temp_lb = data[30:40, 2]
trn_data = np.vstack((trn_data1, temp))
trn_lable = np.vstack((trn_lable1, temp_lb))
# print(trn_data.shape, '\n', trn_lable.shape)
# print(trn_data)
plt.scatter(trn_data[0:10, 0], trn_data[0:10, 1], color='blue', marker='o', label=''r'$\omega_2$')
plt.scatter(trn_data[10:20, 0], trn_data[10:20, 1], color='red', marker='x', label=''r'$\omega_4$')
plt.xlabel(''r'$x_1$')
plt.ylabel(''r'$x_2$')
plt.legend(loc='upper left')
plt.title('Original Data')
plt.show()
X = np.hstack((np.ones((trn_data.shape[0], 1)), trn_data))
X1 = X[0:10, :]
X2 = -1 * X[10:20, :]
X = np.vstack((X1, X2)) # 规范化增广样本
w = np.random.randn(3, 1)
b = np.random.rand(X.shape[0], 1)
eta = 0.1
MAX_iteration = 1000
step = 0
acc = 0
for i in range(MAX_iteration):
e = np.dot(X, w) - b
e_p = 0.5 * (e + abs(e))
eta_k = eta/(i+1)
# if (e == 0).all():
if max(abs(e)) <= min(b):
print(e)
break
else:
b += 2 * eta_k * e_p
Y_p = np.linalg.pinv(X)
w = np.dot(Y_p, b)
step += 1
acc = (np.sum(np.dot(X, w) > 0)) / X.shape[0]
print('第%2d次更新, 分类准确率%f' % (step, acc))
# print(e, '\n')
if step == MAX_iteration and acc != 1:
print("未找到解,线性不可分!")
x1 = np.array([-8, 8])
x2 = -1 * (w[1]*x1 + w[0])/w[2]
plt.scatter(trn_data[0:10, 0], trn_data[0:10, 1], color='blue', marker='o', label=''r'$\omega_2$')
plt.scatter(trn_data[10:20, 0], trn_data[10:20, 1], color='red', marker='x', label=''r'$\omega_4$')
plt.plot([x1[0], x1[1]], [x2[0], x2[1]], 'black')
plt.xlabel(''r'$x_1$')
plt.ylabel(''r'$x_2$')
plt.text(3, -2, 'Accuracy: %.3f' % acc)
plt.legend(loc='upper left')
plt.title('classified Data')
plt.show()
Méthode d'extension multi-classes MSE
Calculez d'abord le poids W en fonction de l'échantillon d'apprentissage, puis calculez la valeur prédite en fonction de ce poids et de l'échantillon de test, et prenez l'argmax pour obtenir l'étiquette de sortie finale, de sorte que le taux de précision de classification soit de 100%.
"""MSE多类扩展方法"""
import numpy as np
data = np.loadtxt('data.txt')
train_data = []
train_label = []
test_data = []
test_label = []
# 数据预处理
for i in [0, 10, 20, 30]:
temp_data = data[i:i+8, 0:2]
temp_label = data[i:i+8, 2]
train_data.append(temp_data)
train_label.append(temp_label)
test_data.append(data[i+8:i+10, 0:2])
test_label.append(data[i+8:i+10, 2])
train_data = np.array(train_data).reshape((32, 2))
train_label = np.array(train_label).reshape(-1).astype(int) - 1
test_data = np.array(test_data).reshape((8, 2))
test_label = np.array(test_label).reshape(-1).astype(int) - 1
train_label = np.eye(4)[train_label] # 32x4大小,one-hot向量矩阵
test_label = np.eye(4)[test_label] # 8x4大小
train_data = np.hstack((train_data, np.ones((train_data.shape[0], 1))))
test_data = np.hstack((test_data, np.ones((test_data.shape[0], 1))))
print(train_data.shape, train_label.shape)
print(test_data.shape, test_label.shape)
train_data = train_data.T # 按照课件的公式调整数据维度
train_label = train_label.T
test_data = test_data.T
test_label = test_label.T
print(train_data.shape, train_label.shape)
print(test_data.shape, test_label.shape)
lam = 1e-9
temp = np.linalg.inv(np.dot(train_data, train_data.T) + lam)
W = np.dot(np.dot(temp, train_data), train_label.T) # 3x4维
y_pred = np.dot(W.T, test_data)
index = np.argmax(y_pred, axis=0) # 得到每个样本对应类别的值最大的索引
y_pred = np.eye(y_pred.shape[0])[index].T # 转换为one-hot向量
wrong_num = sum(sum(y_pred - test_label))
acc = (1 - wrong_num / len(test_label)) * 100
print('分类正确率为:%.2f%% ' % acc)
Réf.
[1] Richard O. Duda. Classification des modèles [M]. Traduit par Li Hongdong et autres. China Machinery Industry Press, CITIC Press, 2003.