human
I am working on the file "Notebooks/SVM/zh-cn/LinearSVM.ipynb".
The first task is:
通过下面这张动图，我们能够直观地感受极大梯度下降法下 LinearSVM 的训练过程：

可以看到，LinearSVM 确实卡在了奇怪的地方
原理我不敢乱说，这里只提供一个牵强附会的直观解释：

每次只取使得损失函数极大的一个样本进行梯度下降$\rightarrow$模型在某个地方可能来来回回都只受那么几个样本的影响$\rightarrow$死循环（什么鬼！）

专业的理论就留待专业的观众老爷补充吧 ( σ'ω')σ
解决方案
极大梯度下降法的最大问题很有可能在于它每次都只根据使得损失函数最大的一个样本点来进行梯度下降，这会导致两个问题：
+ 模型的训练将会很不稳定（这点和随机梯度下降类似）
+ 模型对噪声或“不太好的点”极为敏感（因为它们往往会使损失函数最大）
按部就班、我们先解决第一个问题，为此我们只需要多选出几个样本点（比如选出使得损失函数最大的 top n 个样本）、然后取它们梯度的平均即可
Top n 梯度下降法

注：该名字同样只是我瞎编的一个名字（喂）
Can you write Python program for it?
assistant
#Here is the Python program you requested.

# 继承上一个 LinearSVM 以重复利用代码
class LinearSVM2(LinearSVM):    
    # 用参数 batch_size 表示 Top n 中的 n
    def fit(self, x, y, c=1, lr=0.01, batch_size=128, epoch=10000):
        x, y = np.asarray(x, np.float32), np.asarray(y, np.float32)
        # 如果 batch_size 设得比样本总数还多、则将其改为样本总数
        batch_size = min(batch_size, len(y))
        self._w = np.zeros(x.shape[1])
        self._b = 0.
        for _ in range(epoch):
            self._w *= 1 - lr
            err = 1 - y * self.predict(x, True)
            # 利用 argsort 函数直接取出 Top n
            # 注意 argsort 的结果是从小到大的，所以要用 [::-1] 把结果翻转一下
            batch = np.argsort(err)[-batch_size:][::-1]
            err = err[batch]
            if err[0] <= 0:
                continue
            # 注意这里我们只能利用误分类的样本做梯度下降
            # 因为被正确分类的样本处、这一部分的梯度为 0
            mask = err > 0
            batch = batch[mask]
            # 取各梯度平均并做一步梯度下降
            delta = lr * c * y[batch]
            self._w += np.mean(delta[..., None] * x[batch], axis=0)
            self._b += np.mean(delta)