了解 softmax 分类器
Understanding softmax classifier
我试图从这个 link - CS231n - Convolutional Neural Networks for Visual Recognition 中理解 Softmax classifier 的简单实现。他们在这里实现了一个简单的 softmax classifier。在 link 上的 Softmax 分类器示例中,二维 space 上有随机的 300 个点以及与它们关联的标签。 softmax classifier 将学习哪个点属于哪个 class。
这里是 softmax classifier 的完整代码。或者你可以看看我提供的link
# initialize parameters randomly
W = 0.01 * np.random.randn(D,K)
b = np.zeros((1,K))
# some hyperparameters
step_size = 1e-0
reg = 1e-3 # regularization strength
# gradient descent loop
num_examples = X.shape[0]
for i in xrange(200):
# evaluate class scores, [N x K]
scores = np.dot(X, W) + b
# compute the class probabilities
exp_scores = np.exp(scores)
probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True) # [N x K]
# compute the loss: average cross-entropy loss and regularization
corect_logprobs = -np.log(probs[range(num_examples),y])
data_loss = np.sum(corect_logprobs)/num_examples
reg_loss = 0.5*reg*np.sum(W*W)
loss = data_loss + reg_loss
if i % 10 == 0:
print "iteration %d: loss %f" % (i, loss)
# compute the gradient on scores
dscores = probs
dscores[range(num_examples),y] -= 1
dscores /= num_examples
# backpropate the gradient to the parameters (W,b)
dW = np.dot(X.T, dscores)
db = np.sum(dscores, axis=0, keepdims=True)
dW += reg*W # regularization gradient
# perform a parameter update
W += -step_size * dW
b += -step_size * db
我不明白他们是如何计算这里的梯度的。我假设他们在这里计算了梯度 -
dW = np.dot(X.T, dscores)
db = np.sum(dscores, axis=0, keepdims=True)
dW += reg*W # regularization gradient
但是怎么办?我的意思是为什么 dW
的梯度是 np.dot(X.T, dscores)
?为什么 db
的梯度是 np.sum(dscores, axis=0, keepdims=True)
?那么他们如何计算权重和偏差的梯度呢?还有他们为什么计算 regularization gradient
?
我刚刚开始学习卷积神经网络和深度学习。我听说 CS231n - Convolutional Neural Networks for Visual Recognition
是一个很好的起点。我不知道在哪里放置深度学习相关的post。所以,我把它们放在 Whosebug 上。如果有任何地方 post 与深度学习相关的问题,请告诉我。
此处开始计算梯度:
# compute the gradient on scores
dscores = probs
dscores[range(num_examples),y] -= 1
dscores /= num_examples
首先,这设置 dscores
等于 softmax 函数计算的概率。然后,它从第二行中为正确 类 计算的概率中减去 1
,然后除以第三行中的训练样本数。
为什么要减去1
?因为理想情况下,您希望正确标签的概率为 1
。所以它从它实际预测的东西中减去它应该预测的东西:如果它预测的东西接近 1
,减法将是一个很大的负数(接近于零),所以梯度会很小,因为你是接近解决方案。否则,它将是一个很小的负数(远离零),因此梯度会更大,您将朝着解决方案迈出更大的步伐。
你的激活函数很简单 w*x + b
。它关于 w
的导数是 x
,这就是为什么 dW
是 x
和分数/输出层的梯度之间的点积。
w*x + b
关于b
的导数是1
,这就是为什么你在反向传播时简单地求和dscores
。
梯度下降
反向传播是为了降低整个系统(这里是softmax分类器)的成本J
,优化权重参数W
使成本最小化是个问题。假设成本函数 J = f(W)
是 凸 ,梯度下降 W = W - α * f'(W)
将导致 Wmin
最小化 J
。超参数 α
称为 学习率 我们也需要对其进行优化,但不在此答案中。
Y
在图中应读作 J
。假设你在一个形状定义为 J = f(W)
的地方的表面上,你需要到达点 Wmin
。没有重力,所以你不知道哪条路通向底部,但你知道函数和你的坐标。你怎么知道你应该走哪条路?你可以从导数f'(W)
找到方向并移动到一个新的坐标W = W - α * f'(W)
。如此反复,就可以越来越接近Wmin
.
点
仿射层的反向传播
在乘法或点运算发生的节点(仿射),函数为J = f(W) = X * W
。假设有m
个固定的二维坐标表示为X。我们如何找到最小化J = f(W) = X * W
的超平面及其向量W
?
如果α合适,我们可以通过重复梯度下降W += -α * X
来接近最优W
。
链式法则
当softmax分类器中Affine层之后有softmax层和log loss层等层时,我们可以用链式法则计算梯度。在图中,将 sigmoid 替换为 softmax.
如cs321页面Computing the Analytic Gradient with Backpropagation所述,softmax层和log loss层的梯度贡献是 dscore 部分。也请参阅下面的注释部分。
通过链式法则将梯度应用于仿射层,推导出代码,其中α被替换为step_size。其实step_size也是需要学习的
dW = np.dot(X.T, dscores)
W += -step_size * dW
偏差梯度可以通过将链式法则应用于偏差 b 以及来自 [= 的梯度 (dscore) 148=]层。
db = np.sum(dscores, axis=0, keepdims=True)
正则化
如cs231页面Regularization所述,成本函数(objective)通过加入正则化调整,即reg_loss 在代码中。就是为了减少过拟合。根据我的理解,直觉是,如果特定特征导致过度拟合,我们可以通过使用权重参数 W 来增加成本来减少它,因为梯度下降将减少权重的成本贡献。由于我们不知道哪些,所以使用所有 W。 0.5 * W*W 的原因是因为它给出了简单的导数 W.
reg_loss = 0.5*reg*np.sum(W*W)
梯度贡献reg*W
来自reg_loss的导数。 reg是真正训练中需要学习的超参数。
reg_loss/dw -> 0.5 * reg * 2 * W
它被添加到仿射之后的层的渐变中。
dW += reg*W # regularization gradient
在post中引用的cs231页面中省略了从包含正则化的成本中获取导数的过程,可能是因为通常的做法是只放置正则化的梯度,但令人困惑对于那些正在学习的人。有关正则化的信息,请参阅 Andrew Ng 的 Coursera Machine Learning Week 3 Cost Function。
备注
偏移参数 b 被替换为 X0 因为偏移可以通过转移到基数来省略。
我试图从这个 link - CS231n - Convolutional Neural Networks for Visual Recognition 中理解 Softmax classifier 的简单实现。他们在这里实现了一个简单的 softmax classifier。在 link 上的 Softmax 分类器示例中,二维 space 上有随机的 300 个点以及与它们关联的标签。 softmax classifier 将学习哪个点属于哪个 class。
这里是 softmax classifier 的完整代码。或者你可以看看我提供的link
# initialize parameters randomly
W = 0.01 * np.random.randn(D,K)
b = np.zeros((1,K))
# some hyperparameters
step_size = 1e-0
reg = 1e-3 # regularization strength
# gradient descent loop
num_examples = X.shape[0]
for i in xrange(200):
# evaluate class scores, [N x K]
scores = np.dot(X, W) + b
# compute the class probabilities
exp_scores = np.exp(scores)
probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True) # [N x K]
# compute the loss: average cross-entropy loss and regularization
corect_logprobs = -np.log(probs[range(num_examples),y])
data_loss = np.sum(corect_logprobs)/num_examples
reg_loss = 0.5*reg*np.sum(W*W)
loss = data_loss + reg_loss
if i % 10 == 0:
print "iteration %d: loss %f" % (i, loss)
# compute the gradient on scores
dscores = probs
dscores[range(num_examples),y] -= 1
dscores /= num_examples
# backpropate the gradient to the parameters (W,b)
dW = np.dot(X.T, dscores)
db = np.sum(dscores, axis=0, keepdims=True)
dW += reg*W # regularization gradient
# perform a parameter update
W += -step_size * dW
b += -step_size * db
我不明白他们是如何计算这里的梯度的。我假设他们在这里计算了梯度 -
dW = np.dot(X.T, dscores)
db = np.sum(dscores, axis=0, keepdims=True)
dW += reg*W # regularization gradient
但是怎么办?我的意思是为什么 dW
的梯度是 np.dot(X.T, dscores)
?为什么 db
的梯度是 np.sum(dscores, axis=0, keepdims=True)
?那么他们如何计算权重和偏差的梯度呢?还有他们为什么计算 regularization gradient
?
我刚刚开始学习卷积神经网络和深度学习。我听说 CS231n - Convolutional Neural Networks for Visual Recognition
是一个很好的起点。我不知道在哪里放置深度学习相关的post。所以,我把它们放在 Whosebug 上。如果有任何地方 post 与深度学习相关的问题,请告诉我。
此处开始计算梯度:
# compute the gradient on scores
dscores = probs
dscores[range(num_examples),y] -= 1
dscores /= num_examples
首先,这设置 dscores
等于 softmax 函数计算的概率。然后,它从第二行中为正确 类 计算的概率中减去 1
,然后除以第三行中的训练样本数。
为什么要减去1
?因为理想情况下,您希望正确标签的概率为 1
。所以它从它实际预测的东西中减去它应该预测的东西:如果它预测的东西接近 1
,减法将是一个很大的负数(接近于零),所以梯度会很小,因为你是接近解决方案。否则,它将是一个很小的负数(远离零),因此梯度会更大,您将朝着解决方案迈出更大的步伐。
你的激活函数很简单 w*x + b
。它关于 w
的导数是 x
,这就是为什么 dW
是 x
和分数/输出层的梯度之间的点积。
w*x + b
关于b
的导数是1
,这就是为什么你在反向传播时简单地求和dscores
。
梯度下降
反向传播是为了降低整个系统(这里是softmax分类器)的成本J
,优化权重参数W
使成本最小化是个问题。假设成本函数 J = f(W)
是 凸 ,梯度下降 W = W - α * f'(W)
将导致 Wmin
最小化 J
。超参数 α
称为 学习率 我们也需要对其进行优化,但不在此答案中。
Y
在图中应读作 J
。假设你在一个形状定义为 J = f(W)
的地方的表面上,你需要到达点 Wmin
。没有重力,所以你不知道哪条路通向底部,但你知道函数和你的坐标。你怎么知道你应该走哪条路?你可以从导数f'(W)
找到方向并移动到一个新的坐标W = W - α * f'(W)
。如此反复,就可以越来越接近Wmin
.
仿射层的反向传播
在乘法或点运算发生的节点(仿射),函数为J = f(W) = X * W
。假设有m
个固定的二维坐标表示为X。我们如何找到最小化J = f(W) = X * W
的超平面及其向量W
?
如果α合适,我们可以通过重复梯度下降W += -α * X
来接近最优W
。
链式法则
当softmax分类器中Affine层之后有softmax层和log loss层等层时,我们可以用链式法则计算梯度。在图中,将 sigmoid 替换为 softmax.
如cs321页面Computing the Analytic Gradient with Backpropagation所述,softmax层和log loss层的梯度贡献是 dscore 部分。也请参阅下面的注释部分。
通过链式法则将梯度应用于仿射层,推导出代码,其中α被替换为step_size。其实step_size也是需要学习的
dW = np.dot(X.T, dscores)
W += -step_size * dW
偏差梯度可以通过将链式法则应用于偏差 b 以及来自 [= 的梯度 (dscore) 148=]层。
db = np.sum(dscores, axis=0, keepdims=True)
正则化
如cs231页面Regularization所述,成本函数(objective)通过加入正则化调整,即reg_loss 在代码中。就是为了减少过拟合。根据我的理解,直觉是,如果特定特征导致过度拟合,我们可以通过使用权重参数 W 来增加成本来减少它,因为梯度下降将减少权重的成本贡献。由于我们不知道哪些,所以使用所有 W。 0.5 * W*W 的原因是因为它给出了简单的导数 W.
reg_loss = 0.5*reg*np.sum(W*W)
梯度贡献reg*W
来自reg_loss的导数。 reg是真正训练中需要学习的超参数。
reg_loss/dw -> 0.5 * reg * 2 * W
它被添加到仿射之后的层的渐变中。
dW += reg*W # regularization gradient
在post中引用的cs231页面中省略了从包含正则化的成本中获取导数的过程,可能是因为通常的做法是只放置正则化的梯度,但令人困惑对于那些正在学习的人。有关正则化的信息,请参阅 Andrew Ng 的 Coursera Machine Learning Week 3 Cost Function。
备注
偏移参数 b 被替换为 X0 因为偏移可以通过转移到基数来省略。