在softmax层之前提取输出,然后手动计算softmax会得出不同的结果

时间:2019-09-24 13:39:29

标签: python-2.7 machine-learning keras entropy 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()时,得到的结果与初始Model相同。

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?

我已经绕了这个圈,所以任何帮助或见解将不胜感激。如果有任何不清楚的地方,请告诉我。谢谢!

1 个答案:

答案 0 :(得分:1)

{ "name": "my-app", "version": "0.1.0", "private": true, "dependencies": { "@material-ui/core": "^4.4.2", "antd": "^3.23.3", "axios": "^0.19.0", "bootstrap": "^4.3.1", "react": "^16.9.0", "react-bootstrap": "^1.0.0-beta.12", "react-dom": "^16.9.0", "react-js-pagination": "^3.0.2", "react-paginate": "^6.3.0", "react-router": "^5.0.1", "react-router-dom": "^5.0.1", "react-scripts": "3.1.1", "reactstrap": "^8.0.1" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } } 不会立即生效。您需要再次运行model.pop(),以重新编译不包含最后一层的新模型。

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

此外,您的模型没有softmax作为单独的图层,因此model.predict()离开了整个最后的pop图层。要解决此问题,请将softmax添加为单独的图层,如下所示:

Dense