正则化和最优化Regularization and Optimization

        我们已经介绍了图像分类问题中最重要的两个组成部分——score function和loss function,具体的内容可见线性分类Linear Classification,下面我们将介绍最优化问题,即如何选择W使得loss function最小

一、loss function的可视化

        我们将loss function视为一个大山谷,山的高度代表loss function的大小,不同位置代表W的不同值,我们希望找到山谷的最低点。

        在实际中,各个函数一般非常复杂,因此我们很难直接写出最低点的位置;相反,我们从当前位置开始,通过迭代的方法逐步进行改进。

二、方法一:随机搜索

        随机指定W的值,选择loss function最小的一个。这种方法显然性能较差,在实际中不会经常使用。

# assume X_train is the data where each column is an example (e.g. 3073 x 50,000)
# assume Y_train are the labels (e.g. 1D array of 50,000)
# assume the function L evaluates the loss function

bestloss = float("inf") # Python assigns the highest possible float value
for num in range(1000):
    W = np.random.randn(10, 3073) * 0.0001 # generate random parameters
    loss = L(X_train, Y_train, W) # get the loss over the entire training set
    if loss < bestloss: # keep track of the best solution
        bestloss = loss
        bestW = W

        利用test set中的数据得到准确率如下:

# Assume X_test is [3073 x 10000], Y_test [10000 x 1]
scores = Wbest.dot(Xte_cols) # 10 x 10000, the class scores for all test examples
# find the index with max score in each column (the predicted class)
Yte_predict = np.argmax(scores, axis = 0)
# and calculate accuracy (fraction of predictions that are correct)
np.mean(Yte_predict == Yte)
# returns 0.1555

三、方法二:gradient descent

        1. gradient

        对于一维函数,gradient可以简单的定义为

\frac{df(x)}{dx}=\underset{h\rightarrow 0}{lim}\frac{f(x+h)-f(x)}{h}

         而多维函数的gradient就是各个维度上的partial derivatives组成的向量,gradient对应的方向就是增加最快的方向,相应的-gradient就是下降最快的方向。 

        gradient的计算有两种方法,Numerial gradient和analytic gradient。

        numerical gradient遍历所有维度,每次选择一个维度将x增加一个很小的值h,然后进行上述分式的计算,得到该维度下的gradient。

def eval_numerical_gradient(f, x):
    """
    a naive implementation of numerical gradient of f at x
    - f should be a function that takes a single argument
    - x is the point (numpy array) to evaluate the gradient at
    """
       
    fx = f(x) # evaluate function value at original point
    grad = np.zeros(x.shape)
    h = 0.00001

    # iterate over all indexes in x
    it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite']) #迭代访问数组x中的元素
    while not it.finished:
        # evaluate function at x+h
        ix = it.multi_index
        old_value = x[ix]
        x[ix] = old_value + h # increment by h
        fxh = f(x) # evalute f(x + h)
        x[ix] = old_value # restore to previous value (very important!)

        # compute the partial derivative
        grad[ix] = (fxh - fx) / h # the slope
        it.iternext() # step to next dimension

    return grad

        这种方法一般非常慢,通过微积分我们可以得到一个表达式,直接计算出gradient(analtyic gradient)。在实际中,我们通常使用numerical gradient来验证analytic gradient的值,这种方法称为gradient check。

        2. gradient descent算法

        首先随机初始化W的值,然后循环计算loss以及gradient,在-gradient方向(loss下降最快的方向)更新W。其中,step_size为learning rate,也是一个非常重要的hyperparameter。

while True:
    weights_grad = evaluate_gradient(loss_fun, data, weights)
    weights += -step_size * weights_grad # perform parameter update

        3. Stochastic Gradient Descent(SGD)

        在之前的模型中,我们依次计算每个training example的误差Li,整个数据集的误差就是所有Li的平均值。

L(W)=\frac{1}{N}\sum_{i=1}^NL_i(x_i,y_i,W)+\lambda R(W)

       每次更新W时,我们都需要计算L的gradient,即涉及整个training set的遍历。但在实际情况中,training set通常非常大,这种计算方法需要很长时间。

        因此,我们通常采用SGD,在每次迭代中只选取一小部分的训练样本(minibatch)来计算gradient并更新W。

while True:
  data_batch = sample_training_data(data, 256) # sample 256 examples
  weights_grad = evaluate_gradient(loss_fun, data_batch, weights)
  weights += - step_size * weights_grad # perform parameter update

你可能感兴趣的:(CS231n,python,计算机视觉)