시리즈
- 1주차: 대회 이해하기
- 2주차: Action Space 이해하기
- 3-4주차: Observation Space 이해하기
- 5주차: Reward 이해하기
- 6-8주차: 강화학습 실전 기술
Observation
Note: 현재, 기본 observation 형태는 project=True
으로, list를 반환한다. 그러나, osim-rl
의 다음 릴리스에서는 observation 이 project=False
로 바뀌어서 dictionary를 반환할 것이다. 만약 project
가 무엇인지 모른다면, 1주차 포스트를 확인해 보자!
Observation 은 크게 신체 부위, 관절, 근육, 힘, 무게중심 이렇게 5가지로 나눌 수 있다. 각 신체 부위마다 위치, 속도, 가속도, 각도, 각속도, 각가속도를 관측할 수 있고, 유사하게 각 관절마다 위치, 속도, 가속도를 관측할 수 있다. 또, 각 근육마다 activation, fiber force, fiber length, fiber velocity를 관측할 수 있고, 힘들은 신체 부위에 작용하는 힘들을 관측한 것을 나타낸다. 마지막으로, 무게중심 역시 위치, 속도, 그리고 가속도를 관측할 수 있다.
{
'body_acc': {
'calcn_l': [1253.688828798722, 453.4117256205009, -462.8844724817433],
'femur_l': [3552.7596723666466, 102.32773696018921, -24.14590774460615],
'femur_r': [3577.2392919297267, 97.2556003736695, -24.14590774460615],
'head': [-2151.6179549639746, 247.21132544086612, -5.651007630868147],
'pelvis': [3021.7003234669214, 680.8998459553628, -32.50184112628757],
'pros_foot_r': [2097.069790884677, 407.6437699668757, 985.199411865104],
'pros_tibia_r': [-7206.973998543474, 407.6437699668757, 459.98267021582114],
'talus_l': [1326.619748123917, 365.89822770528855, -448.4463030305569],
'tibia_l': [-5893.369348915658, 365.89822770528855, -227.17211746475732],
'toes_l': [1250.10882643996, 148.06830447245676, -490.1229719729977],
'torso': [2351.823145970354, -146.7888874667765, -15.265452971775463]
},
'body_acc_rot': {
'calcn_l': [514.5911292227897, 146.58454828192848, -1710.8455233087516],
'femur_l': [514.5911292227897, 146.58454828192848, -23292.824849203236],
'femur_r': [-1221.434282905309, 146.5845482819343, -26557.63606714429],
'head': [30.372075368382077, 146.58454828191628, 8219.35187112352],
'pelvis': [30.372075368382077, 146.58454828191628, 8219.351871123528],
'pros_foot_r': [-1221.434282905309, 146.5845482819343, 2218.8731787441284],
'pros_tibia_r': [-1221.434282905309, 146.5845482819343, 21637.311138205005],
'talus_l': [514.5911292227897, 146.58454828192848, -1710.8455233087516],
'tibia_l': [514.5911292227897, 146.58454828192848, 16790.672318696685],
'toes_l': [514.5911292227897, 146.58454828192848, -1710.8455233087516],
'torso': [30.372075368382077, 146.58454828191628, 8219.35187112352]
},
'body_pos': {
'calcn_l': [-0.123969856517536, 0.006129303551649576, -0.09142],
'femur_l': [-0.0707, 0.8738999999999999, -0.0835],
'femur_r': [-0.0707, 0.8738999999999999, 0.0835],
'head': [-0.052764320996907754, 1.5694070821576522, 0.0],
'pelvis': [0.0, 0.94, 0.0],
'pros_foot_r': [-0.07519985651753601, 0.04807930355164958, 0.0835],
'pros_tibia_r': [-0.07519985651753601, 0.47807930355164957, 0.0835],
'talus_l': [-0.07519985651753601, 0.04807930355164958, -0.0835],
'tibia_l': [-0.07519985651753601, 0.47807930355164957, -0.0835],
'toes_l': [0.05483014348246398, 0.004129303551649576, -0.0925],
'torso': [-0.1007, 1.0214999999999999, 0.0]
},
'body_pos_rot': {
'calcn_l': [-0.0, 0.0, -0.0],
'femur_l': [-0.0, 0.0, -0.0],
'femur_r':[-0.0, 0.0, -0.0],
'head': [-0.0, 0.0, -0.0872665],
'pelvis': [-0.0, 0.0, -0.0],
'pros_foot_r': [-0.0, 0.0, -0.0],
'pros_tibia_r': [-0.0, 0.0, -0.0],
'talus_l': [-0.0, 0.0, -0.0],
'tibia_l': [-0.0, 0.0, -0.0],
'toes_l': [-0.0, 0.0, -0.0],
'torso': [-0.0, 0.0, -0.0872665]
},
'body_vel': {
'calcn_l': [0.0, 0.0, 0.0],
'femur_l': [0.0, 0.0, 0.0],
'femur_r': [0.0, 0.0, 0.0],
'head': [0.0, 0.0, 0.0],
'pelvis': [0.0, 0.0, 0.0],
'pros_foot_r': [0.0, 0.0, 0.0],
'pros_tibia_r': [0.0, 0.0, 0.0],
'talus_l': [0.0, 0.0, 0.0],
'tibia_l': [0.0, 0.0, 0.0],
'toes_l': [0.0, 0.0, 0.0],
'torso': [0.0, 0.0, 0.0]
},
'body_vel_rot': {
'calcn_l': [0.0, 0.0, 0.0],
'femur_l': [0.0, 0.0, 0.0],
'femur_r': [0.0, 0.0, 0.0],
'head': [0.0, 0.0, 0.0],
'pelvis': [0.0, 0.0, 0.0],
'pros_foot_r': [0.0, 0.0, 0.0],
'pros_tibia_r': [0.0, 0.0, 0.0],
'talus_l': [0.0, 0.0, 0.0],
'tibia_l': [0.0, 0.0, 0.0],
'toes_l': [0.0, 0.0, 0.0],
'torso': [0.0, 0.0, 0.0]
},
'forces': {
'AnkleLimit_l': [0.0, 0.0],
'AnkleLimit_r': [0.0, 0.0],
'HipAddLimit_l': [0.0, 0.0],
'HipAddLimit_r': [0.0, 0.0],
'HipLimit_l': [0.0, 0.0],
'HipLimit_r': [0.0, 0.0],
'KneeLimit_l': [-0.0, 0.0],
'KneeLimit_r': [-0.0, 0.0],
'abd_l': [0.0],
'abd_r': [0.0],
'add_l': [0.0],
'add_r': [0.0],
'ankleSpring': [-0.0],
'bifemsh_l': [6084.326590359711],
'bifemsh_r': [6084.326590359711],
'foot_l': [-1.7615592933859115e-12, -504.53063397142085, 0.0, -46.45915575255036, 1.622112753284362e-13, -4.943148065393853, 6.786660275561278e-13, 194.37767574636297, 0.0, 0.0, 0.0, 5.831330272390875, 1.0828932658297836e-12, 310.1529582250579, 0.0, 0.0, 0.0, 6.203059164501164, 1.0828932658297836e-12, 310.1529582250579, 0.0, 0.0, 0.0, 6.203059164501164],
'gastroc_l': [0.0],
'glut_max_l': [147037.7044007947],
'glut_max_r': [147037.7044007947],
'hamstrings_l': [0.0],
'hamstrings_r': [0.0],
'iliopsoas_l': [21479.14279626967],
'iliopsoas_r': [21479.14279626967],
'pros_foot_r_0': [-1.3573320551122304e-12, -388.7553514927188, 0.0, 32.46107184964201, -1.1333722660187127e-13, 3.726164264482634, 1.3573320551122304e-12, 388.7553514927188, 0.0, 0.0, 0.0, 25.50818238819416, 1.3573320551122304e-12, 388.7553514927188, 0.0, 0.0, 0.0, 25.50818238819416],
'rect_fem_l': [0.0],
'rect_fem_r': [0.0],
'soleus_l': [0.0],
'tib_ant_l': [0.0],
'vasti_l': [0.0],
'vasti_r': [0.0]
},
'joint_acc': {
'ankle_l': [-18501.517842005436],
'ankle_r': [-19418.437959460876],
'back': [-1.000444171950221e-11],
'back_0': [],
'ground_pelvis': [8219.351871123528, 30.372075368382077, 146.58454828191628, 3021.7003234669214, 680.8998459553628, -32.50184112628757],
'hip_l': [-31512.176720326766, -484.21905385440766, -1.2192913345643319e-11],
'hip_r': [-34776.98793826782, -1251.806358273691, 1.801936377887614e-11],
'knee_l': [40083.49716789992],
'knee_r': [48194.947205349294],
'mtp_l': [],
'subtalar_l': []
},
'joint_pos': {
'ankle_l': [0.0],
'ankle_r': [0.0],
'back': [-0.0872665],
'back_0': [],
'ground_pelvis': [0.0, 0.0, 0.0, 0.0, 0.94, 0.0],
'hip_l': [0.0, 0.0, 0.0],
'hip_r': [0.0, 0.0, 0.0],
'knee_l': [0.0],
'knee_r': [0.0],
'mtp_l': [],
'subtalar_l': []
},
'joint_vel': {
'ankle_l': [0.0],
'ankle_r': [0.0],
'back': [0.0],
'back_0': [],
'ground_pelvis': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
'hip_l': [0.0, 0.0, 0.0],
'hip_r': [0.0, 0.0, 0.0],
'knee_l': [0.0],
'knee_r': [0.0],
'mtp_l': [],
'subtalar_l': []
},
'markers': {},
'misc': {
'mass_center_acc': [-4.001157926055469e-13, 2.5708322099694465],
'mass_center_pos': [-0.08466565561225976, 0.9952730567231536],
'mass_center_vel': [0.0, 0.0]
},
'muscles': {
'abd_l': { 'activation': 0.05, 'fiber_force': 1.547474121413317e-14, 'fiber_length': 0.1, 'fiber_velocity': -1.326540950462705 },
'abd_r': { 'activation': 0.05, 'fiber_force': 1.547474121413317e-14, 'fiber_length': 0.1, 'fiber_velocity': -1.326540950462705 },
'add_l': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -1.0367973163843414 },
'add_r': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -1.0367973163843414 },
'bifemsh_l': { 'activation': 0.05, 'fiber_force': 6738.484542501806, 'fiber_length': 0.1, 'fiber_velocity': 379.68284762694003 },
'bifemsh_r': { 'activation': 0.05, 'fiber_force': 6738.484542501806, 'fiber_length': 0.1, 'fiber_velocity': 379.68284762694003 },
'gastroc_l': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -3481.201038861244 },
'glut_max_l': { 'activation': 0.05, 'fiber_force': 147037.7044007947, 'fiber_length': 0.1, 'fiber_velocity': 2608.0828361198787 },
'glut_max_r': { 'activation': 0.05, 'fiber_force': 147037.7044007947, 'fiber_length': 0.1, 'fiber_velocity': 2608.0828361198787 },
'hamstrings_l': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -5.221454250202676 },
'hamstrings_r': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -5.221454250202676 },
'iliopsoas_l': { 'activation': 0.05, 'fiber_force': 21769.687084250327, 'fiber_length': 0.1, 'fiber_velocity': 276.6184843761971 },
'iliopsoas_r': { 'activation': 0.05, 'fiber_force': 21769.687084250327, 'fiber_length': 0.1, 'fiber_velocity': 276.6184843761971 },
'rect_fem_l': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -0.4092974568990915 },
'rect_fem_r': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -0.4092974568990915 },
'soleus_l': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -190146.97438065815 },
'tib_ant_l': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -16.394217173963888 },
'vasti_l': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -0.427439106952905 },
'vasti_r': { 'activation': 0.05, 'fiber_force': 0.0, 'fiber_length': 0.1, 'fiber_velocity': -0.427439106952905 }
}
}
위의 dictionary는 첫 state (상태)의 observation dictionary인데, 숫자들의 크기가 무척 차이가 난다는 것을 알 수 있다. 신체 부위의 y축 포지션은 대부분 0과 1 사이인 것에 반해, 신체부위의 가속도는 몇만의 큰 숫자를 가지고 있다. 이렇게 큰 숫자가 나타나는 이유는 근육들이 제대로 초기화되지 않아서일 수도 있지만 (Issue #133), 그렇다고 하더라도 observation을 normalize (표준화)하는 것도 충분히 에이전트의 학습속도에 유의미한 영향이 있을 수 있다.
또, observation에서 위치를 나타내는 모든 숫자는 절대적인 값인데, 에이전트는 이러한 절대적인 값보다 pelvis의 x, z축에 대한 상대적인 값이 더 유용할 것이라 추측된다. 예를 들어, 만약 머리가 허리 뒤에 있다면, 에이전트는 뒤로 넘어질 확률이 높고, 머리가 허리 앞에 있다면, 에이전트는 앞으로 넘어지거나 뛸 확률이 높다.
참고로, 현재 무게중심은 2개의 숫자밖에 없는데, 이것은 곧 수정될 버그이다 (Issue #129).
만약 observation 에 대해 더 세부적으로 알고 싶다면, 공식 문서를 확인하는 것을 추천한다.
osim-rl-helper
DictToList
기존의 DictToList
wrapper 는 osim-rl
패키지의 ProstheticsEnv.get_observation()
를 이용해서 dict
형태의 observation을 list
형태로 바꾸었다. 그러나, 이 함수는 $z$축의 정보를 전혀 쓰지 않는 버그가 있다. 그러므로, 기존의 DictToList
wrapper는 DictToListLegacy
라는 이름으로 바뀌었다. 그 대신, 전처리 없이 단순히 형태만 list
로 바꾸는 DictToListFull
wrapper를 추가하였다.
def _dict_to_list(self, state_desc):
res = []
# Body Observations
for info_type in ['body_pos', 'body_pos_rot',
'body_vel', 'body_vel_rot',
'body_acc', 'body_acc_rot']:
for body_part in ['calcn_l', 'talus_l', 'tibia_l', 'toes_l',
'femur_l', 'femur_r', 'head', 'pelvis',
'torso', 'pros_foot_r', 'pros_tibia_r']:
res += state_desc[info_type][body_part]
# Joint Observations
# Neglecting `back_0`, `mtp_l`, `subtalar_l` since they do not move
for info_type in ['joint_pos', 'joint_vel', 'joint_acc']:
for joint in ['ankle_l', 'ankle_r', 'back', 'ground_pelvis',
'hip_l', 'hip_r', 'knee_l', 'knee_r']:
res += state_desc[info_type][joint]
# Muscle Observations
for muscle in ['abd_l', 'abd_r', 'add_l', 'add_r',
'bifemsh_l', 'bifemsh_r', 'gastroc_l',
'glut_max_l', 'glut_max_r',
'hamstrings_l', 'hamstrings_r',
'iliopsoas_l', 'iliopsoas_r', 'rect_fem_l', 'rect_fem_r',
'soleus_l', 'tib_ant_l', 'vasti_l', 'vasti_r']:
res.append(state_desc['muscles'][muscle]['activation'])
res.append(state_desc['muscles'][muscle]['fiber_force'])
res.append(state_desc['muscles'][muscle]['fiber_length'])
res.append(state_desc['muscles'][muscle]['fiber_velocity'])
# Force Observations
# Neglecting forces corresponding to muscles as they are redundant with
# `fiber_forces` in muscles dictionaries
for force in ['AnkleLimit_l', 'AnkleLimit_r',
'HipAddLimit_l', 'HipAddLimit_r',
'HipLimit_l', 'HipLimit_r', 'KneeLimit_l', 'KneeLimit_r']:
res += state_desc['forces'][force]
# Center of Mass Observations
res += state_desc['misc']['mass_center_pos']
res += state_desc['misc']['mass_center_vel']
res += state_desc['misc']['mass_center_acc']
return res
상호작용 모니터
에이전트와 환경의 상호작용을 모니터링할 수 있는 Jupyter Notebook을 추가하였다. 이것은 agent.act(observation)
이라는 함수가 있는 모든 agent
에 쓸 수 있고, 무엇을 모니터링할 지 설정할 수도 있다. 현재 지원하는 것은 observation, reward, 그리고 action이다. 아래의 비디오는 pelvis의 포지션, reward, 총 reward, 그리고 첫번째 근육에 주는 힘을 관측한 것이다.
다음 주 예정
이번 주와 저번 주에는 연구를 하고 블로그를 리디자인하느라 상당히 바빠서 생각보다 이 대회에 많은 시간을 낼 수 없었다. 다음 주에는 reward space에 대해서 알아보는 것을 끝으로 환경을 살펴보는 것을 끝낼 것이다.
아마 몇 주 후에 대회가 2라운드로 진행될 텐데, 그러면 에이전트는 현재처럼 3 m/s의 속도로 달리는 것이 아니라, 무작위로 바뀌는 속도 벡터를 따라가야 한다. 현재 환경에 존재하는 몇 가지 버그 또한 그 때 수정될 것 같다 (Issues #129, #133). 그러므로 2라운드가 시작되면 첫 주는 바뀐 점을 소개하면서, osim-rl-helper
를 업데이트한 것에 대해 포스트를 쓰고, 그 이후 본격적으로 에이전트를 학습시키는 것을 시작할 것 같다.