softmax 回归的从零开始实现 讨论区


#171

请问练习里的这两个问题有什么解决方案?我实在没想到,因为第一个exp(50)好大好大,第二个问题,ln定义域必须大于0,但根本不可能小于0啊,因为损失函数出来的值根本不会小于等于0啊

本节中,我们直接按照 softmax 运算的数学定义来实现 softmax 函数。这可能会造成什么
问题?(提⽰:试⼀试计算exp(50)的⼤小。)
• 本节中的 cross_entropy函数是按照交叉熵损失函数的数学定义实现的。这样的实现⽅
式可能有什么问题?(提⽰:思考⼀下对数函数的定义域。)
• 你能想到哪些办法来解决上⾯的两个问题?


#172

第一个问题是将传入的值都变小,如下(纯搬运):

所以代码如下:

def softmax(X):
    X = X-X.max()
    exp_X = X.exp()
    return exp_X/exp_X.sum()

第二个问题我觉得是, log(x) , x非常接近于0会有问题,例如:

def cross_entropy(yhat, y):
    return -nd.pick(yhat, nd.array([1])).log()

def softmax(X):
    X = X-X.max()
    exp_X = X.exp()
    return exp_X/exp_X.sum()

X = nd.array([[5000, 1, 5, 3]])
yhat = softmax(X)
y = nd.array([1])
cross_entropy(yhat, y) # 输出为 [inf]

不过第二个问题怎么解决,或者是不是不用解决,求大佬解答一下。


#173

评论中关于交叉熵损失函数的含义链接打不开啦,显示404,可以再发一下吗? 谢谢啦!


#174

http://zh.diveintodeeplearning.org/chapter_deep-learning-basics/softmax-regression.html#交叉熵损失函数


#175

收到,谢谢!


#176

第二个问题主要是因为log()函数中出现了零值,因此在计算交叉熵时,在log()中加一极小值,如
log(x+e-5)


#177

定义模型

def net(X):
return softmax(nd.dot(X.reshape((-1, num_inputs)), W) + b)

我想问一下这个模型中的权重W,b为什么不通过形参传入,有什么考虑?


#178

发现gluon的softmaxentropyloss没有像pytorch的crossentropyloss那样考虑到语义分割中样本类别分布不平衡的问题,也就是没有类别权重的参数,虽然自己也能做一个weight的mask,但是那样太繁琐,希望接下来update的时候能够考虑到这个问题!


#179

这里可以设置权重

下面有个相关的例子:
http://zh.diveintodeeplearning.org.s3-website-us-west-2.amazonaws.com/chapter_natural-language-processing/word2vec-gluon.html#二元交叉熵损失函数

In [19]:

loss = gloss.SigmoidBinaryCrossEntropyLoss()

值得一提的是,我们可以通过掩码变量指定小批量中参与损失函数计算的部分预测值和标签:当掩码为 1 时,相应位置的预测值和标签将参与损失函数的计算;当掩码为 0 时,相应位置的预测值和标签则不参与损失函数的计算。我们之前提到,掩码变量可用于避免填充项对损失函数计算的影响。

In [20]:

pred = nd.array([[1.5, 0.3, -1, 2], [1.1, -0.6, 2.2, 0.4]]) # 标签变量 label 中的 1 和 0 分别代表背景词和噪音词。

label = nd.array([[1, 0, 0, 0], [1, 1, 0, 0]]) 

mask = nd.array([[1, 1, 1, 1], [1, 1, 1, 0]]) # 掩码变量。 

loss(pred, label, mask) * mask.shape[1] / mask.sum(axis=1)

Out[20]:

[0.8739896 1.2099689] <NDArray 2 @cpu(0)>


#180

谢谢!利用mask的思想我也了解,您说的softmaxentropyloss里可以 设置weight,但是我看_apply_weighting里的源码weight的type是一个float的number,不清楚这个weight代表什么。我是计算出来所有样本n个类别像素的权重,得到一个1n的ndarray,在gluon里有米有办法直接利用这个n1的ndarray对loss进行加权?


#181

可能是测试集比训练集的特征更明显?如果再迭代多次,并逐步减少学习率,就会发现最终训练集的正确率会比测试集的高。


#182

有两个问题:

  1. 按这种算法,逐步迭代并降低学习率之后会发现正确率是有一个上界的,为什么正确率会出现上界而不是收敛到1呢?

  2. X矩阵为什么要定义成 1 x 784 而不是 28 x 28 呢?如果进一步把 W 矩阵改成 28 x 10 ,这种算法的正确率的上界是不是会下降很多呢?

其实第2个问题我是想验证我对问题1的猜测:可能是与W矩阵的维数有关。增加维数的话应该会使训练集的正确率的上界继续上升直到1,反之则下降。

ps:但是增加维数我又不会,把W改成28 x 28在evaluate_accuracy又会出现错误,所以很尴尬。

顺便,这个课程有视频教学吗?

期待各位大神的解答。


#183

练习的第一个问题,让每个样本的每类预测结果减去最大的那个值再求exp似乎就能解决
第二个问题我死活想不出来……我觉得概率是用exp算出来的,怎么样定义域也是在(0,1)之内吧?顶多过小的概率使得log之后的值过大,但就算是这个问题我也不知道该怎么解决……


#184

另外我发现,计算loss的时候,每次迭代首先求了一次平均值(当前batch的平均损失),然后最后把每个batch的平均损失加起来再求平均(除以batch的数量),如果batch_size不能整除总的样本数,这样求平均不科学吧?


#185

accuracy那里的代码说标签需要转换成浮点数,但是python里面值相同的浮点数和整数进行“==”运算应该会返回True吧,那么还有别的理由需要这样转换类型吗?


#186

谢谢。本来考虑代码简洁所以用了近似计算。权衡了一下,还是决定准确计算了:

ndarray不能比较int32和float32


#187

请问,练习中的第二个思考问题有解答的吗?


#189

for X, y in test_iter:
break
请问这段代码什么意思???


#190

请问一下为什么这个是全0的是不成功吗?
而且,我第一次可以进入for循环,之后如果再for循环就会无响应,显示[*]


#191

为啥我搜了一遍整个文章,都没看到你说的这行代码?是在哪里啊?