DQN Model ValueError: установка элемента массива с последовательностью - PullRequest
0 голосов
/ 29 марта 2020

(Все ссылки на код можно найти на https://github.com/EXJUSTICE/Doom_DQN_GC/blob/master/TF2_Doom_GC_CNN.ipynb)

Фон

Я прошу прощения за длину этого поста, Я хотел, чтобы это было как можно более ясным.

Я адаптировал некоторый мой код для спортзала Atari OpenAI для работы над пакетом VizDoom для построения модели DQN в Doom с использованием изображений входных кадров 480 x640. Запустив несколько начальных демонстраций (ячейка с отметкой 8) с совершенно случайной политикой, я заметил, что модель всегда пропускает первый эпизод. Если это произойдет, вызов состояния вернет объект None. В результате я адаптировал свой исходный код, чтобы проверить, был ли выполнен эпизод, прежде чем выполнять какое-либо обучение (ячейка, помеченная как 24)

Укладка

Один из общих подходов В построении агентов для обучения подкреплению есть использование сложенных кадров. Идея здесь состоит в том, чтобы отслеживать движение, суммируя поэлементные максимумы нескольких последовательных кадров. Это показано ниже для справки:

stacked_frames  =  deque([np.zeros((84,84), dtype=np.int) for i in range(stack_size)], maxlen=4)

def stack_frames(stacked_frames, state, is_new_episode):
    # Preprocess frame
    frame = preprocess_observation(state)

    if is_new_episode:
        # Clear our stacked_frames
        stacked_frames = deque([np.zeros((84,84), dtype=np.int) for i in range(stack_size)], maxlen=4)

        # Because we're in a new episode, copy the same frame 4x, apply elementwise maxima

        stacked_frames.append(frame)
        stacked_frames.append(frame)
        stacked_frames.append(frame)
        stacked_frames.append(frame)



        # Stack the frames
        stacked_state = np.stack(stacked_frames, axis=2)

    else:
        #Since deque append adds t right, we can fetch rightmost element
        #maxframe=np.maximum(stacked_frames[-1],frame)
        # Append frame to deque, automatically removes the oldest frame
        stacked_frames.append(frame)

        # Build the stacked state (first dimension specifies different frames)
        stacked_state = np.stack(stacked_frames, axis=2) 

    return stacked_state, stacked_frames

Проблема

Все мои попытки запустить мой агент привели к следующей ошибке:

/usr/local/lib/python3.6/dist-packages/skimage/transform/_warps.py in warp(image, inverse_map, map_args, output_shape, order, mode, cval, clip, preserve_range)
    805 
    806     if image.size == 0:
--> 807         raise ValueError("Cannot warp empty image with dimensions", image.shape)
    808 
    809     image = convert_to_float(image, preserve_range)

ValueError: ('Cannot warp empty image with dimensions', (0, 24))

При тщательном осмотре эта ошибка возникает из-за функции изменения формы предварительной обработки, которая вызывает преобразование scikit-image для преобразования обрезанного кадра в градациях серого во входную форму (84,84). В моем исходном коде OpenAI я вызвал функцию .reshape () вместо .transform, но я это дал мне ошибки с кадрами Vizdoom, поэтому я застрял с преобразованием.

def preprocess_observation(frame):

    # Crop and resize the image into a square, as we don't need the excess information
    cropped = frame[60:-60,30:-30]

    normalized = cropped/255.0

    img_gray = rgb2gray(normalized)

    preprocessed_frame = transform.resize(img_gray, [84,84])

    return preprocessed_frame

Поскольку мне показалось, что метод пытался изменить пустое изображение (я полагаю), я, естественно, проверил раздел агента done .

          next_obs=np.zeros((84,84), dtype=np.int)
          next_obs,stacked_frames= stack_frames(stacked_frames,next_obs,False)

          exp_buffer.append([obs, action, next_obs, reward, done])

          step = max_steps
          history.append(episodic_reward)
          print('Episode: {}'.format(len(history)),
                          'Total reward: {}'.format(episodic_reward))

          game.new_episode()

Я полагаю, что это была проблема с укладкой, которая дала мне проблему. Поэтому я провел некоторые эксперименты, чтобы подтвердить это.

Решения предприняты

  1. Смещение функции суммирования и попытка вызвать наблюдение из самой среды приводит к Ошибка, не относящаяся к типу, которая понятна, если учесть, что среда мертва.

  2. Увеличение длины буфера буферной памяти позволяет увеличить время обучения (от 5 до 10 эпизодов)

3.Если удаляются все стеки из раздела done , происходит определенное обучение.

      step = max_steps
      history.append(episodic_reward)
      print('Episode: {}'.format(len(history)),
                      'Total reward: {}'.format(episodic_reward))

      game.new_episode()

В результате получается около 10 эпизодов обучения. до того, как мы наблюдаем серию ошибок в ячейке 24 (сокращено ниже).

ValueError                                Traceback (most recent call last)
ValueError: setting an array element with a sequence.

The above exception was the direct cause of the following exception:

ValueError                                Traceback (most recent call last)
<ipython-input-24-fa4adb5665e3> in <module>()
    158 
    159                 # merge all summaries and write to the file
--> 160                 mrg_summary = merge_summary.eval(feed_dict={X:o_obs, y:np.expand_dims(y_batch, axis=-1), X_action:o_act, in_training_mode:False})
    161                 file_writer.add_summary(mrg_summary, global_step)
    162 

4 frames
/usr/local/lib/python3.6/dist-packages/numpy/core/_asarray.py in asarray(a, dtype, order)
     83 
     84     """
---> 85     return array(a, dtype, copy=False, order=order)
     86 
     87 

ValueError: setting an array element with a sequence.

Выполнение некоторого поиска в StackOverflow приводит меня к мысли, что входной массив наблюдений, подаваемый в модель, каким-то образом не в форме процесс отбора проб. Это заставляет меня поверить, что проблема заключается в отсутствии стекирования.

Любой совет может помочь решить эту головную боль. Спасибо за ваше время!

1 Ответ

0 голосов
/ 30 марта 2020

это из-за длины списков и не может иметь форму, например:

np.array( [ [1,2,3],[1,2,3,4],[1,2,3],[1,2] ] ) #this just returns an np array object without shape and this may be your problem. if you print the shape you'll get (4,)
np.array( [ [1,2,3],[1,2,3,4],[1,2,3],[1,2] ], dtype='float32') #if you run this you'll get "setting an array element with a sequence" error
np.array( [ [1,2,3],[1,2,3],[1,2,3],[1,2,3] ], dtype='float32') #this will work correctly and if your print it's shape it'll be (4,3)
...