博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线性SVM分类器实战
阅读量:5256 次
发布时间:2019-06-14

本文共 9527 字,大约阅读时间需要 31 分钟。

1 概述

基础的理论知识参考。

代码实现环境:python3

2 数据处理

2.1 加载数据集

将原始数据集放入“data/cifar10/”文件夹下。

### 加载cifar10数据集import osimport pickleimport randomimport numpy as npimport matplotlib.pyplot as pltdef load_CIFAR_batch(filename):    """    cifar-10数据集是分batch存储的,这是载入单个batch    @参数 filename: cifar文件名    @r返回值: X, Y: cifar batch中的 data 和 labels    """    with open(filename,'rb') as f:        datadict=pickle.load(f,encoding='bytes')        X=datadict[b'data']        Y=datadict[b'labels']                X=X.reshape(10000, 3, 32, 32).transpose(0,2,3,1).astype("float")        Y=np.array(Y)                return X, Ydef load_CIFAR10(ROOT):    """    读取载入整个 CIFAR-10 数据集    @参数 ROOT: 根目录名    @return: X_train, Y_train: 训练集 data 和 labels             X_test, Y_test: 测试集 data 和 labels    """    xs=[]    ys=[]    for b in range(1,6):        f=os.path.join(ROOT, "data_batch_%d" % (b, ))        X, Y=load_CIFAR_batch(f)        xs.append(X)        ys.append(Y)    X_train=np.concatenate(xs)    Y_train=np.concatenate(ys)    del X, Y    X_test, Y_test=load_CIFAR_batch(os.path.join(ROOT, "test_batch"))    return X_train, Y_train, X_test, Y_testX_train, y_train, X_test, y_test = load_CIFAR10('data/cifar10/') print(X_train.shape)print(y_train.shape)print(X_test.shape)print( y_test.shape)

运行结果如下:

(50000, 32, 32, 3)(50000,)(10000, 32, 32, 3)(10000,)

2.2 划分数据集

将加载好的数据集划分为训练集,验证集,以及测试集。

## 划分训练集,验证集,测试集num_train = 49000num_val = 1000num_test = 1000# Validation setmask = range(num_train, num_train + num_val)X_val = X_train[mask]y_val = y_train[mask]# Train setmask = range(num_train)X_train = X_train[mask]y_train = y_train[mask]# Test setmask = range(num_test)X_test = X_test[mask]y_test = y_test[mask]print('Train data shape: ', X_train.shape)print('Train labels shape: ', y_train.shape)print('Validation data shape: ', X_val.shape)print('Validation labels shape ', y_val.shape)print('Test data shape: ', X_test.shape)print('Test labels shape: ', y_test.shape)

运行结果为:

Train data shape:  (49000, 3072)Validation data shape:  (1000, 3072)Test data shape:  (1000, 3072)

2.3 去均值归一化

将划分好的数据集归一化,即:所有划分好的数据集减去均值图像。

# Processing: subtract the mean imagesmean_image = np.mean(X_train, axis=0)X_train -= mean_imageX_val -= mean_imageX_test -= mean_image# append the bias dimension of ones (i.e. bias trick)X_train = np.hstack([X_train, np.ones((X_train.shape[0], 1))])#堆叠数组X_val = np.hstack([X_val, np.ones((X_val.shape[0], 1))])X_test = np.hstack([X_test, np.ones((X_test.shape[0], 1))])print('Train data shape: ', X_train.shape)print('Validation data shape: ', X_val.shape)print('Test data shape: ', X_test.shape)

运行结果为:

Train data shape:  (49000, 3073)Validation data shape:  (1000, 3073)Test data shape:  (1000, 3073)

3 线性SVM分类器

3.1 定义线性SVM分类器

关键的是线性SVM的梯度推导过程。具体的可以看看。

#Define a linear SVM classifierclass LinearSVM(object):    """ A subclass that uses the Multiclass SVM loss function """    def __init__(self):        self.W = None    def loss_vectorized(self, X, y, reg):        """        Structured SVM loss function, naive implementation (with loops).        Inputs:        - X: A numpy array of shape (num_train, D) contain the training data          consisting of num_train samples each of dimension D        - y: A numpy array of shape (num_train,) contain the training labels,          where y[i] is the label of X[i]        - reg: (float) regularization strength        Outputs:        - loss: the loss value between predict value and ground truth        - dW: gradient of W        """                 # Initialize loss and dW        loss = 0.0        dW = np.zeros(self.W.shape)                # Compute the loss        num_train = X.shape[0]        scores = np.dot(X, self.W)        correct_score = scores[range(num_train), list(y)].reshape(-1, 1)            margin = np.maximum(0, scores - correct_score + 1) # delta = 1        margin[range(num_train), list(y)] = 0  #分对的损失为0        loss = np.sum(margin) / num_train + 0.5 * reg * np.sum(self.W * self.W) #reg就是权重lamda                # Compute the dW        num_classes = self.W.shape[1]        mask = np.zeros((num_train, num_classes))        mask[margin > 0] = 1        mask[range(num_train), list(y)] = 0        mask[range(num_train), list(y)] = -np.sum(mask, axis=1)        dW = np.dot(X.T, mask)        dW = dW / num_train + reg * self.W                return loss, dW        def train(self, X, y, learning_rate = 1e-3, reg = 1e-5, num_iters = 100,              batch_size = 200, print_flag = False):        """        Train linear SVM classifier using SGD        Inputs:        - X: A numpy array of shape (num_train, D) contain the training data          consisting of num_train samples each of dimension D        - y: A numpy array of shape (num_train,) contain the training labels,          where y[i] is the label of X[i], y[i] = c, 0 <= c <= C        - learning rate: (float) learning rate for optimization        - reg: (float) regularization strength        - num_iters: (integer) numbers of steps to take when optimization        - batch_size: (integer) number of training examples to use at each step        - print_flag: (boolean) If true, print the progress during optimization        Outputs:        - loss_history: A list containing the loss at each training iteration        """                loss_history = []        num_train = X.shape[0]        dim = X.shape[1]        num_classes = np.max(y) + 1                # Initialize W        if self.W == None:            self.W = 0.001 * np.random.randn(dim, num_classes)                # iteration and optimization        for t in range(num_iters):            idx_batch = np.random.choice(num_train, batch_size, replace=True)            X_batch = X[idx_batch]            y_batch = y[idx_batch]            loss, dW = self.loss_vectorized(X_batch, y_batch, reg)            loss_history.append(loss)            self.W += -learning_rate * dW                        if print_flag and t%100 == 0:                print('iteration %d / %d: loss %f' % (t, num_iters, loss))                return loss_history        def predict(self, X):        """        Use the trained weights of linear SVM to predict data labels        Inputs:        - X: A numpy array of shape (num_train, D) contain the training data        Outputs:        - y_pred: A numpy array, predicted labels for the data in X        """                y_pred = np.zeros(X.shape[0])        scores = np.dot(X, self.W)        y_pred = np.argmax(scores, axis=1)                return y_pred

3.2 无交叉验证

3.2.1 训练模型

##Stochastic Gradient Descentsvm = LinearSVM()loss_history = svm.train(X_train, y_train, learning_rate = 1e-7, reg = 2.5e4, num_iters = 2000,              batch_size = 200, print_flag = True)

运行结果如下:

iteration 0 / 2000: loss 407.076351iteration 100 / 2000: loss 241.030820iteration 200 / 2000: loss 147.135737iteration 300 / 2000: loss 90.274781iteration 400 / 2000: loss 56.509895iteration 500 / 2000: loss 36.654007iteration 600 / 2000: loss 23.732160iteration 700 / 2000: loss 16.340341iteration 800 / 2000: loss 11.538806iteration 900 / 2000: loss 9.482515iteration 1000 / 2000: loss 7.414343iteration 1100 / 2000: loss 6.240377iteration 1200 / 2000: loss 5.774960iteration 1300 / 2000: loss 5.569365iteration 1400 / 2000: loss 5.326023iteration 1500 / 2000: loss 5.708757iteration 1600 / 2000: loss 4.731255iteration 1700 / 2000: loss 5.516500iteration 1800 / 2000: loss 4.959480iteration 1900 / 2000: loss 5.447249

3.2.2 预测

# Use svm to predict# Training sety_pred = svm.predict(X_train)num_correct = np.sum(y_pred == y_train)accuracy = np.mean(y_pred == y_train)print('Training correct %d/%d: The accuracy is %f' % (num_correct, X_train.shape[0], accuracy))# Test sety_pred = svm.predict(X_test)num_correct = np.sum(y_pred == y_test)accuracy = np.mean(y_pred == y_test)print('Test correct %d/%d: The accuracy is %f' % (num_correct, X_test.shape[0], accuracy))

运行结果如下:

Training correct 18799/49000: The accuracy is 0.383653Test correct 386/1000: The accuracy is 0.386000

3.3 有交叉验证

3.3.1 训练模型

#Cross-validationlearning_rates = [1.4e-7, 1.5e-7, 1.6e-7]regularization_strengths = [8000.0, 9000.0, 10000.0, 11000.0, 18000.0, 19000.0, 20000.0, 21000.0]results = {}best_lr = Nonebest_reg = Nonebest_val = -1   # The highest validation accuracy that we have seen so far.best_svm = None # The LinearSVM object that achieved the highest validation rate.for lr in learning_rates:    for reg in regularization_strengths:        svm = LinearSVM()        loss_history = svm.train(X_train, y_train, learning_rate = lr, reg = reg, num_iters = 2000)        y_train_pred = svm.predict(X_train)        accuracy_train = np.mean(y_train_pred == y_train)        y_val_pred = svm.predict(X_val)        accuracy_val = np.mean(y_val_pred == y_val)        if accuracy_val > best_val:            best_lr = lr            best_reg = reg            best_val = accuracy_val            best_svm = svm        results[(lr, reg)] = accuracy_train, accuracy_val        print('lr: %e reg: %e train accuracy: %f val accuracy: %f' %              (lr, reg, results[(lr, reg)][0], results[(lr, reg)][1]))print('Best validation accuracy during cross-validation:\nlr = %e, reg = %e, best_val = %f' %      (best_lr, best_reg, best_val))

3.3.2 预测

# Use the best svm to testy_test_pred = best_svm.predict(X_test)num_correct = np.sum(y_test_pred == y_test)accuracy = np.mean(y_test_pred == y_test)print('Test correct %d/%d: The accuracy is %f' % (num_correct, X_test.shape[0], accuracy))

运行结果为:

Test correct 372/1000: The accuracy is 0.372000

转载于:https://www.cnblogs.com/Terrypython/p/10984227.html

你可能感兴趣的文章
Linux下Mysql数据库互为主从的配置过程
查看>>
ECSHOP系统,数据库表名称、结构
查看>>
Python Web开发框架Django
查看>>
【Install】我是如何安装Linux类系统的
查看>>
作业三4
查看>>
多态存在的3个必要条件
查看>>
code First 四
查看>>
Django与Ajax
查看>>
再做一题,2013-6-16更新
查看>>
Oracle_Statspack性能诊断工具
查看>>
面向对象(封装、继承、多态、抽象)
查看>>
Memcached数据库缓存
查看>>
转获取sql维护的表关系
查看>>
网络基础——TCP/IP五层模型
查看>>
HDU-3018 Ant Trip(欧拉回路)
查看>>
Codeforces Round #215 (Div. 1) B. Sereja ans Anagrams 匹配
查看>>
CDOJ 1251 谕神的密码 贪心
查看>>
CMYK列印颜色
查看>>
matplotlib 进阶之Tight Layout guide
查看>>
多线程 测试
查看>>