使用SVM Loss与Gradient Descent
先回顾一下整体步骤
- 导入图片
- 每一张图片进入分类器得到分数
- 所得分数与该张图的正确标签得分协同计算svm_loss
- 为了使svm_loss降低,对svm_loss的表达式进行求导得到梯度表达式(计算梯度的输入为loss与x)
- 利用梯度表达式计算出当loss与x所对应的梯度
- 更新权重矩阵
- 权重矩阵 = 权重矩阵 - 步长 * 梯度
- 用新的权重矩阵计算下一张图片
代码如下(暂时是这样的思路 ,后面仍会改进)
import numpy as np
import pickle
# 字符定义
# X 数据集(训练集与测试集)
# Y 标签集
# x 一个数据
# y 一个标签
# Ypred 预测标签集
# W 权重
# b 偏移
# dw 梯度
# learning_rate 步长
# scores 得分
# 超参数
learning_rate = 0.01
# 迭代次数
times = 10
filename = 'xxxx'
filename_test = 'xxxx'
class LinearC:
"""docstring for NearestNeighbor"""
def __init__(self):
self.W = np.random.rand(10, 3072) * 0.001
# self.b = np.zeros((10,1))
# 导入数据
def load_file(self, filename):
with open(filename, 'rb') as fo:
data = pickle.load(fo, encoding='latin1')
return data
# 计算梯度
def evaluate_gradient(self, x, y):
scores = self.W.dot(np.matrix(x).T) # + self.b
# print(scores - scores[y] + 1)
margins = np.maximum(0, scores - scores[y] + 1)
margins[y] = 0
self.loss.append(np.sum(margins))
binary = margins
binary[margins > 0] = 1
binary[y] = -np.sum(binary)
dW = binary * x
return dW
def train(self, X, Y):
for count in range(times):
num = X.shape[0]
self.loss = []
for i in range(num):
dW = self.evaluate_gradient(X[i], Y[i])
self.W = self.W - learning_rate * dW
# print(self.W)
# square = 0
# for i in range(self.W.shape[0]):
# for j in range(self.W.shape[1]):
# square += self.W[i,j] * self.W[i,j]
average_loss = np.sum(np.matrix(self.loss))/num
print(average_loss)
# 使用模型进行预测,X是test集的数据
def predict(self, X):
num_test = X.shape[0]# test数据个数
Ypred = np.zeros(num_test)# 初始化预测结果
for i in range(num_test):
scores = self.W.dot(np.matrix(X[i]).T) # + self.b
Ypred[i] = np.argmax(scores)
return Ypred
net = LinearC()
data = net.load_file(filename)
test_batch = net.load_file(filename_test)
net.train(data1['data'], data1['labels'])
result = net.predict(test_batch['data'])
print(result)
网友评论