Извлечение выходных данных перед слоем softmax, затем ручной расчет softmax дает другой результат - PullRequest
0 голосов
/ 24 сентября 2019

У меня есть модель, обученная классифицировать значения 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 для проверки 2-го результата и получаю почти идентичный ответ на Pop1.

  4. Pop3 Однако, когда я просто вычисляю getinfo () на выходе model.pop () без функции softmax, я получаю тот же результат, что и исходная модель.

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.Интересно, проблема в вычислениях softmax после model.predict?И получаю ли я один и тот же результат в Model и Pop3, потому что softmax ограничивает значения между 0-1, так что для функции getinfo () результат математически эквивалентен?

Если это так, то как мне выполнить softmax до model.predict?

Я ходил по кругу с этим, поэтому любая помощь или понимание будет высоко ценится.Пожалуйста, дайте мне знать, если что-то неясно.Спасибо!

1 Ответ

1 голос
/ 24 сентября 2019

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
...