机器学习的本质:从大量数据里提取出特征与相应的类别产生联系,该类别称之为标签,也就是说使得特征与对应的标签产生对应关系,从而具有识别的能力。
分类和聚类分类是已知物体的类别的标签,聚类则是数据处于无标签状态,我们把具有相似特征的物体归为同一类。分类是有监督的学习,有标签(预设标准答案);聚类是无监督的学习,无标签。
文章图片
SVM(Support Vector Machine)支持向量机:是机器学习里非常常见的算法,其本质是把两个不同类别的数据样本,通过找到一条理想中的最优超平面,(一个面是一条线,三维是一个面,如果是高维的则需要找到一个最优的超平面)使得后续的数据添加进来后仍然可以划分数据。理想中是找到两类数据中最中间的分界线,以上图为例,找到最接近的红点和蓝点,然后从他们中间找到最优的平面,这样的两个点称为支持向量。
文章图片
但如果是这种情况则很难找到一条线对红点蓝点进行划分。则我们需要把这样的二维问题映射到高维的空间中。
文章图片
比如可以想象:这里有一张桌子,红点和蓝点都可以从桌子上跳起来,蓝点比较沉,则跳的就很低,红点很轻,跳的比较高,通过这种方式,我们就可以很轻松的找到一条线,再次把红蓝点区分开来。遇到线性不可分的问题时,我们通常把这样的问题通过核函数映射到高维空间,只要维度够高,所有的问题都可以进行线性划分。
文章图片
二维映射到三维的例子
文章图片
那么此时如果数据中再加入两个未知颜色的点,则位于线的上方我们就把其归于蓝色,位于线的下方则把其归于红色。
计算超平面的方法如下,其具体的数学分析我们会在下一章节描述。
文章图片
文章图片
文章图片
大体思路是先根据支持向量找到两个超平面,然后寻找中间的目标超平面,根据拉格朗日的对偶问题求解超平面的参数值。具体推导过程下一章节中讲。
warnings.filterwarnings("ignore")
PICTURE_PATH="C:\"
def get_Image():
for i in range(1,41):
for j in range(1,11):
path=PICTURE_PATH+"\\s"+str(i)+"\\"+str(j)+".pgm"
img=mpimg.imread(path)
h,w=img.shape
img_col=img.reshape(h*w)
all_data_set.append(img_col)
all_data_label.append(i)
return h,w
all_data_set=[]
all_data_label=[]
h,w=get_image()
x=array(all_data_set)
y=array(all_data_label)
n_samples,n_features=X.shape
n_classes=len(unique(y))
target_names=[]
for i in range(1,41)
names="person"+str(i)
target_names.append(names)
print("Total dataset size:")
print("n_samples:%d"%n_samples)
print("n_features:%d"%n_features)
print("n_classes:%d"%n_classes)`
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.25,random_state=42)
n_components=10
print("Extracting the top %d eigenfaces from d% faces"%(n_components,X_train.shape[0]))
t0=time()
pca=PCA(n_components=n_components,svd_solver='randomized',whiten=True).fit(X_train)
print("done in %0.3fs"%(time()-t0))
eigenfaces=pca.components_.reshape((n_components,h,w))
print("Projecting the input data on the eigenfaces orthonormal basics")
t0=time
X_train_pca=pca.transform(X_train)
X_test_pca=pca.transform(X_test)
print("done in %0.3fs"(time()-t0))
print("Fitting the classifier to the training set")
t0=time()
param_grid={'C':[1e3,5e3,1e4,5e4,1e5],
'gamma':[0.0001,0.0005,0.001,0.005,0.01,0.1],}
clf=GridSearchCV(SVC(kernel='rbf',class_weight='balanced'),param_grid)
clf=clf.fit(X_train_pca,y_train)
print("done in %0.3fs"%(time()-10))
print("Best estimator found by grid search:")
print(clf.best_estimator_)
print("Predicting people's names on test set")
t0=time()
y_pred=clf.predict(X_test_pca)
print("done in %0.3"%(time()-10))
print(classification_report(y_test,y_pred,target_names=target_names))
print(confusion_matrix(y_test,y_pred,labels=range(n_classes)))
def plot_gallery(images,titles,h,w,n_row=3,n_col=4):
plt.figure(figsize=(1.8*n_col,2.4*n_row))
plt.subplot_adjust(bottom=0,left=.01,right=.99,top=.90,hspace=.35)
for i in range(10):
plt.subplot(n_row,n_col,i+1)
plt.imshow(images[i].reshape((h,w)),cmap=plt.cm.gray)
plt.title(title[i].size=12)
plt.xticks(())
plt.yticks(())
def title(y_pred,y_test,target_names,i)
pred_name=target_names[y_pred[i]-1]
true_name=target_names[y_test[i]-1]
retuen 'predicted: %s\ntrue:%s' % (pred_name,true_name) 'prediction_titles=[title(y_pred,y_test,target_names,i)
for i in range(y_pred.shape[0])]
plot_gallery(X_test,prediction_titles,h,w)eigenface_titles=["eigenface %d" % i for i in range(eigenfaces,shape[0])]
plot_gallery(eigenfaces,eigenface_titles,h,w)
ply.show()
【SVM实现人脸识别(超详细易懂)(一)】代码如上
代码部分解析
y是图像的标签,添加图形数字矩阵和特征,并最图像进行一个数据统计:图像张数,特征,多少类
*X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.25,random_state=42)
*根据图像和对应标签划分为训练集和测试集,测试集所占的比重为25%
eigenfaces=pca.components_.reshape((n_components,h,w))
文章图片
对图像做主成分分析生成很多特征脸,我们可以认为每一张图像都是由特征脸叠加而成的,特征脸是根据图像进行主成分分析得到的,可以理解为每个人脸的一些特征,将这些特征叠加起来就可以得到一张清晰的人脸。通过主成分分析,我们可以抽取每一张图像的特征脸
*X_train_pca=pca.transform(X_train)
X_test_pca=pca.transform(X_test)
然后把图像根据特征脸做转化提取里面的特征。
param_grid={‘C’:[1e3,5e3,1e4,5e4,1e5],
‘gamma’:[0.0001,0.0005,0.001,0.005,0.01,0.1],}
设置SVM里的必要参数,C是惩罚系数,gamma是学习值,即允许的间隔值
clf=GridSearchCV(SVC(kernel=‘rbf’,class_weight=‘balanced’),param_grid)
通过网格搜索的方式,调整SVC(SVM分类器),C和gamam的组合有56=30个,那么我们现在希望找到一个最好的参数组合,使得SVM表示最好,所以网格搜索就是一个一个实验30个组合得到的参数运行程序,观察哪一种组合的表现是最好的,从而得到最优的超参数。
clf=clf.fit(X_train_pca,y_train)
得到最优超参数后训练我们的模型,将训练集得到的特征和与之对应的标签放进模型中训练,此时模型就可以找到一个对于这部分训练数据来说最优的超平面clf.best_estimator_。
找到之后我们用得到的最优超平面去预测测试集的特征
y_pred=clf.predict(X_test_pca)
每一个测试集的特征,与之对应的都会给出一个y_pred预测的结果。
print(classification_report(y_test,y_pred,target_names=target_names))
将预测的结果输出就会得到一个预测的准确率
文章图片
预测结果和准确率表示
def plot_gallery(images,titles,h,w,n_row=3,n_col=4)
画图的函数,首先生成界面plt.subplot_adjust(bottom=0,left=.01,right=.99,top=.90,hspace=.35)
挨个展示图像和预测值(title为预测值)pred_name是预测值,true_name是真实的标签
prediction_titles=[title(y_pred,y_test,target_names,i)
for i in range(y_pred.shape[0])]
plot_gallery(X_test,prediction_titles,h,w)
展示预测值
eigenface_titles=[“eigenface %d” % i for i in range(eigenfaces,shape[0])]
展示了一部分特征脸
代码为纯手打,因此可能有很多bug,建议仔细调试后再使用