跑代码,softmax
最开始,写softmax_loss_naive用循环求loss和gradient
softmax分类器使用交叉熵loss,公式为
编程实现时候稍微利用了广播,10个分数一起算的
for i in range(num_train):
scores = X[i].dot(W)
scores -= max(scores)#避免溢出
scores = np.exp(scores) / np.sum(np.exp(scores))
loss += - np.log(scores[y[i]])
为什么初始计算出来的loss约等于0.1
因为初始W约等于0,按照公式计算,相当于
求导计算上面的公式,得到梯度,过程很多,但是最后基本上都约掉了
if j == y[i]:
dW[:,j] += (qj - 1) * X[i]
else:
dW[:,j] += qj * X[i]
qj是log里面那部分
接下来向量化
scores = X.dot(W)
scores -= np.max(scores, axis=1, keepdims=True)
scores = np.exp(scores) / np.sum(np.exp(scores), axis=1, keepdims=True)
dW = np.copy(scores)
dW[range(num_train),y] -= 1
dW = X.T.dot(dW)
loss -= np.log(scores[range(num_train),y])
loss = np.sum(loss)
这里注意:dW[range(num_train),y]和dW[:,y]并不一样,shape分别是(500,) 和(500, 500)
第一种是每次是第i行和y[i]构成元组,取dW[i,y[i]],第二种是所有行和y[i]
剩下的部分和svm类似