思路:从训练集当中选取一部分作为验证集,对于剩下的训练集,进行多次迭代,每次使用一定量的样本进行训练,用验证集进行测试,从而确定好超参数。确定了超参数之后,用所有的训练集开始进行训练,思路和之前的类似,迭代一定的次数,每次选取一定量的数据进行训练。在训练结束之后,利用测试集进行测试即可,具体实现见如下代码,准确率基本稳定在35%左右,比knn的方法要好。
import numpy as np
import pickle as pic
class svm:
weight=[]
delta=1
l_rate, reg = 0, 0
def readData(self,file):
with open(file,'rb') as fo:
dict=pic.load(fo,encoding='bytes')
return dict
def getTrainGrad(self,amount,cur_data,cur_label,reg):##
score=self.weight.dot(cur_data.T)
correct_score=score[cur_label,range(amount)]
score=score-correct_score+self.delta
score=np.maximum(score,0)
score[cur_label,range(amount)]=0
score[score>0]=1
sum_score=np.sum(score,axis=0)
score[cur_label,range(amount)]-=sum_score
gred=score.dot(cur_data)/amount+reg*self.weight
return gred
def getPrecision(self,data,label):
score=self.weight.dot(data.T)
res=np.argmax(score,axis=0)
return np.mean(res==label)
def getGoodParameter(self,learning,regu,amount,iteration,
total_train,train_data,train_label,validate_data,validate_label):##
self.weight=0.001*np.random.randn(10,3073)
for i in range(0,iteration):
sample_ind=np.random.choice(total_train,amount,replace=False)
cur_train_data=train_data[sample_ind,:]
cur_train_label=train_label[sample_ind]
gred1=self.getTrainGrad(amount,cur_train_data,cur_train_label,regu)
self.weight=self.weight-gred1*learning
return self.getPrecision(validate_data,validate_label)
def final_train(self,train_data,train_label,total_train,amount,iteration):
for i in range(0,iteration):
sample_ind = np.random.choice(total_train,amount, replace=False)
cur_train_data = train_data[sample_ind, :]
cur_train_label = train_label[sample_ind]
gred1=self.getTrainGrad(amount,cur_train_data,cur_train_label,self.reg)
self.weight = self.weight - gred1 * self.l_rate
def Test_2(self,path_train,path_test):
train_data,train_label,test_data,test_label=[],[],[],[]
for i in range(1,6):
cur_path=path_train+str(i)
read_infor=self.readData(cur_path)
if i==1:
train_data=read_infor[b'data']
train_label=read_infor[b'labels']
else:
train_data=np.append(train_data,read_infor[b'data'],axis=0)
train_label+=read_infor[b'labels']
mean_image=np.mean(train_data,axis=0)
train_data=train_data-mean_image#预处理
read_infor=self.readData(path_test)
train_label=np.array(train_label)
test_data=read_infor[b'data']#测试数据集
test_label=np.array(read_infor[b'labels'])#测试标签
test_data = test_data - mean_image # 预处理
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))])
amount_train=train_data.shape[0]
amount_validate=20000;
amount_train-=amount_validate
validate_data=train_data[amount_train:,:]#验证数据集
validate_label=train_label[amount_train:]#验证标签
train_data=train_data[:amount_train,:]#训练数据集
train_label=train_label[:amount_train]#训练标签
learning=[1e-7,1e-6,1e-5]
regu=[6,7,8,9,10]
res_learning,res_reg=0,0
pre=-1
for i in learning:
for j in regu:
precision=self.getGoodParameter(i,j,200,1500,amount_train,
train_data,train_label,validate_data,validate_label)
print(precision)
if(precision>pre):
pre=precision
self.l_rate=i
self.reg=j
print("result: "+str(pre)+" "+str(self.l_rate)+" "+str(self.reg))
print("Start Training!")
self.weight = 0.001 * np.random.randn(10, 3073)
final_train_data=np.append(train_data,validate_data,axis=0)
final_train_label=np.append(train_label,validate_label,axis=0)
final_amount=final_train_data.shape[0]
self.final_train(final_train_data,final_train_label,final_amount,2000,1200)
final_pre=self.getPrecision(test_data,test_label)
print("final accurracy: "+str(final_pre))
a=svm()
a.Test_2("D:\\data\\cifar-10-batches-py\\data_batch_",
"D:\\data\\cifar-10-batches-py\\test_batch")