SVM人脸识别

数据读取

给出的数据是mat格式存储的,19*19的灰度值,所以用loadmat就能直接读出

from scipy.io import loadmat

train_data = loadmat('task2/train(Task2)/train_data.mat')
train_label = loadmat('task2/train(Task2)/train_label.mat')
train_data = train_data.get('train_data')
train_label = train_label.get('train_label')


test_data = loadmat('task2/test(Task2)/test_data_2.mat')
test_data = test_data.get('test_data')

增强训练集

给出的训练集只有800个样本,想要在测试集上得到很好的效果是不可能的,所以先对训练集进行增强。

简单看了下训练集和测试集,人脸朝向都是一致的,所以不用做旋转增强,就做了上下翻折和缩放处理。

train_data_crop1 = []
train_data_crop2 = []
train_data_transpose = []
for img in train_data:
    img = img.reshape(19,19)
    img = np.array(img)

    # 缩放
    img_1 = img
    img_1[0] = 0
    img_1[18] = 0
    for i in img_1:
        i[0] = 0
        i[18] = 0
    img_crop1 = img_1.reshape(361)
    train_data_crop1.append(img_crop1)

    img_2 = img
    img_2[0] = 0
    img_2[1] = 0
    img_2[18] = 0
    img_2[17] = 0
    for i in img_2:
        i[0] = 0
        i[1] = 0
        i[18] = 0
        i[17] = 0
    img_crop2 = img_2.reshape(361)
    train_data_crop2.append(img_crop2)

    # 上下翻折
    img = Image.fromarray(img)
    img_transpose = img.transpose(Image.FLIP_TOP_BOTTOM)
    img_transpose = np.array(img_transpose)
    img_transpose = img_transpose.reshape(361)
    train_data_transpose.append(img_transpose)

train_data_transpose = np.array(train_data_transpose)
train_data_crop1 = np.array(train_data_crop1)
train_data_crop2 = np.array(train_data_crop2)


train_data_enlarge = np.vstack((train_data, train_data_transpose))
train_data_enlarge = np.vstack((train_data_enlarge, train_data_crop1))
train_data_enlarge = np.vstack((train_data_enlarge, train_data_crop2))


train_label_enlarge = train_label
train_label_enlarge = np.vstack((train_label_enlarge, train_label))
train_label_enlarge = np.vstack((train_label_enlarge, train_label))
train_label_enlarge = np.vstack((train_label_enlarge, train_label))

SVM训练

要求是用libsvm进行训练,但是sklearn里面的svm模块更好用,所以就先用sklearn里面的svm训练,找到最佳参数就在换成libsvm。

parameters={'C':np.linspace(0.0001,10,20),'gamma':np.linspace(0.0001 ,5,20)}
svc = svm.SVC(kernel='poly')
model = GridSearchCV(svc, parameters, cv=5, scoring='accuracy', n_jobs=-1)
model.fit(train_data, train_label)
result = model.best_params_

但实际上网格搜索到的参数虽然在训练集和交叉验证上的表现都很好,但是在测试集上表现不尽人意,所以最后还是凑出来c = 0.1, gamma = 0.1 的时候最好。

用libsvm实现

# 数据格式转化
index = []
train = []
test = []
label = []
for i in range(1,362):
    index.append(i)
for item in train_data:
    data = dict(zip(index, item))
    train.append(data)
for item in test_data:
    data = dict(zip(index, item))
    test.append(data)
for i in train_label:
    label.append(i)

# 网格搜索最佳参数
acc = []
C = []
G = []
for i in range(-5,5):
    for j in range(-5,5):
        c = 10**i
        gamma = 10**j
        prob = svm_problem(label, train)
        param = svm_parameter('-s 0 -t 2 -c '+ str(c) +' -g '+ str(gamma) +' -v 10')
        model = svm_train(prob, param)
        acc.append(model)
        C.append(c)
        G.append(gamma)

dir = acc.index(max(acc))
best_c = C[dir]
best_g = G[dir]
accuracy = acc[dir]

# 测试集预测
best_param = svm_parameter('-s 0 -t 2 -c '+str(best_c)+' -g '+str(best_g))
best_model = svm_train(prob, best_param)

p_label, p_acc, p_val = svm_predict([], test, best_model)

print(p_label)

输出

用给出的demo得到测试集标签(代码有点杂)

# coding=utf-8
"""
This is the submission demo  for the task 2.
"""
from libsvm.svmutil import svm_predict
import numpy as np 
import os
from sklearn import svm
from scipy.io import loadmat
from sklearn.neural_network import MLPClassifier
from PIL import Image
from libsvm.svm import *
from libsvm.svmutil import *


#output task2_result.txt

train_data = loadmat('task2/train(Task2)/train_data.mat')
train_label = loadmat('task2/train(Task2)/train_label.mat')
train_data = train_data.get('train_data')
train_label = train_label.get('train_label')


test_data = loadmat('task2/test(Task2)/test_data_2.mat')
test_data = test_data.get('test_data')

train_data_crop1 = []
train_data_crop2 = []
train_data_transpose = []
for img in train_data:
    img = img.reshape(19,19)
    img = np.array(img)

    # 缩放
    img_1 = img
    img_1[0] = 0
    img_1[18] = 0
    for i in img_1:
        i[0] = 0
        i[18] = 0
    img_crop1 = img_1.reshape(361)
    train_data_crop1.append(img_crop1)

    img_2 = img
    img_2[0] = 0
    img_2[1] = 0
    img_2[18] = 0
    img_2[17] = 0
    for i in img_2:
        i[0] = 0
        i[1] = 0
        i[18] = 0
        i[17] = 0
    img_crop2 = img_2.reshape(361)
    train_data_crop2.append(img_crop2)

    # 上下翻折
    img = Image.fromarray(img)
    img_transpose = img.transpose(Image.FLIP_TOP_BOTTOM)
    img_transpose = np.array(img_transpose)
    img_transpose = img_transpose.reshape(361)
    train_data_transpose.append(img_transpose)

train_data_transpose = np.array(train_data_transpose)
train_data_crop1 = np.array(train_data_crop1)
train_data_crop2 = np.array(train_data_crop2)


train_data_enlarge = np.vstack((train_data, train_data_transpose))
train_data_enlarge = np.vstack((train_data_enlarge, train_data_crop1))
# train_data_enlarge = np.vstack((train_data_enlarge, train_data_crop2))


train_label_enlarge = train_label
train_label_enlarge = np.vstack((train_label_enlarge, train_label))
train_label_enlarge = np.vstack((train_label_enlarge, train_label))
# train_label_enlarge = np.vstack((train_label_enlarge, train_label))
def store_txt(label,result_txt):
    """
    :param label: list of your classification labels
    :param result_txt: output file
    :return:
    """
    with open(result_txt,"w") as w:
        for index,result in enumerate(label,1):
            w.write(str(index)+" "+str(result)+"\n")   #  imageID(int)+" "+label(-1\1,int)+"\n"
# example main function
def main():
    label = svm_train()
    # label = mlp_train()
    label[label==0] = -1
    store_txt(label,'task2_svm_result.txt')

def svm_train():

    # model = svm.SVC(kernel='poly', C=0.1,coef0=3,degree=3,gamma=0.1)    #0.797
    # model = svm.SVC(kernel='linear')     0.769
    # model = svm.SVC(kernel='rbf', C=0.1, gamma=0.01)

    # model.fit(train_data_enlarge, train_label_enlarge)
    # score = model.score(train_data_enlarge, train_label_enlarge)
    prob = svm_problem(train_label_enlarge, train_data_enlarge)
    param = svm_parameter('-s 0 -t 2 -c 0.1 -g 0.1')
    model = svm_train(prob, param)
    p_label, p_acc, p_val = svm_predict([], test_data, model)

    # model.fit(train_data, train_label)
    # score = model.score(train_data, train_label)
    # print(score)
    # #Predict Output
    # predicted = model.predict(test_data)
    return p_label

def mlp_train():
    model = MLPClassifier(activation='logistic', solver='lbfgs', alpha=1e-5,hidden_layer_sizes=(5,), random_state=None , batch_size=200)
    model.fit(train_data, train_label)
    predict = model.predict(test_data)
    return predict

if __name__ == "__main__":
    main()           
    

最后在网站上提交,0.902准确度,排名第三,还行。

##小道消息老师给出的训练集有4张图片故意给错了,但是因为懒所以懒得去找了

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值