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

 
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? Это просто более высокий  уровень. 

 
Vladimir Perervenko:

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

Для ускорения добавьте в параметры при вызове BayesianOptimization

    maxit = 1    #1 вместо 100 - число повторов для GP_fit для предсказания гиперплоскости
Не заметил улучшений при 100 повторах в сравнении с 1, поэтому теперь использую 1.
Т.е.

BayesianOptimization(все как у вас , maxit = 1)

maxit=1 через ... пердастся в GPfit::GP_fit и оптимизация будет 1 раз запускаться вместо 100.
Еще можно передать:
control = c(20*d, 10*d, 2*d);#по умолчанию  - control = c(200*d, 80*d, 2*d) - из 200*d выбрать 80*d лучших и построить 2*d кластеров - где d - число оптимизируемых параметров

Описание этих параметров тут https://github.com/cran/GPfit/blob/master/R/GP_fit.R

Vladimir Perervenko:

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

Да вроде и с Darch 30% при обучении и 36% на тесте получается. Доделаю советник, запущу в работу, а потом  может займусь.
Хотя Darch плохо поддерживается, кое что они поправили и доработали, но в январе его из CRAN в архив отправили за неисправление ошибок (там была одна с оценкой ошибки в режиме обучения с валидацией). В мае выпустили 13 версию, но потом откатили к 12-й. Сейчас вот опять 13-я появилась - видимо доделали.
 
elibrarius:

Для ускорения добавьте в параметры при вызове BayesianOptimization

    maxit = 1    #1 вместо 100 - число повторов для GP_fit для предсказания гиперплоскости
Не заметил улучшений при 100 повторах в сравнении с 1, поэтому использую 1.
Т.е.

maxit=1 через ... пердастся в GPfit::GP_fit и оптимизация будет 1 раз запускаться вместо 100.
Еще можно передать:
control = c(20*d, 10*d, 2*d);#по умолчанию  - control = c(200*d, 80*d, 2*d) - из 200*d выбрать 80*d лучших и построить 2*d кластеров - где d - число оптимизируемых параметров

Да вроде и с Darch 30% при обучении и 36% на тесте получается. Доделаю советник, запущу в работу, а потом  может займусь.
Хотя Darch плохо поддерживается, кое что они поправили и доработали, но в январе его из CRAN в архив отправили за неисправление ошибок (там была одна с оценкой ошибки в режиме обучения с валидацией). В мае выпустили 13 версию, но потом откатили к 12-й. Сейчас вот опять 13-я появилась - видимо доделали.

Спасибо за информацию. Попробую с Вашими параметрами. 

Я давно к ним не заходил на Github. Нужно будет предложение написать. В пакете darch предусмотрено использование GPU но пакет который они используют для этого из CRAN удалили (для 3.4.4). А было бы интересно как повлияет GPU на  скорость и качество. 

Удачи

 

Еще один тормоз тут

https://github.com/yanyachen/rBayesianOptimization/blob/master/R/Utility_Max.R

Тоже ставлю maxit = 1 вместо 100.

Через ... передать нельзя, можно просто свою Utility_Max функцию в R загрузить и пользоваться исправленной версией.

 
elibrarius:

Еще один тормоз тут

https://github.com/yanyachen/rBayesianOptimization/blob/master/R/Utility_Max.R

Тоже ставлю maxit = 1 вместо 100.

Через ... передать нельзя, можно просто свою Utility_Max функцию в R загрузить и пользоваться исправленной версией.

Проверил на оптимизации ансамбля нейросетей из статьи PartVI. Ни maxit, ни  control не оказывают видимого влияния на время вычисления. Наибольшее влияние оказывает количество нейронов в скрытом слое. Оставил так

 OPT_Res <- BayesianOptimization(fitnes, bounds = bonds,
                                  init_grid_dt = NULL, init_points = 20, 
                                  n_iter = 20, acq = "ucb", kappa = 2.576, 
                                  eps = 0.0, verbose = TRUE,
                                  maxit = 100, control = c(100, 50, 8))
elapsed = 14.42 Round = 1       numFeature = 9.0000     r = 7.0000      nh = 36.0000    fact = 9.0000   Value = 0.7530 
elapsed = 42.94 Round = 2       numFeature = 4.0000     r = 8.0000      nh = 46.0000    fact = 6.0000   Value = 0.7450 
elapsed = 9.50  Round = 3       numFeature = 11.0000    r = 5.0000      nh = 19.0000    fact = 5.0000   Value = 0.7580 
elapsed = 14.17 Round = 4       numFeature = 10.0000    r = 4.0000      nh = 35.0000    fact = 4.0000   Value = 0.7480 
elapsed = 12.36 Round = 5       numFeature = 8.0000     r = 4.0000      nh = 23.0000    fact = 6.0000   Value = 0.7450 
elapsed = 25.61 Round = 6       numFeature = 12.0000    r = 8.0000      nh = 44.0000    fact = 7.0000   Value = 0.7490 
elapsed = 8.03  Round = 7       numFeature = 12.0000    r = 9.0000      nh = 9.0000     fact = 2.0000   Value = 0.7470 
elapsed = 14.24 Round = 8       numFeature = 8.0000     r = 4.0000      nh = 45.0000    fact = 2.0000   Value = 0.7620 
elapsed = 9.05  Round = 9       numFeature = 7.0000     r = 8.0000      nh = 20.0000    fact = 10.0000  Value = 0.7390 
elapsed = 17.53 Round = 10      numFeature = 12.0000    r = 9.0000      nh = 20.0000    fact = 6.0000   Value = 0.7410 
elapsed = 4.77  Round = 11      numFeature = 9.0000     r = 2.0000      nh = 7.0000     fact = 2.0000   Value = 0.7570 
elapsed = 8.87  Round = 12      numFeature = 6.0000     r = 1.0000      nh = 40.0000    fact = 8.0000   Value = 0.7730 
elapsed = 14.16 Round = 13      numFeature = 8.0000     r = 6.0000      nh = 41.0000    fact = 10.0000  Value = 0.7390 
elapsed = 21.61 Round = 14      numFeature = 9.0000     r = 6.0000      nh = 47.0000    fact = 7.0000   Value = 0.7620 
elapsed = 5.14  Round = 15      numFeature = 13.0000    r = 3.0000      nh = 3.0000     fact = 5.0000   Value = 0.7260 
elapsed = 5.66  Round = 16      numFeature = 6.0000     r = 9.0000      nh = 1.0000     fact = 9.0000   Value = 0.7090 
elapsed = 7.26  Round = 17      numFeature = 9.0000     r = 2.0000      nh = 25.0000    fact = 1.0000   Value = 0.7550 
elapsed = 32.09 Round = 18      numFeature = 11.0000    r = 7.0000      nh = 38.0000    fact = 6.0000   Value = 0.7600 
elapsed = 17.18 Round = 19      numFeature = 5.0000     r = 3.0000      nh = 46.0000    fact = 6.0000   Value = 0.7500 
elapsed = 11.08 Round = 20      numFeature = 6.0000     r = 4.0000      nh = 20.0000    fact = 6.0000   Value = 0.7590 
elapsed = 4.47  Round = 21      numFeature = 6.0000     r = 2.0000      nh = 4.0000     fact = 2.0000   Value = 0.7390 
elapsed = 5.27  Round = 22      numFeature = 6.0000     r = 2.0000      nh = 21.0000    fact = 10.0000  Value = 0.7520 
elapsed = 7.96  Round = 23      numFeature = 7.0000     r = 1.0000      nh = 41.0000    fact = 7.0000   Value = 0.7730 
elapsed = 12.31 Round = 24      numFeature = 7.0000     r = 3.0000      nh = 41.0000    fact = 3.0000   Value = 0.7730 
elapsed = 7.64  Round = 25      numFeature = 8.0000     r = 4.0000      nh = 16.0000    fact = 7.0000   Value = 0.7420 
elapsed = 6.24  Round = 26      numFeature = 13.0000    r = 5.0000      nh = 6.0000     fact = 1.0000   Value = 0.7600 
elapsed = 8.41  Round = 27      numFeature = 11.0000    r = 8.0000      nh = 8.0000     fact = 7.0000   Value = 0.7420 
elapsed = 8.48  Round = 28      numFeature = 6.0000     r = 7.0000      nh = 15.0000    fact = 2.0000   Value = 0.7580 
elapsed = 10.11 Round = 29      numFeature = 12.0000    r = 6.0000      nh = 17.0000    fact = 4.0000   Value = 0.7310 
elapsed = 6.03  Round = 30      numFeature = 8.0000     r = 3.0000      nh = 12.0000    fact = 1.0000   Value = 0.7540 
elapsed = 8.58  Round = 31      numFeature = 13.0000    r = 5.0000      nh = 18.0000    fact = 2.0000   Value = 0.7300 
elapsed = 6.78  Round = 32      numFeature = 13.0000    r = 2.0000      nh = 15.0000    fact = 8.0000   Value = 0.7320 
elapsed = 9.54  Round = 33      numFeature = 10.0000    r = 3.0000      nh = 37.0000    fact = 9.0000   Value = 0.7420 
elapsed = 8.19  Round = 34      numFeature = 6.0000     r = 1.0000      nh = 42.0000    fact = 3.0000   Value = 0.7630 
elapsed = 12.34 Round = 35      numFeature = 7.0000     r = 2.0000      nh = 43.0000    fact = 8.0000   Value = 0.7570 
elapsed = 20.47 Round = 36      numFeature = 7.0000     r = 8.0000      nh = 39.0000    fact = 2.0000   Value = 0.7670 
elapsed = 11.51 Round = 37      numFeature = 5.0000     r = 9.0000      nh = 18.0000    fact = 3.0000   Value = 0.7540 
elapsed = 32.71 Round = 38      numFeature = 7.0000     r = 7.0000      nh = 40.0000    fact = 6.0000   Value = 0.7540 
elapsed = 28.33 Round = 39      numFeature = 7.0000     r = 9.0000      nh = 38.0000    fact = 5.0000   Value = 0.7550 
elapsed = 22.87 Round = 40      numFeature = 12.0000    r = 6.0000      nh = 48.0000    fact = 3.0000   Value = 0.7580 

 Best Parameters Found: 
Round = 12      numFeature = 6.0000     r = 1.0000      nh = 40.0000    fact = 8.0000   Value = 0.7730                                  maxit = 100, control = c(100, 50, 8))

Лучших 10 

OPT_Res %$% History %>% dp$arrange(desc(Value)) %>% head(10) %>%
    dp$select(-Round) -> best.init
  best.init
   numFeature r nh fact Value
1           6 1 40    8 0.773
2           7 1 41    7 0.773
3           7 3 41    3 0.773
4           7 8 39    2 0.767
5           6 1 42    3 0.763
6           8 4 45    2 0.762
7           9 6 47    7 0.762
8          11 7 38    6 0.760
9          13 5  6    1 0.760
10          6 4 20    6 0.759

Value - средний F1. Неплохие показатели. 

Для ускорения вычислений нужно переписать некоторые функции пакета. Самое первое - заменить все ncol(), nrow() которых там море на dim()[1], dim()[2]. Они исполняются в десятки раз быстрее. Ну и наверное, поскольку там только матричные операции, использовать GPU (пакет gpuR ). Сам я это сделать не смогу, может предложить разработчику?

Удачи