HW#1 Imitation Learning
HW #1
Behavioral Cloning
DAgger 를 적용해보기 전에는 replay buffer 에서 sampling 하는 것과 MLP policy 네트워크 코드만 작성하면 된다.
policy 에서는 observation 과 action 을 mapping 하는 MLP 구조로 되어 있어, forward()
부분에는 코랩 튜토리얼을 바탕으로 gaussian distribution 을 output 으로 만듦.
처음에는 mean_net, log_std
가 왜 있는지, nn.Sequential
로 MLP 를 만들고도 왜 forward()
를 따로 구현해야 하는지 잘 몰라서 (보통 튜토리얼 예제들과 다르다보니) 헤매다가 가 distribution 인 내용을 이해하고 변수들의 존재 이유를 알 수 있었음.
update()
함수에서는 확률분포로부터 sampling 한 observation 을 얻고, 이를 MSE(square loss) 나 NLL(Negative log-likelihood) 로 Loss 를 계산한다.
https://wensun.github.io/CS4789_data/Imitation_Learning_April_8_annotated.pdf
위 자료에서 많이 사용되는 것이 NLL 이나 MSE 라고 하였고, quadratic error 증명 파트에서 MSE Loss 를 사용해서 이를 그대로 코드에 사용함.
https://pytorch.org/docs/stable/generated/torch.nn.MSELoss.html
궁금한 점
1. 보통 PyTorch 예제를 보면 모델을 정의하고 ⇒ expert_policy 에서 forward()
대신 모델의 클래스 변수에 넣어 y = net(x)
와 같이 사용한다. 아마도 이렇게 하면 nn.Module
상위 클래스의 forward()
함수가 wrapping 되어 input_dim 으로 넣어주면 feed foward 가 자동으로 되는 것으로 보이는데,
여기 코드를 짤 때는 update()
가 클래스 내부에 있어서 클래스 변수명을 사용할 수 없어 forward()
를 직접 호출하였는데 맞는지는 모르겠다.self(observation)
으로 작성되어 있음!!
2. NLLLoss 로 짜는 경우에는 코랩 예제처럼 loss = -self.forward.log_prob(actions).sum()
로 하거나 loss = -self.forward.log_prob(actions).mean()
으로 하는 것 같다. (어떤 것이 맞는 방법인지?)
https://pytorch.org/docs/stable/generated/torch.nn.NLLLoss.html
-
What is Optimizer (e.g. Adam)?
주어진 코드에서 Adam 을 기본적으로 사용하길래, optimizer 의 역할이 무엇인지 안쓰면 안되는지에 대해 알아보았음.
https://medium.com/cdri/optimizer에-대한-전반적인-이해-633d8ec9ac1b
https://heeya-stupidbutstudying.tistory.com/entry/ML-신경망에서의-Optimizer-역할과-종류
DAgger
Behavioral cloning 에서는 n_iter
가 1 이지만 DAgger 에서는 여러 번 학습하며 expert 의 데이터를 가져와야 한다.
environment 에서 policy 를 수행해서 얻은 결과를 라벨링을 통해 데이터셋을 수정하고 이를 가지고 policy 를 다시 학습시킨다.
코드에서는 샘플링한 action 을 expert 의 action 으로 바꾸는 방식으로 DAgger 를 적용하였다.
앞서 Behavioral cloning 코드를 돌려보려면 sample_trajectory
함수도 작성했어야 하므로, 여기 부분은 지시사항에 맞게 작성만 해주면 의외로 쉽게 마무리된다.
궁금한 점
- *
def* sample_trajectories(*env*, *policy*, *min_timesteps_per_batch*, *max_path_length*, *render*=False):
에서max_path_length
는 어떤 변수를 의미하는지?
DAgger 에서 sampling 할 때 total_envsteps
와 envsteps_this_batch
중 어떤 변수를 넣어야 맞는지 모르겠음.
- 몇몇 코드를 맞게 짠 것인지? 현재는 DAgger 를 실행하면 index out of range 에러가 나타남.
아마도 sample_trajectory
구현 부분에서 문제가 있어보임. (1번과 연관이 있거나)
디버깅 및 제출
Important
docs 폴더에 Analysis 와 결과 제출 pdf 파일 업로드.
코드에서 잘못된 부분은 위 궁금한 점에서 max_path_length
에 잘못된 변수를 넣었던 것이다.
여기에 total_envsteps
나 envsteps_this_batch
가 아닌 episode length 가 들어가야 한다.
두 번째로 random.permutation
으로 무작위 학습 데이터를 가져오는 부분에서 잘못되었다.
위와 같이 전체 데이터 중에서 batch_size
만큼 무작위로 가져와야 한다.
이전에는 아래와 같이 작성했다.
세 번째로 rsample()
과 sample()
의 차이이다.
https://stackoverflow.com/questions/60533150/what-is-the-difference-between-sample-and-rsample
forward
에서 distributions.Normal(self.mean_net(observation), self.logstd.exp())
을 return 하도록 하였고, action 을 가져올 때마다 .sample()
을 사용하였다. 근데 성능이 매우 저조하였고 가장 높은게 expert policy의 약 0.3% 였다. 여러 param 들을 바꿔서 테스트해보아도 정상적인 연관성이 나타나지 않았다.
어떤 환경은 evaluation 에서의 episode length 가 1000 으로 끝까지 수행하였음에도 평균 return 이 작았다.
그래서 문제를 찾아서 아래와 같이 수정하였다.
loss 를 계산하여 신경망을 학습하는 경우에는 .rsample()
을 사용해서 넣어주었다.
sample_trajectory()
에서 action 을 한번 가져올 때는 .sample()
을 사용하였다.
그랬더니 성능들이 정상적으로 나왔고 제출 파일까지 작성 완료.