Продолжение №127.

So I came to idea that I need a more complex pipeline:

foveal point selector. This is a rough CNN (e.g. 4x4 grid) coupled with simple transformer. Goal: given observation produce number of foveal points (configurable parameter) in terms of x,y,std(x),std(y). I.e. produce parameters of Gaussian distribution from one could sample.

spatial feature extractor. Given sampled foveal points for each observation extract features with different resolution. I think I just need two resolutions: fine-grained (e.g. 5x5) and middle-grained (e.g. 4.4) with extended area. Observation space is not so large (it’s not a Starcraft observations) to use 3 or more resolution grades. so I end up with a bunch of feature tokens for each observation which I label with temporal label and spatial labels. The remaining part of model is unchanged for now.

Хотелось научиться работать многофокальными данными, когда есть несколько точек зрения на один кадр и потом через трансформер всё это изучается в целостности.

Провеёл несколько экспериментов для сетапа, когда есть 1 обзервейшн и нет pov_vision_head. Т.е. чисто за счёт ob_vision_head. Эксперименты:

эксперимент особенность ssim
18c_world_model_02/1 ‘ob_vision_head’: {‘grid’: (6, 6), ‘features_counts’: (2, 4, 8, 16)} 0.963
18c_world_model_02/2 ‘ob_vision_head’: {‘grid’: (7, 7), ‘features_counts’: (2, 4, 8, 16)} 0.9567
18c_world_model_02/3 ‘ob_vision_head’: {‘grid’: (9, 9), ‘features_counts’: (2, 4, 8, 16)} 0.9618
18c_world_model_02/4 ‘ob_vision_head’: {‘grid’: (6, 6), ‘features_counts’: (4, 8, 16, 32)} 0.9546
18c_world_model_02/5 ‘ob_vision_head’: {‘grid’: (7, 7), ‘features_counts’: (4, 8, 16, 32)} 0.9607
18c_world_model_02/6 ‘ob_vision_head’: {‘grid’: (9, 9), ‘features_counts’: (4, 8, 16, 32)} 0.9653
18c_world_model_02/7 ‘ob_vision_head’: {‘grid’: (6, 6), ‘features_counts’: (8, 16, 32, 64)} 0.9682
18c_world_model_02/8 ‘ob_vision_head’: {‘grid’: (7, 7), ‘features_counts’: (8, 16, 32, 64)} 0.969
18c_world_model_02/9 ‘ob_vision_head’: {‘grid’: (9, 9), ‘features_counts’: (8, 16, 32, 64)} 0.9608
18c_world_model_02/10 ‘ob_vision_head’: {‘grid’: (6, 6), ‘features_counts’: (16, 32, 64, 128)} 0.9723
18c_world_model_02/11 ‘ob_vision_head’: {‘grid’: (7, 7), ‘features_counts’: (16, 32, 64, 128)} 0.9693
18c_world_model_02/12 ‘ob_vision_head’: {‘grid’: (9, 9), ‘features_counts’: (16, 32, 64, 128)} 0.9711
18c_world_model_02/13 ‘ob_vision_head’: {‘grid’: (6, 6), ‘features_counts’: (16, 32, 64, 128)}, ‘batch_size’: 256 0.9613
18c_world_model_02/14 ‘ob_vision_head’: {‘grid’: (9, 9), ‘features_counts’: (16, 32, 64, 128)}, ‘batch_size’: 256 0.957

Я думал, что чем больше грид и чем больше фичей, тем лучше. Но нет - как ни сранно 6х6 делает и 7х7 и 9х9 по крайней мере на первых 100 эпохах.

Дальше 4 обзервейшна, 2 пова, ob_vision_head выключен. База - это 'pov_vision_head': {'grid': (5, 5), 'features_counts': (16, 32, 64)} Эксперименты: |эксперимент|особенность|ssim| |—|—|—| |18c_world_model_02/15|-|0.8936| |18c_world_model_02/16|’parent’: ‘18c_world_model_02:15’, ‘learn_rate’: ‘const(0.0001)’|0.9037| |18c_world_model_02/17|’parent’: ‘18c_world_model_02:15’, ‘learn_rate’: ‘const(0.00025)’|0.8989| |18c_world_model_02/18|’parent’: ‘18c_world_model_02:15’, ‘learn_rate’: ‘const(0.00005)’|0.8994| |18c_world_model_02/19|’pov_coords_encoding’: {‘frequencies_count’: 16, ‘inner_d_model’: 64}|0.8855| |18c_world_model_02/20|’pov_coords_encoding’: {‘frequencies_count’: 6, ‘inner_d_model’: 128}|0.8775| |18c_world_model_02/21|’pov_coord_lists’: ‘pov_coord_lists:1:cls=2,0_526,49753,0_2’}|0.9026| |18c_world_model_02/22|’pov_coord_lists’: ‘pov_coord_lists:1:cls=2,0_526,49753,0_2’}, ‘pov_coords_encoding’: {‘frequencies_count’: 6, ‘inner_d_model’: 64, ‘is_combined’: False}|0.9053| |18c_world_model_02/23|’pov_coord_lists’: ‘pov_coord_lists:1:cls=2,0_526,49742’}, ‘pov_coords_encoding’: {‘frequencies_count’: 6, ‘inner_d_model’: 64, ‘is_combined’: False}|0.8806| |18c_world_model_02/24|’pov_vision_head’: {‘grid’: (5, 5), ‘features_counts’: (32, 64, 128)}, ‘pov_coord_lists’: ‘pov_coord_lists:1:cls=2,0_526,49742’}, ‘pov_coords_encoding’: {‘frequencies_count’: 6, ‘inner_d_model’: 64, ‘is_combined’: True}|0.8711| |18c_world_model_02/25|’comment’: ‘removed BatchNorm2d in pov_vision_head’, ‘pov_vision_head’: {‘grid’: (5, 5), ‘features_counts’: (32, 64, 128)}, ‘pov_coord_lists’: ‘pov_coord_lists:1:cls=2,0_526,49742’}, ‘pov_coords_encoding’: {‘frequencies_count’: 6, ‘inner_d_model’: 64, ‘is_combined’: True}|0.8924|

Сначала меня смутил низкий ssim, особенно на фоне предыдущих экспериментов. Даже после дообучения лучший был 0.9037. Возникла мысля, что это из-за хитроумного PovCoordsEncoding, который сразу и X, и Y смешивает в один эмбеддинг. Попробовал несколько эксперментов, где использовались различные эмбеддинги для X и Y (is_combined=False), также пробовал с гранулярными pov_coords (гранулярность 0.2, гранулярность исключает непрерывность, что делает изучение X,Y проще). Стало чуть получше, но не убедительно. После визуального просмотра обратил внимание на то, что модель плодит сразу несколько врагов в ряду. Т.е. как будто для неё выгодно в случае отсутствия информации нарисовать хоть что-то, т.к. это видимо просто снижает ошибку. Поэтому возникла мысль, что видимо в таком сетапе (рандомные pov_coords, нет общего контектса) м.б. лучше и не получить.

Ок. А что если совместить ob_vision_head и pov_vision_head, как собственно и задумывалось изначально? Это был эксп 18c_world_model_02/26, ssim=0.979.

Не сказать, чтобы был какой-то прорыв. Конечно, за счёт грамотной раскладки POV должно быть возможным вырасти ssim. Но это надо девелопировать foveal point selector либо хардкодтить. Стоит ли оно того?

Потом возникла мысль, а может быть и не нужны отдельные pov? Может просто хватит ob_vision_head на каждый из элементов сиквенса. Это, конечно, в каком-то роде декаденс, т.к. возвращает к тому сетапу, который был в №127. Правда там было 16х16х4=1024 токена, а здесь будет меньше. |эксперимент|сетка|токенов|ssim| |—|—|—|—| |18c_world_model_02/27|6x6|144|0.9757| |18c_world_model_02/29|7x7|196|0.9746| |18c_world_model_02/30|9x9|324|0.9814|

Потом следующая мысль! А может стерео зрение попробовать? Это когда один обзервейшн исследуется двумя CNN (2x178х178->6x6, 72 токена), но с разными смещениями по оси Х. Так же смотрим что лучше работает: когда одна CNN для лева и права (сильная регуляризация), или когда разные (выше гибкость). Был выточен 18c_study_01. Результаты: |эксперимент|offset|is_shared|ssim| |—|—|—|—| |18c_world_model_02/opt_01/60|1|F|0.9777| |18c_world_model_02/opt_01/56|2|F|0.9741| |18c_world_model_02/opt_01/57|3|F|0.9799| |18c_world_model_02/opt_01/52|4|F|0.9744| |18c_world_model_02/opt_01/54|5|F|0.9751| |18c_world_model_02/opt_01/59|1|T|0.9751| |18c_world_model_02/opt_01/55|2|T|0.9785| |18c_world_model_02/opt_01/51|3|T|0.9778| |18c_world_model_02/opt_01/58|4|T|0.9818| |18c_world_model_02/opt_01/62|5|T|0.9775|

Не, ну какое-то улучшение есть, по сравнению с тем, когда на один кадр одна CNN (один ob_vision_head). Вопрос только в цене: 32 токена против 72 (для 6х6).

Вообще упражняться тут долго можно:

  1. ob_vision_head на последний кадр. На предыдущие кадры горизонтальные band-like CNN (9x1), чтобы точнее фиксировать горизонтальное движения
  2. харкодное расположение pov_vision_head в заранее определённых местах
  3. foveal point selector, как и задумывалось
  4. и т.д.

Но, кажется, это немного отвлекает от главной задачи. А именно №126. Всё таки хочется научить агента проходить игру. Пока стало понятно, что надо заменять в агенте CNN, например, на 6х6. Короче, с новым опытом и наработками возвращаемся к агенту. Переделываем ему зрение, экспериментируем. Если будет не хватать, то можно вернуться к экспериментам world_model и найти ещё более оптимальную CNN. А если хватит и простой 6x6, то зачем усложнять?