Обсуждение статьи "Глубокие нейросети (Часть V). Байесовская оптимизация гиперпараметров DNN" - страница 2

 

Интересные результаты оптимизации - ошибка на валидационной выборке вышла меньше, чем на тренировочной!

Другими словами, модель тренируясь на одних данных, научилась работать на других, т.е. извлекла из тренировочных данных больше информации, чем там ее было на самом деле - это научная фантастика или авантюра...?

Обращаюсь к автору - прекращайте штукарства и подтасовку, напишите наконец советник и покажите какой нибудь результат, хоть на демо.

 
revers45:

Другими словами, модель тренируясь на одних данных, научилась работать на других, т.е. извлекла из тренировочных данных больше информации, чем там ее было на самом деле - это научная фантастика или авантюра...?

Все модели обучались на тренировочном участке, т.е. стремились минимизировать ошибку именно на нем, но в конце отбор делался по тестовому участку, и если бы модель не нашла закономерности в данных, то были бы очень плохими результаты на обучающем или на участке после тестового. Но как показали результаты и там и там они не сильно отличаются от тестового, по которому делался отбор.
Т.е. НС не научилась работать на других, а нашла общие закономерности в обоих наборах данных.
Если бы результаты были менее стабильны, то отбор по тестовому участку (без учета ошибки обучающего) мог бы привести к подгонке под него. В данном случае не привел, но на других данных (если бы не нашлись закономерности) - мог бы. И тогда лучше было бы искать баланс между ошибками типа Err = (ErrLeran * 0.37 + ErrValid * 0.63)

 
elibrarius:

Здравствуйте Владимир,

не совсем понимаю, почему у вас  НС тренируется на обучающих данных, а ее оценка делается на тестовых (если не ошибаюсь вы его используете как валидационный).

Не получится ли в этом случае подгонка под тестовый участок, т.е. будет выбрана модель, которая именно на тестовом участке лучше всего отработала?
Еще надо учесть, что тестовый участок достаточно мал и можно подогнаться под одну из временных закономерностей, которая может перестать работать очень быстро.
Может быть лучше делать оценку на обучающем участке, или на сумме участков, или как в Darch, (при поданных валидационных данных) на Err = (ErrLeran * 0.37 + ErrValid * 0.63) - эти коэффициенты по умолчанию, но их можно менять.

Вариантов много и неясно, какой из них лучше. Интересны ваши аргументы в пользу тестового участка.

Добрый день.

Давайте уточним. Набор данных Х состоит из 4 поднаборов preptrain = 4001, train = 1000, test = 500 и test1= 100 баров. Для претренинга используются обучающий набор - pretrain, валидационный - train. 

# SRBM + upper Layer (backpropagation)
 pretrainSRBM_topLayer <- function(Ln, fact1, fact2, dr1, dr2, Lr.rbm, Lr.top) # SRBM + upper Layer (backpropagation)
  {
    darch( x = X$pretrain$x, y = X$pretrain$y,
          xValid = X$train$x, 
          yValid = X$train$y,
          #=====constant======================
......................................................

Для тонкой настройки в качестве обучающего используется набор train  , а валидационного - первые 250 баров набора test . 

fineTuneRP <- function(Ln, fact1, fact2, dr1, dr2, Dnn) # rpropagation
  {
    darch( x = X$train$x, y = X$train$y,
           #xValid = X$test$x, yValid = X$test$y,
           xValid = X$test$x %>% head(250), 
           yValid = X$test$y %>% head(250),
           #=====constant========
................................................

Поэтому для определения окончательного качества в качестве тестового набора используем последние 250 баров набора test. code

#---SRBM + upperLayer + RP----
  fitnes4.DNN <- function(n1, n2, fact1, fact2, dr1, dr2, Lr.rbm, Lr.top)
  {
    Ln <- c(0, 2*n1, 2*n2, 0)
    #--
    pretrainSRBM_topLayer(Ln, fact1, fact2, dr1, dr2, Lr.rbm, Lr.top) -> Dnn
    fineTuneRP(Ln, fact1, fact2, dr1, dr2, Dnn) -> Dnn
    predict(Dnn, newdata = X$test$x %>% tail(250) , type = "class") -> Ypred
    yTest <- X$test$y[ ,1] %>% tail(250)
    #numIncorrect <- sum(Ypred != yTest)
    #Score <- 1 - round(numIncorrect/nrow(xTest), 2)
    Score <- Evaluate(actual = yTest, predicted = Ypred)$Metrics$F1 %>%
      mean() 
    return(list(Score = Score, Pred = Ypred)
  }

Не вижу противоречий. Согласны?

Удачи

 
elibrarius:

Все модели обучались на тренировочном участке, т.е. стремились минимизировать ошибку именно на нем, но в конце отбор делался по тестовому участку, и если бы модель не нашла закономерности в данных, то были бы очень плохими результаты на обучающем или на участке после тестового. Но как показали результаты и там и там они не сильно отличаются от тестового, по которому делался отбор.
Т.е. НС не научилась работать на других, а нашла общие закономерности в обоих наборах данных.
Если бы результаты были менее стабильны, то отбор по тестовому участку (без учета ошибки обучающего) мог бы привести к подгонке под него. В данном случае не привел, но на других данных (если бы не нашлись закономерности) - мог бы. И тогда лучше было бы искать баланс между ошибками типа Err = (ErrLeran * 0.37 + ErrValid * 0.63)

По любому, общих закономерностей на обучающей участке должно быть не меньше чем на тестовом т.к. они вместе со всеми остальными там же были и найдены, а поэтому и НС на нем не должна работать хуже.

По-моему, это очевидно, так же, как и то, что знания учителя не должны быть меньше чем у ученика, хотя автор статьи, видимо пытается опровергнуть это, поскольку он писал в камментах, что не учёный и не программист, а упорно продолжает учить нас программировать нейросети.

Конечно, он запостил уже очень много R кода, но хотелось бы увидеть и адекватные результаты, а главное понять, сколько ещё он напишет таких статей, пока появится хоть один, нормальный советник.

 
Vladimir Perervenko:

Добрый день.

Давайте уточним. Набор данных Х состоит из 4 поднаборов preptrain = 4001, train = 1000, test = 500 и test1= 100 баров. Для претренинга используются обучающий набор - pretrain, валидационный - train. 

Для тонкой настройки в качестве обучающего используется набор train  , а валидационного - первые 250 баров набора test . 

Поэтому для определения окончательного качества в качестве тестового набора используем последние 250 баров набора test. code

Не вижу противоречий. Согласны?

Удачи

Технически все сделано хорошо, не об этом вопрос.
Мне кажется маловато 250 бар для оценки модели, потому и интересовался, почему только по этому участку отбор делаете.
Да, это работает в конкретном случае (у вас на всех участках получилась хорошие результаты), но мне кажется это не универсально.

Ведь могли попасться данные, которые не так хороши. И модель например могла обучаться до 40% ошибки на обучающем участке, и чисто случайно показать 30% на тестовом. А вторая модель допустим, обучилась до 35% на обоих участках. Вторая очевидно лучше. Но выбор только по тестовому участку выберет первую. Для сравнения есть такие варианты оценки модели:
оценка только на обучающем участке,
или на сумме  всех участков,
или как в Darch, (при поданных валидационных данных) на Err = (ErrLeran * 0.37 + ErrValid * 0.63) - эти коэффициенты по умолчанию, но их можно менять.

Последний вариант самый интересный, т.к. учитывает обе ошибки, но с большим весом валидационного участка.
В принципе можно формулу расширить, например до Err = (ErrLeran * 0.25 + ErrValid * 0.35 + ErrTest * 0.4).

Может даже по дельтам ошибок надо делать отбор, например если ErrLeran и ErrTest отличаются более чем на 5% - то отбраковать такую модель. А из оставшихся уже делать выбор.

Поставил эксперимент.

Вот некоторые результаты из 30 обучений: (модель не та, что изначально, на ней все отлично, поэтому убрал претренинг чтобы были и плохие результаты)

Расшифровка: V1 = 1-ErrLearn;    V2= 1-ErrOOC;      Value     = 1 - (ErrLeran * 0.37 + ErrOOC * 0.63);   в ООС cклеил данные из Valid и Test.

 Value     V1     V2

0.5712 0.4988 0.6138 - ООС хорош, но случаен, т.к. Learn = 50%

0.5002 0.5047 0.4975 - так чаще получалось

0.6719 0.6911 0.6606 - и вот так пару раз. Сортировка по Value     = 1 - (ErrLeran * 0.37 + ErrOOC * 0.63) вытягивает такие модели вверх

 
revers45:
Конечно, он запостил уже очень много R кода, но хотелось бы увидеть и адекватные результаты, а главное понять, сколько ещё он напишет таких статей, пока появится хоть один, нормальный советник.

В одной из статей был советник, я его за пару дней переписал под новую версию Darch - технически все прекрасно взаимодействует. Советник то простенький - считать OHLC и закинуть в R и запустить ф-ю расчетов в R. В конце получив команды от НС, послать торговые команды на сервер. Все. Остальное - трейлинги, стопы, ММ - на свой вкус.
Самое сложное как раз то, что описывается в статьях - найти хорошие данные,  и правильно обучить на них НС. Владимир показывает всевозможные варианты моделей, ансамблей, оптимизаций, отбора и обработки предикторов..., не успеваю за ним угнаться))

 

Как думаете,
может стоит из перебора гиперпараметров исключить варианты c числом нейронов в слоях, где n2 > n1 ?

Например сеть 10 - 20 - 100 - 2 или 10 - 8 - 100 - 2

Если n2 > n1, то получится сжатие до n1, потом декомпрессия до n2 и потом снова сжатие до 1 или 2 нейронов выходного слоя. Если в конце все-равно имеем 2 нейрона, то в середине декомпрессия не должна дать никаких перимуществ, после сжатия данных на n1 слое. Но это будет съедать кучу времени на просчет заведомо худших вариантов.
Думаю это можно сделать в фитнес функции таким образом: n1 перебирать, как число нейронов, а n2, как % от n1, потом округлить и *2 для maxout

Обновление:
себе сделал, надеюсь вычислительные мощности будут тратиться более эффективно.
 
elibrarius:

Как думаете,
может стоит из перебора гиперпараметров исключить варианты c числом нейронов в слоях, где n2 > n1 ?

Например сеть 10 - 20 - 100 - 2 или 10 - 8 - 100 - 2

Если n2 > n1, то получится сжатие до n1, потом декомпрессия до n2 и потом снова сжатие до 1 или 2 нейронов выходного слоя. Если в конце все-равно имеем 2 нейрона, то в середине декомпрессия не должна дать никаких перимуществ, после сжатия данных на n1 слое. Но это будет съедать кучу времени на просчет заведомо худших вариантов.
Думаю это можно сделать в фитнес функции таким образом: n1 перебирать, как число нейронов, а n2, как % от n1, потом округлить и *2 для maxout

Приветствую.

Из моих длительных экспериментов с параметрами только несколько особенностей заметил:

- часто лучшие результаты с fact = 2

- или когда оба скрытых слоя имеют одинаковую функцию активации

Я не ограничивал соотношение нейронов в скрытых слоях. Не оптимальные соотношения очень быстро выбывают из рассмотрения. Но Вы можете проверить эту идею. Я может найду время и проверю оптимизацию с помощью rgenoud.

Удачи

 
Vladimir Perervenko:

Я не ограничивал соотношение нейронов в скрытых слоях. Не оптимальные соотношения очень быстро выбывают из рассмотрения. Но Вы можете проверить эту идею. Я может найду время и проверю оптимизацию с помощью rgenoud.

Я сделал, чтобы следующий слой считался в % от предыдущего. Но сравнивать особо нет желания. Чисто теоретически надеюсь, что прав, что декомпрессия внутри сети новой информации ей не даст, после сжатия на предыдущих слоях.

Генетику на GA:ga попробовал. Он 200-300 раз запустил НС на расчеты. Многовато. И по результатам улучшений нет.

Хотя и для бейесовской оптимизации предполагаю, что надо больше проходов, не 20-30, а может и до 100. Т.к. часто бывает, что лучшим результатом остается один из 10 рандомных стартовых вариантов, и за следующие 10-20 проходов оптимизатором - ничего лучшего не находится. Может за 100 проходов будут улучшения...

Vladimir Perervenko:

- часто лучшие результаты с fact = 2

- или когда оба скрытых слоя имеют одинаковую функцию активации

Тут у меня все по разному. Relu часто хорош.

 
elibrarius:

Я сделал, чтобы следующий слой считался в % от предыдущего. Но сравнивать особо нет желания. Чисто теоретически надеюсь, что прав, что декомпрессия внутри сети новой информации ей не даст, после сжатия на предыдущих слоях.

Генетику на GA:ga попробовал. Он 200-300 раз запустил НС на расчеты. Многовато. И по результатам улучшений нет.

Хотя и для бейесовской оптимизации предполагаю, что надо больше проходов, не 20-30, а может и до 100. Т.к. часто бывает, что лучшим результатом остается один из 10 рандомных стартовых вариантов, и за следующие 10-20 проходов оптимизатором - ничего лучшего не находится. Может за 100 проходов будут улучшения...

Тут у меня все по разному. Relu часто хорош.

Генетика не нашла лучших вариантов и у меня. 

Для байесовской нужно поиграть не только с количеством проходов но и с количеством точек. Нужно искать более быстрый вариант. С этим очень утомительно.

Удачи

ПС. Вы что не переходите на TensorFlow? Это просто более высокий  уровень.