实验日期

2021.10.02 — 2021.10.06

实验环境

  • python 3.8.8 64-bit

KNN

KNN实验的核心就在于distance矩阵的计算。其中,计算方法分为两层循环,一层循环和无循环计算

  • 两层循环

    for i in range(num_test):for j in range(num_train):dists[i][j] = np.sqrt(np.sum(np.square(X[i , :] - self.X_train[j , :])))
    
    • distance矩阵得出的结果是每一个测试数据距离所有训练数据的距离。因为我们可以在遍历测试集的每一个数据时,将测试数据各个feature的数据与训练数据对应feature相减,然后得到L2-norm形式的距离。最终dists[ i ] [ j ]代表第 i 的测试数据和第 j 个训练数据的L2-norm距离
  • 一层循环

     for i in range(num_test):dists[i] = np.sqrt(np.sum(np.square(X[i , :] - self.X_train) , axis=1))
    
    • 在这里,只使用一层循环,是遍历测试数据的。np.array的一个特性是,当一个向量与一个矩阵做加减运算时,该向量会自动复制,扩充到和矩阵一样大的维度,然后对应相减。所以这里的测试数据是一个行向量,在减去X_train时,会和X_train的每一行相减,这样我们就得到了所有的差值,然后平方,求和,开方,就得到了L2-norm距离
  • 无循环

     a = np.sum(np.square(X) , axis=1 , keepdims=True) #列向量b = np.sum(np.square(self.X_train) , axis=1) # 行向量c = np.multiply(np.dot(X , self.X_train.T) , -2)dists = np.add(a , b)dists = np.add(dists , c)dists = np.sqrt(dists)
    
    • 这里需要数学上的小技巧,即利用(x−y)2=x2+y2−2xy(x-y)^2 = x^2 + y^2 - 2xy(x−y)2=x2+y2−2xy的公式,我们想要得到式子左边的,可以通过求式子右边的x2x^2x2 , y2y^2y2 , −2xy-2xy−2xy 来得到,即a , b , c , 注意:a , b 分别为列向量和行向量,相加得到一个矩阵
  • 三种循环的运行速度

    • Two loop version took 29.890179 seconds
    • One loop version took 57.145778 seconds
    • No loop version took 0.229963 seconds

补充predict

closest_y = self.y_train[np.argsort(dists[i,:])[:k]] #取前k小个dist对应的索引
y_pred[i] = np.argmax(np.bincount(closest_y))#找出现最多次的label
  • 利用np.argsort得到前k小dists的索引,然后再利用np.bincount计算这些索引出现的次数,最后利用大多数投票的方式得到最终的label

交叉验证

X_train_folds = np.array_split(X_train , num_folds , axis = 0)
y_train_folds = np.array_split(y_train , num_folds , axis = 0)
  • 首先将训练集分为num_folds份
for k in k_choices:accuracies = []for i in range(num_folds):#选取一份当验证集,其余的作为训练集X_train_cv = np.vstack(X_train_folds[0:i] + X_train_folds[i+1:])y_train_cv = np.hstack(y_train_folds[0:i] + y_train_folds[i+1:])X_valid_cv = X_train_folds[i]y_valid_cv = y_train_folds[i]classifier.train(X_train_cv , y_train_cv)dists = classifier.compute_distances_no_loops(X_valid_cv)y_test_pred = classifier.predict_labels(dists , k)num_correct = np.sum(y_test_pred == y_valid_cv)accuracy = float(num_correct) / y_valid_cv.shape[0]accuracies.append(accuracy)k_to_accuracies[k] = accuracies
  • 交叉验证中,将刚才分好的数据,选取一份做验证集,其余的作为训练集,进行训练和预测,并得到预测的准确度

  • 尝试不同的k

  • 最终选取训练效果最好的k = 10

    • Got 141 / 500 correct => accuracy: 0.282000

SVM

首先,推导SVM loss function对w的梯度

对于每一个样本,正确分类的得分应该比错误分类的得分至少高Δ\DeltaΔ , Δ\DeltaΔ取值在实际中一般为1

  • 若正确分类的得分比错误分类的得分大1 , 则认为判断正确

  • loss function:Li=∑j≠yi[max(0,wjTxi−wyiTxi+Δ)]L_i = \sum_{j \ne y_i} [max(0 , w_j^Tx_i - w_{y_i}^Tx_i + \Delta)]Li​=∑j​=yi​​[max(0,wjT​xi​−wyi​T​xi​+Δ)]

    • wyiTxiw_{y_i}^Tx_iwyi​T​xi​ 求的是 xix_ixi​在第 yiy_iyi​ 个类别,也就是对正确分类的得分
    • wjTxiw_j^Tx_iwjT​xi​ 求的是 xix_ixi​ 在第 j 个类别的得分 , 也就是对错误分类的得分
    • Δ\DeltaΔ 是正确分类的得分要比错误分类的得分高 Δ\DeltaΔ 才算分类正确 , 分类正确 loss 算 0
    • Δ\DeltaΔ 通常取1 , 因为 Δ\DeltaΔ 的变换可以转换成 www 的变化
  • 梯度

    • 对loss function 直接求梯度,实际是分成两部分求的,一部分是对 0 求,一部分是对∑j≠yi(wjTxi−wyiTxi+Δ)\sum_{j \ne y_i}(w_j^Tx_i - w_{y_i}^Tx_i + \Delta)∑j​=yi​​(wjT​xi​−wyi​T​xi​+Δ) 求 , 所以梯度中会出现判别式
    • 对正确分类的梯度:
      • ▽wyiLi=−(∑j≠yi1(wjTxi−wyiTxi+Δ>0))xi\bigtriangledown_{w_{y_i}}L_i = -\left(\sum_{j \ne y_i } 1(w_j^Tx_i - w_{y_i}^Tx_i + \Delta > 0) \right) x_i▽wyi​​​Li​=−(∑j​=yi​​1(wjT​xi​−wyi​T​xi​+Δ>0))xi​
      • 注意:需要求和( yiy_iyi​ 是同一个)
      • 若正确分类,则判别式中 > 0 不满足 , 因此该项梯度为 0
      • 若分类错误,则判别式中 > 0 满足 ,因此该项梯度为 −xi-x_i−xi​
    • 对错误分类的梯度:
      • ▽wjLi=1(wjTxi−wyiTxi+Δ>0)xi\bigtriangledown_{w_j}L_i = 1(w_j^Tx_i - w_{y_i}^Tx_i + \Delta > 0) x_i▽wj​​Li​=1(wjT​xi​−wyi​T​xi​+Δ>0)xi​
      • 注意:不用求和(每一个 jjj 都不是同一个)
      • 若正确分类,则判别式中 > 0 不满足 , 因此该项梯度为 0
      • 若分类错误,则判别式中 > 0 满足 ,因此该项梯度为 xix_ixi​
  • 对应求梯度和loss的代码部分 ,在计算梯度和loss的时候只需要考虑分类错误所带来的影响,因为分类正确时,对loss和梯度的贡献都是0

        dW = np.zeros(W.shape) # 初始化梯度矩阵为0# compute the loss and the gradientnum_classes = W.shape[1] #类别个数num_train = X.shape[0] #训练数据个数loss = 0.0for i in range(num_train):scores = X[i].dot(W) #一个输入的所有类得分 , W:D-by-C , 每一列评判一个类的得分correct_class_score = scores[y[i]] #y[i]对应这条数据的真实label , 得到真实label的得分for j in range(num_classes):if j == y[i]: #continuemargin = scores[j] - correct_class_score + 1 #分类不正确 #正确分类得分比不正确的至少大1,代表分类正确if margin > 0: # max(0,--)操作 ,若正确类别的得分没有比错误类别得分大 1loss += margindW[:,y[i]] += -X[i] #对应正确分类的梯度 , 结合上面梯度推导很容易明白dW[:,j] += X[i] #对应不正确分类的梯度 , 结合上面梯度推导很容易明白
    

代码补充svm_loss_naive

  • 只是计算平均梯度并加上正则项
    # 计算平均梯度并加上正则项dW /= num_traindW += reg * W

代码补充svm_loss_vectorized部分

  • 首先计算loss

        scores = np.dot(X,W) #计算出所有的得分 (N , C)大小的矩阵num_train = X.shape[0]correct_class_score = scores[np.arange(num_train),y] #找到所有正确类别的得分 , 1-by-Ncorrect_class_score = np.reshape(correct_class_score,(num_train,-1)) # N-by-1,为下面相减做准备margins = np.maximum(0, scores - correct_class_score + 1)margins[np.arange(num_train),y] = 0 #正确分类自己的 loss 为 0loss += np.sum(margins) / num_trainloss += reg * np.sum(W * W)
    
    • 需要注意的是

      • 找到所有正确分类的得分,是个行向量,我们要将其转化为列向量,这样在与矩阵相减时才能保证对应列相减,因为scores中的每一行是一个数据的所有类别的得分
      • 在margins的计算过程中,要注意,正确分类对loss的贡献为0
  • 计算梯度

        margins[margins > 0] = 1 #将所有大于0的项置1row_sum = np.sum(margins,axis=1) margins[np.arange(num_train),y] = -row_sumdW = np.dot(X.T,margins) #X:N-by-D , margins:N-by-C , dW:D-by-C , C代表的是类别个数 , D代表每个类的参数个数#margins中第i行的数代表第i个训练数据对梯度的贡献量dW /= num_traindW += reg * W
    
    • 首先将margins中大于0的项置1,因为所有未正确分类的数据都会对dW[:,y[i]]有多次影响

      • 参照

         if margin > 0: # max(0,--)操作 ,若正确类别的得分没有比错误类别得分大 1loss += margindW[:,y[i]] += -X[i] #对应正确分类的梯度 , 结合上面梯度推导很容易明白dW[:,j] += X[i] #对应不正确分类的梯度 , 结合上面梯度推导很容易明
        
    • 从每个margin > 0 ,正确分类的梯度都要减去X[i] , 因此有

      margins[np.arange(num_train),y] = -row_sum
      
    • 对未正确分类的梯度来说,只需要加上X[i] 即可

    • 关键的部分在于

      dW = np.dot(X.T,margins) #X:N-by-D , margins:N-by-C , dW:D-by-C , C代表的是类别个数 , D代表每个类的参数个数#margins中第i行的数代表第i个训练数据对梯度的贡献量
      
      • 当X.T与margins相乘时,可以将margins中的数看成贡献量
      • 若margins[i] [j] = k , 则dW[:,j] += k * X[i] , 这个式子是向量化计算的核心

调参(交叉验证)

  • 就是简单的遍历 + 训练 + 预测 , 得到最好的参数
  • 结果:best validation accuracy achieved during cross-validation: 0.398000
  • linear SVM on raw pixels final test set accuracy: 0.377000
for learning_rate in learning_rates:for regularization_strength in regularization_strengths:svm = LinearSVM()loss_hist = svm.train(X_train, y_train, learning_rate=learning_rate, reg=regularization_strength,num_iters=1500, verbose=True)#训练模型y_train_pred = svm.predict(X_train)#预测训练集y_val_pred = svm.predict(X_val)#预测验证集y_train_acc = np.mean(y_train_pred==y_train)y_val_acc = np.mean(y_val_pred==y_val)results[(learning_rate,regularization_strength)] = [y_train_acc, y_val_acc] #得到一组参数对应的结果if y_val_acc > best_val:#更新best_val = y_val_accbest_svm = svm

softmax

首先,推导softmax loss function对w的梯度

  • Softmax 公式:Si=efyi∑jefjS_i = \frac{e^ {f_{y_i}}}{\sum_je^ {f_j} }Si​=∑j​efj​efyi​​​

  • Softmax Loss 公式:Li=−log⁡efyi∑jefjL_i = -\log \frac{e^ {f_{y_i}}}{\sum_je^ {f_{j}} }Li​=−log∑j​efj​efyi​​​ , fj=X(i)W(j)f_j = X(i)W(j)fj​=X(i)W(j) , 若fyif_{y_i}fyi​​的得分越高,则其所占总得分比例越大,LiL_iLi​越小

  • 梯度

    • 对每一个 X[i] 来说,可能对分类器判断所有类别的参数都有贡献,需要对所有的W(j)求导W(j)求导W(j)求导

    • ∂Li∂Wj=∂Li∂fj∂fj∂Wj\frac{\partial L_i}{\partial W_j} = \frac{\partial L_i}{\partial f_j}\frac{\partial f_j}{\partial W_j}∂Wj​∂Li​​=∂fj​∂Li​​∂Wj​∂fj​​ , 可见,当求导链式法则第一项时,分子下标为 i , 分母下标为 j , 因此分为 i=ji=ji=j 和 i≠ji \ne ji​=j 来求导第一项

      • i = j

        • ∂Li∂fj=−∑jefyiefyi∑j−efyiefj∑j2=efj−∑j∑j\frac{\partial L_i}{\partial f_j} = -\frac{\sum_{j}^{} }{e^{f_{y_i}}} \frac{e^{f_{y_i}}\sum_{j}-e^{f_{y_i}}e^{f_j}}{{\sum_{j}}^2} =\frac{e^{f_j} - \sum_j }{\sum_{j} }∂fj​∂Li​​=−efyi​​∑j​​∑j​2efyi​​∑j​−efyi​​efj​​=∑j​efj​−∑j​​
      • i≠ji \ne ji​=j

        • ∂Li∂fj=−∑jefyi−efyiefj∑j2=efj∑j\frac{\partial L_i}{\partial f_j} = -\frac{\sum_{j}^{} }{e^{f_{y_i}}} \frac{-e^{f_{y_i}}e^{f_j}}{{\sum_{j}}^2} =\frac{e^{f_j}}{\sum_{j} }∂fj​∂Li​​=−efyi​​∑j​​∑j​2−efyi​​efj​​=∑j​efj​​
    • 易知:∂fj∂Wj=∂XiWj∂Wj=Xi\frac{\partial f_j}{\partial W_j} = \frac{\partial X_iW_j}{\partial W_j} = X_i∂Wj​∂fj​​=∂Wj​∂Xi​Wj​​=Xi​

    • 综上

      • i = j

        • ∂Li∂Wj=efj−∑j∑jXi=(Sj−1)Xi\frac{\partial L_i}{\partial W_j} = \frac{e^{f_j} - \sum_j }{\sum_{j} }X_i = (S_j - 1)X_i∂Wj​∂Li​​=∑j​efj​−∑j​​Xi​=(Sj​−1)Xi​
      • i≠ji \ne ji​=j
        • ∂Li∂Wj=efj∑jXi=SjXi\frac{\partial L_i}{\partial W_j} = \frac{e^{f_j}}{\sum_{j} }X_i = S_jX_i∂Wj​∂Li​​=∑j​efj​​Xi​=Sj​Xi​

代码补充softmax_loss_naive

    num_classes = W.shape[1]num_train = X.shape[0]for i in xrange(num_train):scores = X[i].dot(W) #(1,C)shift_scores = scores - max(scores) #保持数据稳定性 , 防止exp过大loss += (-shift_scores[y[i]] + np.log(sum(np.exp(shift_scores))) )for j in xrange(num_classes):softmax_output = np.exp(shift_scores[j])/sum(np.exp(shift_scores))if j == y[i]:dW[:,j] += (-1 + softmax_output) *X[i] else: dW[:,j] += softmax_output *X[i] loss /= num_train loss +=  0.5* reg * np.sum(W * W)dW = dW/num_train + reg* W
  • 首先通过X[i]对W的一个点积,得到所有训练数据的所有类别的得分

  • 所有数据的得分减去这个数据所有类别得分中的最大值,以保证得分较小,防止在exp时溢出

  • 得到loss

  • 在梯度中可以清晰地看到

    • i = j

      • ∂Li∂Wj=efj−∑j∑jXi=(Sj−1)Xi\frac{\partial L_i}{\partial W_j} = \frac{e^{f_j} - \sum_j }{\sum_{j} }X_i = (S_j - 1)X_i∂Wj​∂Li​​=∑j​efj​−∑j​​Xi​=(Sj​−1)Xi​
    • i≠ji \ne ji​=j

      • ∂Li∂Wj=efj∑jXi=SjXi\frac{\partial L_i}{\partial W_j} = \frac{e^{f_j}}{\sum_{j} }X_i = S_jX_i∂Wj​∂Li​​=∑j​efj​​Xi​=Sj​Xi​
    • 这里的 S 就是softmax_output , 也就是经过softmax之后的得分

代码补充softmax_loss_vectorized

    num_classes = W.shape[1]num_train = X.shape[0]scores = X.dot(W) #N-by-Cshift_scores = scores - np.max(scores, axis = 1, keepdims = True)# 每一项都用softmax公式转成概率softmax_output = np.exp(shift_scores)/np.sum(np.exp(shift_scores), axis = 1, keepdims = True) loss = -np.sum(np.log(softmax_output[range(num_train), list(y)]))loss = loss / num_train + 0.5* reg * np.sum(W * W)dscores = softmax_output.copy()#这个矩阵乘法和SVM的一样,只是参数不一样#X.T : D-by-N  dscores : N-by-C#N个输入中的每一个都会对dW的整个矩阵有贡献 ,对X[i]来说,若当前 j = y[i] , 则贡献量为softmax_output[i][y[i]] - 1#否则为 softmax_output[i][y[i]] ,即不用修改softmax_output矩阵dscores[range(num_train), y] += -1 #dscores的第i行代表 X[i] 对整个分类器的贡献量dW = (X.T).dot(dscores)dW = dW/num_train + reg* W
  • 可以说,上述过程和 SVM 的向量化计算非常类似,只是loss和梯度的计算方式发生了改变,其原理都是一样的

  • loss很容易算出

  • 要注意的是,这里的dscores中的元素也可以当做贡献量来看

    • dscores[i] [j] = k ,则 dW[:,j] += X[i]
    • 而k , 也就是X[i] 前面的系数,只有 -1 和 不 -1 之分 , 这点可以通过梯度的计算公式得到

调参(交叉验证)

  • 这里的交叉验证也和SVM类似,不再多说
  • 结果:best validation accuracy achieved during cross-validation: 0.358000
  • softmax on raw pixels final test set accuracy: 0.361000
for reg in regularization_strengths:for lr in learning_rates:svm = Softmax()loss_hist = svm.train(X_train, y_train, lr, reg, num_iters=1500)y_train_pred = svm.predict(X_train)train_accuracy = np.mean(y_train == y_train_pred)y_val_pred = svm.predict(X_val)val_accuracy = np.mean(y_val == y_val_pred)if val_accuracy > best_val:best_val = val_accuracybest_softmax = svm           results[(lr,reg)] = train_accuracy, val_accuracy

three_layer_net

代码补充 loss

h1 = np.dot(X , W1) + b1
first_layer = np.maximum(0 , h1) #第一层全连接层 + ReLu: N-by-D * D-by-H + H-by-1 -> N-by-H h2 = np.dot(first_layer , W2) + b2
second_layer = np.maximum(0 , h2) # N-by-Hscores = np.dot(second_layer , W3) + b3 #最后一个全连接层的输出 N-by-C
  • 这里需要注意的就是,层与层之间的维度关系不要乱
#softmax
shift_scores = scores - np.max(scores, axis = 1, keepdims = True)
softmax_output = np.exp(shift_scores)/np.sum(np.exp(shift_scores), axis = 1, keepdims = True)
loss = -np.sum(np.log(softmax_output[range(N), y]))
loss = loss / N + 0.5 * reg * np.sum(W1 * W1) +  0.5 * reg * np.sum(W2 * W2) + 0.5 * reg * np.sum(W3 * W3)
  • 这里的 loss 就是一个softmax的过程 , 和前面softmax一模一样 , 只不过多加了几个正则项
dscores = softmax_output
dscores[range(N),y] -= 1
grads['W3'] = np.dot(second_layer.T,dscores) / N + reg * W3
grads['b3'] = np.sum(dscores,axis=0,keepdims=False) / N #b 和 W 一样 , 只不过不用乘以X[i] , 因为b的前面没有参数mask = np.zeros_like(h2)
mask[h2>0] = 1 # ReLu中大于0的部分
#print(da2_dz2.shape)
delta2 = np.dot(dscores , W3.T) * mask #链式法则,前面求的是score对second_layer的导数,再乘以dscore(tot_loss对score的导数)
grads['W2'] = first_layer.T.dot(delta2) / N + reg * W2
grads['b2'] = np.ones(N).dot(delta2) / Nmask2 = np.zeros_like(h1)
mask2[h1>0] = 1
delta1 = np.dot(delta2 , W2.T) * mask2
grads['W1'] = X.T.dot(delta1) / N + reg * W1
grads['b1'] = np.ones(N).dot(delta1) / N
  • 这里就需要注意了

    • 第三层

      • dscores 的本质:是tot_loss 对 score 的梯度
      • 在求解W3的梯度时,其实就是softmax中对W3的梯度 , 求的是 tot_loss 对 W3 的导数
      • 在求解b3的梯度时,其实和W3一样,只是没有了X[i]作为系数,因为b的前面没有参数
    • 第二层

      • 根据链式法则,tot_loss 对 第二层 + ReLu 之后的数据second_layer的导数,应该是tot_loss对scores的梯度 * scores对second_layer的梯度

      • second_layer就是 W3*X + b3 中的 X , 也就是第三层的输入 , 因此scores对second_layer的导数就是 W3TW_3^TW3T​

      • ReLu将小于0的值,归成了0 , 大于 0 的为 x

        • 因此second_layer 对 ReLu之前的数据 h2 的导数为 , 0 或 1
        • h2 对 W2 的梯度为 first_layerTfirst\_layer^Tfirst_layerT
      • 所以就有了这部分,这部分就是链式法则的运用

        mask = np.zeros_like(h2)
        mask[h2>0] = 1 # ReLu中大于0的部分
        #print(da2_dz2.shape)
        delta2 = np.dot(dscores , W3.T) * mask #链式法则,前面求的是score对second_layer的导数,再乘以dscore(tot_loss对score的导数)
        
    • 第一层

      • 从第二层到第一层和从第三层到第二层一样,直接重复上述操作即可

代码补充train

# 选择训练集
batch_inx = np.random.choice(num_train, batch_size)
X_batch = X[batch_inx,:]
y_batch = y[batch_inx]
self.params['W1'] -= learning_rate * grads['W1']
self.params['b1'] -= learning_rate * grads['b1']
self.params['W2'] -= learning_rate * grads['W2']
self.params['b2'] -= learning_rate * grads['b2']
self.params['W3'] -= learning_rate * grads['W3']
self.params['b3'] -= learning_rate * grads['b3']
  • 选择训练集和参数迭代

代码补充predict

scores = self.loss(X)
y_pred = np.argmax(scores, axis=1)
  • 选得分最高的

调参(交叉验证)

  • 结果:Test accuracy: 0.495
best_acc = 0
learning_rate = [1e-4, 5e-3, 1e-3,1e-2]
#regulations = [0.2, 0.25, 0.3, 0.35]
regulations = [1e-4, 5e-4, 1e-3, 4e-3,1e-2]
for lr in learning_rate:for reg in regulations:stats = net.train(X_train, y_train, X_val, y_val,num_iters=2500, batch_size=150,learning_rate=lr, learning_rate_decay=0.95,reg=reg, verbose=True)val_acc = (net.predict(X_val) == y_val).mean()if val_acc > best_acc:best_acc = val_accbest_net = netprint('lr = ',lr ,' reg = ',reg, ' acc = ', best_acc)

features

  • 不在图像的原始像素上运用分类器,而是先从原始数据上计算好一些特征,再对这些特征运用分类器

  • 主要有两个特征提取器

    • hog_feature 注重texture
    • color_histogram_hsv注重颜色
  • SVM

    • 结果:best validation accuracy achieved during cross-validation: 0.420000
    for lr in learning_rates:for reg_str in regularization_strengths:svm = LinearSVM()loss_hist = svm.train(X_train_feats, y_train, learning_rate=lr, reg=reg_str,num_iters=1500, verbose=False)y_train_pred = svm.predict(X_train_feats)accuracy_train = np.mean(y_train == y_train_pred)y_val_pred = svm.predict(X_val_feats)accuracy_val = np.mean(y_val == y_val_pred)results[(lr, reg_str)] = (accuracy_train, accuracy_val) if accuracy_val > best_val:print ("lr:",lr)print ("reg:", reg_str)best_val = accuracy_valbest_svm = svm
    
  • ThreeLayerNet

    • 结果:lr = 1 reg = 1e-05 acc = 0.558

    • test_acc:0.551

    • 调参得到较优的参数为 learning_rat = 1 , reg_choice = 1e-5 , num_iters = 10000

      best_acc = -1
      input_size = 32 * 32 * 3#learning_rate_choice = [1e-4, 5e-3, 1e-3,1e-2,1e-1,1e-5,1e-6]
      #reg_choice = [1e-4, 5e-4, 1e-3, 4e-3,1e-2,1e-1,1,10,1e-5]
      learning_rate_choice  =  [1e-2 , 1e-1 , 1]
      reg_choice =  [1e-5 , 1e-4 , 1e-3 , 1e-2 , 1e-1]for learning_rate_curr in learning_rate_choice:for reg_cur in reg_choice:    net = ThreeLayerNet(input_dim, hidden_dim, num_classes)stats = net.train(X_train_feats, y_train, X_val_feats, y_val,num_iters=10000, batch_size=150,learning_rate=learning_rate_curr, learning_rate_decay=0.95,reg=reg_cur, verbose=True)val_acc = (net.predict(X_val_feats) == y_val).mean()if val_acc>best_acc:best_acc = val_accbest_net = netbest_stats = statsprint('lr = ',learning_rate_curr ,' reg = ',reg_cur, ' acc = ', best_acc)
      

结论分析与体会

  • 通过本次实验,自己推导了SVM loss function 对 W 和 b 的梯度公式,对SVM loss function 有了深入的了解
  • 通过本次实验,自己推导了SoftMax loss function 对 W 和 b 的梯度公式 , 对SoftMax loss function 有了深入的了解
  • 通过本次实验 , 手动构建了三层神经网络 , 直观体会了每一层的 Input 和 W ,b , Output 的关系 , 特别是维度之间的联系
  • 手动推导了多层神经网络的链式法则
  • 手动进行了bp过程
  • 手动进行了调参(有点玄学)
  • 这种通过在有基本框架的基础上补全代码的实验形式,能让我们学到很多东西,就是比较费时间

实验过程中遇到的问题和解决方法

  • 实验过程中遇到的主要问题就是不会求梯度,一开始无从下手

    • 因为先做的SVMSVMSVM , 在SVMSVMSVM中遇到求梯度的问题 , 去搜博客,然后手推并总结
    • 在做完SVMSVMSVM去做SoftMaxSoftMaxSoftMax时,仿照SVMSVMSVM的思想,直接手推就好了
  • 在做三层神经网络的时候,遇到了这个问题 , 不理解这个内积是干什么用的,在求对第二层的导数的时候,为什么用的都是第三层的量

    delta2 = np.dot(dscores , W3.T) * mask
    
    • 后面通过与同学讨论,了解到这一步就是链式法则
    • 然后再了解了这一步是链式法则的基础上,想明白了第二层 + ReLu的输出就是第三层的输入X3X_3X3​ 那 dscoresdscoresdscores 是 totlosstot_losstotl​oss对scores的梯度,scores=X3W3+b3scores = X_3W_3 + b_3scores=X3​W3​+b3​ , 这里出现W3W_3W3​ 刚好是scores对 X3X_3X3​ 的导数 , 这就搞明白了每一层的梯度和链式法则

cs231n Assignment1--机器学习基本方法与深度学习尝试相关推荐

  1. 黄海广博士的机器学习个人笔记及深度学习笔记

    想要下载黄海广博士的机器学习个人笔记及深度学习笔记的请复制下面链接 https://download.csdn.net/download/wgllovemother/10447758 备注:有想下载  ...

  2. 机器学习笔记——神经网络与深度学习

    机器学习笔记--神经网络与深度学习 一.神经网络引言 二.神经元模型与激活函数 2.1 神经元模型 2.2 激活函数 2.2.1 sigmoid & tanh 2.2.2 ReLU激活函数 2 ...

  3. 机器学习技术:使用深度学习处理文本

    到目前为止,我们已经探索了机器学习在各种环境中的应用-- 主题建模.聚类.分类.文本摘要,甚至POS标记和NER标记都是使用机器学习进行训练的.本章我们将开始探索一种前沿的机器学习技术:深度学习.深度 ...

  4. 什么是人工智能?什么是机器学习?什么是深度学习?三连问

    人工智能 人工智能 机器学习 有监督学习 无监督学习 半监督学习 强化学习 深度学习 神经网络 三者之间的关系  最近机器学习,深度学习频繁出现人工智能领域,成为高频词汇,但是好多同学对这些同学一知半 ...

  5. 传统的机器学习目标检测和深度学习的目标检测

    概述: 目标分类:给一张图片,分类 目标检测:给一张图片,找到目标,并用矩形框画出 分类是对一幅图整体,检测是更进一步,找出一幅图中一部分.一般检测以分类为基础, 如用滑动窗口搜索,然后用分类器分类是 ...

  6. 剖析大数据、人工智能、机器学习、神经网络、深度学习五者之区别与联系

    1 引言 当下时代,无论你是否专业于CS,想必都应当听过大数据.人工智能.机器学习.神经网络与深度学习这几个热词.他们区别明显却又联系紧密,有些互有交集,有些又是另一部分的子集.基于上述原因,现作文一 ...

  7. 读懂人工智能、机器学习、神经网络和深度学习的关系

    最近很长的一段时间,人工智能的热度都维持在一定的高度.但是大家在关注或研究人工智能领域的时候,总是会遇到这样的几个关键词:深度学习.机器学习.神经网络.那他们之间到底是什么样的关系呢? 先说人工智能, ...

  8. 探讨使用UML设计机器学习特征工程与深度学习建模等大数据分析软件

    大数据人工智能软件产品研发,是在传统软件工程的基础上,增加了数据特征分析.人工智能算法建模及模型训练过程,同时也增加了很大的不确定性. 0. 前言 本文以程序员视角,以客户流失为案例,使用UML方式设 ...

  9. 机器学习如何选择模型 机器学习与数据挖掘区别 深度学习科普

    今天看到这篇文章里面提到如何选择模型,觉得非常好,单独写在这里. 更多的机器学习实战可以看这篇文章:http://www.cnblogs.com/charlesblc/p/6159187.html 另 ...

最新文章

  1. html当作附件发送,MIME以HTML文件作为附件发送电子邮件?
  2. 小程序canvas的一个坑
  3. Debian 编译内核全过程[转]
  4. 高端企业级存储IBM XIV访谈视频
  5. 节点式光端机与点对点式光端机的区别
  6. 图论 —— 网络流 —— 最大流 —— Dinic 算法
  7. 文件磁盘相关函数[11]-获取指定文件的版本号 GetFileVersion
  8. 专网网速测试软件,wlan网络测试项目和方法 常用测试软件介绍.ppt
  9. 【机械臂】六轴六自由度机械臂轨迹跟踪的matlab实现(基于速度雅各比矩阵方法)
  10. 【报错】paddle相关报错和处理方法
  11. 两个服务共用一个微信支付
  12. 戴尔服务器的性能,解析戴尔12G服务器主要性能提升和改进
  13. juju debug hacks (by quqi99)
  14. MEM/MBA数学基础(04)方程 函数 不等式
  15. Android手机fc模拟器,安卓fc模拟器
  16. 批量删除 txt 记事本文本文件中的某一行或一些行
  17. vivado代码编写——倍频(使用IP核)
  18. mysql mdl 锁_MySQL源码学习:MDL字典锁
  19. 关于TVS管的选型和应用
  20. 专访光庭:传统测绘与众包模式融合,高精地图呼唤新的算法与平台

热门文章

  1. 我“胡汉三”又回来了。
  2. 4T磁盘只有2T可用,将mbr转为gpt安装操作系统。
  3. Spring 事务的传播属性
  4. 组建实验室仅3年,团队人均26岁!这位85后女博导成果登上Nature!
  5. 现代企业管理笔记——管理概论
  6. android界面设计的解剖,ps cc 2017启动画面的制作解剖
  7. 达梦数据库DCA培训笔记(基于dm8)
  8. 人类历史上第一个推荐系统
  9. 教育邮箱怎么申请?国际教育电子邮箱
  10. T3出行快手首秀直播PK赛项目总曝光破亿