Преобразование активации вывода с помощью Softmax дает аналогичные значения.

Я обучил простую рекуррентную сеть (62 единицы ввода, 124 скрытых/контекстных единицы, 62 единицы вывода) предсказывать следующее слово в предложении. Я использовал сигмовидную функцию активации. По каким-то разным и странным причинам применять софтмакс во время тренировки не получалось. Мой профессор предположил, что я мог бы впоследствии применить softmax к выходу сети. Матрица имеет 576 строк и 62 столбца. Итак, я реализовал softmax в R следующим образом:

softmax <- function(outVec = NULL){
  s.vec <- exp(outVec)/sum(exp(outVec))
  return(s.vec)
}

softmax_complete <- function(vec = NULL){
  softmaxed.vec <- matrix(apply(vec, 1, softmax), ncol=dim(vec)[2], nrow=dim(vec)[1])
  return(softmaxed.vec)
}

Каждая строка матрицы, которую возвращает softmax_complete(), правильно суммируется с 1. Проблема в том, что для каждой строки моя функция производит значения, которые очень похожи друг на друга. Невозможно проверить производительность сети, потому что значения почти «одинаковые».

Вот небольшой пример данных. Это со второго ряда выхода сетей. Softmax еще не применялся.

output.vec <- c(0.2371531427, 0.0085829534, 0.0007576860, 0.0027021256, 0.0025776778, 0.0014593119, 0.0019006504, 0.0403518006,
                0.0024586972, 0.0517364480, 0.0012057235, 0.0950696915, 0.0025749709, 0.0008823058, 0.0005064047, 0.0014039490,
                0.0013259919, 0.0014723240, 0.0011820868, 0.0011805159, 0.0009319001, 0.0022884205, 0.0023589570, 0.0020189525,
                0.0015377736, 0.0937648788, 0.0012874968, 0.0443032309, 0.0012919122, 0.0897148922, 0.0022041877, 0.0444274731,
                0.0014143962, 0.0361100733, 0.0020817134, 0.0447632931, 0.0009620183, 0.0011552101, 0.0016173105, 0.0016870035,
                0.0011272663, 0.0019183536, 0.0017270016, 0.0011056620, 0.0007743868, 0.0026786255, 0.0019340677, 0.0010532230,
                0.0014585924, 0.0386148430, 0.0012295874, 0.0390544645, 0.0017903288, 0.0967107117, 0.0013074477, 0.0006164946,
                0.0001758277, 0.0001023397, 0.0004014068, 0.0004558225, 0.0003554984, 0.0001830685)

Когда я применяю softmax к этой строке, я получаю следующие результаты:

[1] 0.01585984 0.01583950 0.01567646 0.01583540 0.01735750 0.01579704 0.01587178 0.01589101 0.01586093 0.01590457
[11] 0.01586255 0.01637181 0.01590217 0.01584308 0.01570456 0.01581733 0.01952223 0.01590497 0.01970620 0.01578586
[21] 0.01610417 0.01591379 0.01588095 0.01584309 0.01567710 0.01582956 0.01650858 0.01573117 0.01589502 0.01608836
[31] 0.01574208 0.01582079 0.01584367 0.01569571 0.01583481 0.01596172 0.01577246 0.01586151 0.01605467 0.01574746
[41] 0.01586397 0.01581472 0.01576479 0.01580914 0.01583660 0.01566672 0.01584366 0.02017004 0.01585517 0.02007705
[51] 0.01580263 0.01583277 0.01580424 0.01583763 0.01587117 0.01568283 0.01583775 0.01595945 0.01587471 0.01575585
[61] 0.01584288 0.01577770

Сумма строки равна 1.000703. А для другой строки, которая не изображена в приведенном выше примере, сумма строк равна 0,9976472. Что я делаю не так?

Может быть, у вас, ребята, есть идея решить эту проблему. Заранее спасибо за ваше время и помощь :-)

С уважением, Матиас

РЕДАКТИРОВАТЬ:

Вот как я создаю сеть Elman Net от RSNNS:

elman<-rsnnsObjectFactory(subclass=c("elman"), nInputs=inputNeurons, maxit=maxIterations, 
                     initFunc="JE_Weights", initFuncParams=c(0.15, -0.15, 0, 1.0, 0.5), 
                     learnFunc="JE_BP", learnFuncParams=c(learnRate),
                     updateFunc="JE_Order", updateFuncParams=c(0),
                     shufflePatterns=FALSE, computeIterativeError=FALSE) 
  elman$archParams <- list(size=hiddenNeurons)
  elman$snnsObject$elman_createNet(c(inputNeurons, hiddenNeurons, outputNeurons),c(1,1,1),FALSE)
  elman$snnsObject$initializeNet(c(0.15, -0.15, 0, 1.0, 0.5), initFunc="JE_Weights") 
  elman$snnsObject$setUnitDefaults(1,0,1,0,1,"Act_Logistic","Out_Identity")
  elman$snnsObject$setTTypeUnitsActFunc("UNIT_INPUT", "Act_Logistic")
  elman$snnsObject$setTTypeUnitsActFunc("UNIT_SPECIAL_H", "Act_Identity")
  elman$snnsObject$setTTypeUnitsActFunc("UNIT_OUTPUT", "Act_Logistic")

person matze    schedule 02.08.2016    source источник


Ответы (1)


Более краткая версия softmax будет выглядеть так:

softmax <- function(x){
  score.exp <- exp(x)
  probs <-sweep(score.exp, 1, rowSums(score.exp), '/')
  return(probs)
}

в который вы теперь можете передать матрицу напрямую. Теперь, глядя на предоставленный вами вектор.

res <- softmax(matrix(output.vec, nrow=1))
sum(res)
[1] 1

Тем не менее, по-прежнему кажется, что в ваших значениях нет большой разницы. Мне кажется, что для этого конкретного образца это не так много информации, предоставленной вашим RNN. В соответствии с этим наиболее вероятным «классом» является первый класс с вероятностью 2%.

Я бы порекомендовал попробовать это на всем наборе данных, используя функцию выше.

Все это предполагает многое в вашей реализации нейронной сети. Было бы полезно, если бы вы могли предоставить ссылку на программное обеспечение, которое вы использовали, и, по крайней мере, какие параметры вы устанавливали.

person cdeterman    schedule 02.08.2016
comment
Большое спасибо за ваш ответ. Для построения сети я использую Stuttgart Neuronal Network Simulator for R (RSNNS). Веса генерируются случайным образом в диапазоне от -0,15 до 0,15. Скорость обучения была установлена ​​на 0,1. Я использовал стандартное обратное распространение для обучения, но без кросс-энтропии (в настоящее время она не предоставляется RSNNS). Функция активации для скрытых, входных и выходных единиц является сигмовидной, а для контекстных единиц - ее идентичностью. - person matze; 02.08.2016
comment
Входные данные предоставляются в матрице с ортогональными строками. Каждый столбец представляет одно слово, строка представляет слово в предложении. Только один бит в строке активен (1) и помечает это конкретное слово. Остальные в этой строке равны нулю. Я попробовал ваше решение, но получил те же результаты. Причина, по которой я хочу использовать softmax, заключается в том, что у меня есть сумма некоторых значений, равная 1, поэтому я не могу использовать логарифмические шансы для своей смешанной линейной модели. - person matze; 02.08.2016
comment
@matze Можете ли вы просто предоставить фактический звонок? Я предполагаю, что вы используете RSNNS::mlp? - person cdeterman; 02.08.2016
comment
Когда я измеряю производительность сети без softmax, я получаю полезные результаты. Я использую формулу Grammatical Prediction Error (Christiansen & Chater, 1999). Он учитывает попадания, промахи и ложные тревоги и сравнивает их с вероятностями слов, сгенерированными контекстно-свободным грамматиком (SLG, Rohde, 1999). Но некоторые значения, как я упоминал выше, дают в сумме >1, и у меня есть опасения, что результаты нельзя интерпретировать как вероятности, и из-за этого я могу сделать ложный вывод. - person matze; 02.08.2016
comment
Я отредактировал свой вопрос, чтобы показать полный вызов функции для создания сети elman с помощью RSNNS. - person matze; 02.08.2016
comment
Я думаю, это может быть потому, что вы применяете функцию Act_Logistic к выходному слою. Я думаю, что это должны быть необработанные значения до использования softmax, чтобы он работал правильно. - person cdeterman; 03.08.2016
comment
Спасибо за ваш ответ. Может быть, я попробую функцию идентификации на выходном слое и потом применю softmax. Вы думаете, что подход с логистической функцией искажает мои данные? Есть ли большая разница между логистикой и softmax соответственно для анализа результатов для интерпретации? - person matze; 03.08.2016
comment
Основное отличие состоит в том, что выходные данные softmax можно напрямую интерпретировать как вероятности для классификации. Метод logistic больше подходит для решения проблемы регрессии. - person cdeterman; 03.08.2016