首页 > 解决方案 > 在 softmax 层之前提取输出,然后手动计算 softmax 会得到不同的结果

问题描述

我有一个经过训练的模型,可以将 rgb 值分类为 1000 个类别。

#Model architecture
model = Sequential()
model.add(Dense(512,input_shape=(3,),activation="relu"))
model.add(BatchNormalization())
model.add(Dense(512,activation="relu"))
model.add(BatchNormalization())
model.add(Dense(1000,activation="relu"))
model.add(Dense(1000,activation="softmax"))

我希望能够在 softmax 层之前提取输出,这样我就可以对模型中的不同类别样本进行分析。我想为每个样本执行 softmax,并使用名为 getinfo() 的函数进行分析。

  1. 模型 最初,我将 X_train 数据输入到 model.predict 中,以获得每个输入的 1000 个概率的向量。我在这个数组上执行 getinfo() 以获得所需的结果。

  2. Pop1 然后我使用 model.pop() 删除 softmax 层。我得到弹出模型的新预测,并执行 scipy.special.softmax。然而, getinfo() 在这个数组上产生一个完全不同的结果。

  3. Pop2 我编写了自己的 softmax 函数来验证第二个结果,我收到了与 Pop1 几乎相同的答案。

  4. Pop3 但是,当我在没有 softmax 函数的情况下对 model.pop() 的输出简单地计算 getinfo() 时,我得到的结果与初始模型相同。

data = np.loadtxt("allData.csv",delimiter=",")
model = load_model("model.h5")

def getinfo(data):
    objects = scipy.stats.entropy(np.mean(data, axis=0), base=2)
    print(('objects_mean',objects))
    colours_entropy = []
    for i in data:
        e = scipy.stats.entropy(i, base=2)
        colours_entropy.append(e)
    colours = np.mean(np.array(colours_entropy))
    print(('colours_mean',colours))
    info = objects - colours
    print(('objects-colours',info))
    return info

def softmax_max(data):
    # calculate softmax whilst subtracting the max values (axis=1)
    sm = []
    count = 0
    for row in data:
        max = np.argmax(row)
        e = np.exp(row-data[count,max])
        s = np.sum(e)
        sm.append(e/s)
    sm = np.asarray(sm)
    return sm

#model
preds = model.predict(X_train)
getinfo(preds)

#pop1
model.pop()
preds1 = model.predict(X_train)
sm1 = scipy.special.softmax(preds1,axis=1)
getinfo(sm1)

#pop2
sm2 = softmax_max(preds1)
getinfo(sm2)

#pop3
getinfo(preds1)

我希望从 Model、Pop1 和 Pop2 获得相同的输出,但对 Pop3 的答案不同,因为我没有在这里计算 softmax。我想知道在model.predict之后计算softmax是否有问题?我是否在 Model 和 Pop3 中得到相同的结果,因为 softmax 将值限制在 0-1 之间,所以对于 getinfo() 函数,结果在数学上是等价的?

如果是这种情况,那么我如何在model.predict之前执行softmax?

我已经在这个圈子里转了转,所以任何帮助或洞察力将不胜感激。如果有任何不清楚的地方,请告诉我。谢谢!

标签: python-2.7machine-learningkerasentropysoftmax

解决方案


model.pop()不会立即产生效果。您需要model.compile()再次运行以重新编译不包含最后一层的新模型。

如果没有重新编译,您实际上是model.predict()在完全相同的模型上连续运行两次,这就解释了为什么 Model 和 Pop3 给出相同的结果。Pop1 和 Pop2 给出了奇怪的结果,因为它们正在计算 softmax 的 softmax。

此外,您的模型没有将 softmax 作为单独的层,因此去掉pop了整个最后Dense一层。要解决此问题,请将 softmax 添加为单独的层,如下所示:

model.add(Dense(1000))           # softmax removed from this layer...
model.add(Activation('softmax')) # ...and added to its own layer

推荐阅读