Jupyter(Ubuntu 14.04)を介して、p2.xlarge AWS サーバーでpython 2.7スクリプトを実行しています。シミュレーションをレンダリングできるようにしたいと思います。
最小限の作業例
import gym
env = gym.make('CartPole-v0')
env.reset()
env.render()
env.render()
は(とりわけ)次のエラーを発生させます。
...
HINT: make sure you have OpenGL install. On Ubuntu, you can run
'apt-get install python-opengl'. If you're running on a server,
you may need a virtual frame buffer; something like this should work:
'xvfb-run -s \"-screen 0 1400x900x24\" python <your_script.py>'")
...
NoSuchDisplayException: Cannot connect to "None"
シミュレーションをどのように見ることができるかをいくつか教えてください。インラインで取得できれば理想的ですが、表示方法はどれでもいいでしょう。
Edit:これは、従来のコントロールなど、一部の環境での問題です。
更新I
this に触発されたxvfb-run -s \"-screen 0 1400x900x24\" python <your_script.py>
(私は仕事をすることができなかった)の代わりに、以下を試しました。
xvfb-run -a jupyter notebook
元のスクリプトを実行すると、代わりに取得できます
GLXInfoException: pyglet requires an X server with GLX
IIを更新
問題 #154 は関連しているようです。ポップアップを無効にして、RGBカラーを直接作成してみました
import gym
env = gym.make('CartPole-v0')
env.reset()
img = env.render(mode='rgb_array', close=True)
print(type(img)) # <--- <type 'NoneType'>
img = env.render(mode='rgb_array', close=False) # <--- ERROR
print(type(img))
ImportError: cannot import name gl_info
を取得します。
アップデートIII
@ Torxed からインスピレーションを得て、ビデオファイルを作成してからレンダリングしようとしました(完全に満足できるソリューション)。
「 結果の記録とアップロード 」のコードを使用する
import gym
env = gym.make('CartPole-v0')
env.monitor.start('/tmp/cartpole-experiment-1', force=True)
observation = env.reset()
for t in range(100):
# env.render()
print(observation)
action = env.action_space.sample()
observation, reward, done, info = env.step(action)
if done:
print("Episode finished after {} timesteps".format(t+1))
break
env.monitor.close()
あなたの提案に従ってみましたが、ImportError: cannot import name gl_info
の実行時にenv.monitor.start(...
を取得しました。
私の理解から、問題はOpenAIがpyglet
を使用し、pyglet
がレンダリングされる画像のRGBカラーを計算するために画面を「必要」とすることです。 したがって、pythonをだましてモニターが接続されていると考える必要があります
IVを更新
参考までに、バンブルビーを使用したオンラインのソリューションが機能しているようです。サーバーを制御できればこれは機能するはずですが、AWSはVMで実行されるため、これを使用できるとは思いません。
Vを更新
この問題があり、何をすべきかわからない場合(私のように)、ほとんどの環境の状態は単純で、独自のレンダリングメカニズムを作成できます。あまり満足できませんが、知っています。
簡単な解決策が得られました:
$ xvfb-run -s "-screen 0 1400x900x24" jupyter notebook
import matplotlib.pyplot as plt
%matplotlib inline
from IPython import display
def show_state(env, step=0, info=""):
plt.figure(3)
plt.clf()
plt.imshow(env.render(mode='rgb_array'))
plt.title("%s | Step: %d %s" % (env._spec.id,step, info))
plt.axis('off')
display.clear_output(wait=True)
display.display(plt.gcf())
注:環境がunwrapped
でない場合は、env.env
をshow_state
に渡します。
これ GitHubの問題は、私にとってはうまくいく答えを与えました。サーバーの追加の依存関係(matplotlib
を既に持っていることを前提としています)または構成を必要としないため、素晴らしいです。
実行するだけです、例:
import gym
import matplotlib.pyplot as plt
%matplotlib inline
env = gym.make('Breakout-v0') # insert your favorite environment
render = lambda : plt.imshow(env.render(mode='rgb_array'))
env.reset()
render()
mode='rgb_array'
を使用すると、各位置のRGB値を持つnumpy.ndarray
が返され、matplotlib
のimshow
(または他のメソッド)はこれらを適切に表示します。
同じセルでmultiple回レンダリングする場合、このソリューションは毎回個別の画像をプロットすることに注意してください。これはおそらくあなたが望むものではありません。そのための適切な回避策を見つけた場合、これを更新しようとします。
this StackOverflowの答えに基づいて、ここに実用的なスニペットがあります(インタラクティブプロットでこれを行うより効率的な方法があるかもしれないことに注意してください。この方法は私のマシンで少し遅れているようです)。
import gym
from IPython import display
import matplotlib.pyplot as plt
%matplotlib inline
env = gym.make('Breakout-v0')
env.reset()
for _ in range(100):
plt.imshow(env.render(mode='rgb_array'))
display.display(plt.gcf())
display.clear_output(wait=True)
action = env.action_space.sample()
env.step(action)
私のマシンでは、これは約3倍高速でした。違いは、レンダリングするたびにimshow
を呼び出す代わりに、元のプロットのRGBデータを変更するだけです。
import gym
from IPython import display
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
env = gym.make('Breakout-v0')
env.reset()
img = plt.imshow(env.render(mode='rgb_array')) # only call this once
for _ in range(100):
img.set_data(env.render(mode='rgb_array')) # just update the data
display.display(plt.gcf())
display.clear_output(wait=True)
action = env.action_space.sample()
env.step(action)
ヘッドレスサーバーでopenai/gym(mujocoを含む)をリモートで実行およびレンダリングすることができました。
# Install and configure X window with virtual screen
Sudo apt-get install xserver-xorg libglu1-mesa-dev freeglut3-dev mesa-common-dev libxmu-dev libxi-dev
# Configure the nvidia-x
Sudo nvidia-xconfig -a --use-display-device=None --virtual=1280x1024
# Run the virtual screen in the background (:0)
Sudo /usr/bin/X :0 &
# We only need to setup the virtual screen once
# Run the program with vitural screen
DISPLAY=:0 <program>
# If you dont want to type `DISPLAY=:0` everytime
export DISPLAY=:0
使用法:
DISPLAY=:0 ipython2
例:
import gym
env = gym.make('Ant-v1')
arr = env.render(mode='rgb_array')
print(arr.shape)
# plot or save wherever you want
# plt.imshow(arr) or scipy.misc.imsave('sample.png', arr)
OpenAI Gym wrappers.Monitor
を使用してレンダリングをビデオとしてキャプチャし、それをノートブック内に表示するだけだと思います。
例:
!apt install python-opengl
!apt install ffmpeg
!apt install xvfb
!pip3 install pyvirtualdisplay
# Virtual display
from pyvirtualdisplay import Display
virtual_display = Display(visible=0, size=(1400, 900))
virtual_display.start()
import gym
from gym import wrappers
env = gym.make("SpaceInvaders-v0")
env = wrappers.Monitor(env, "/tmp/SpaceInvaders-v0")
for episode in range(2):
observation = env.reset()
step = 0
total_reward = 0
while True:
step += 1
env.render()
action = env.action_space.sample()
observation, reward, done, info = env.step(action)
total_reward += reward
if done:
print("Episode: {0},\tSteps: {1},\tscore: {2}"
.format(episode, step, total_reward)
)
break
env.close()
import os
import io
import base64
from IPython.display import display, HTML
def ipython_show_video(path):
"""Show a video at `path` within IPython Notebook
"""
if not os.path.isfile(path):
raise NameError("Cannot access: {}".format(path))
video = io.open(path, 'r+b').read()
encoded = base64.b64encode(video)
display(HTML(
data="""
<video alt="test" controls>
<source src="data:video/mp4;base64,{0}" type="video/mp4" />
</video>
""".format(encoded.decode('ascii'))
))
ipython_show_video("/tmp/SpaceInvaders-v0/openaigym.video.4.10822.video000000.mp4")
役に立てば幸いです。 ;)
私は自分でこれに遭遇しました。 xvfbをXサーバーとして使用すると、どういうわけかNvidiaドライバーと競合します。しかし、最後に this postが正しい方向を示してくれました。 -no-opengl-files
オプションを使用してNvidiaドライバーをインストールし、--no-opengl-libs
オプションを使用してCUDAをインストールすると、Xvfbは問題なく動作します。これを知っていれば、動作するはずです。しかし、これを理解するまでかなり時間がかかり、xvfbとnvidiaドライバーの問題に直面しているのは私だけではないようです。
Ubuntu 16.04 LTSを使用してAWS EC2インスタンスですべてをセットアップするために必要なすべての手順を書き留めました here。
このソリューションpyvirtualdisplay
(Xvfbラッパー)を使用することもあります。このソリューションで気に入っている点の1つは、起動時にラップする代わりに、スクリプト内から起動できることです。
from pyvirtualdisplay import Display
display = Display(visible=0, size=(1400, 900))
display.start()
ここで他の答えを参照してください: JupyterノートブックのみにOpenAIジムを表示します
ここで、フォークできる簡単な作業例を作成しました: https://kyso.io/eoin/openai-gym-jupyter レンダリングの2つの例Jupyterで-1つはmp4として、もう1つはリアルタイムgifとして。
.mp4の例は非常に単純です。
import gym
from gym import wrappers
env = gym.make('SpaceInvaders-v0')
env = wrappers.Monitor(env, "./gym-results", force=True)
env.reset()
for _ in range(1000):
action = env.action_space.sample()
observation, reward, done, info = env.step(action)
if done: break
env.close()
次に、新しいセルJupyterセルで、またはサーバーからビデオを表示できる場所にダウンロードします。
import io
import base64
from IPython.display import HTML
video = io.open('./gym-results/openaigym.video.%s.video000000.mp4' % env.file_infix, 'r+b').read()
encoded = base64.b64encode(video)
HTML(data='''
<video width="360" height="auto" alt="test" controls><source src="data:video/mp4;base64,{0}" type="video/mp4" /></video>'''
.format(encoded.decode('ascii')))
パブリックアクセスが可能なサーバーの場合は、gym-resultsフォルダーでpython -m http.server
を実行し、そこにあるビデオを見ることができます。
OpenGLを修正せずにnvidiaドライバーを再インストールするという同じ問題とI_like_foxesソリューションがありました。 Ubuntu 16.04およびGTX 1080tiに使用したコマンドは次のとおりです https://Gist.github.com/8enmann/931ec2a9dc45fde871d2139a7d1f2d78
PIL、Python Image Libraryを使用するだけで、matplotlibの使用に関する問題を回避しました。
import gym, PIL
env = gym.make('SpaceInvaders-v0')
array = env.reset()
PIL.Image.fromarray(env.render(mode='rgb_array'))
XVフレームバッファーを設定する必要がないことがわかりました。
Colaboratoryで機能するソリューションを探していましたが、最終的にはこれで終わりました
from IPython import display
import numpy as np
import time
import gym
env = gym.make('SpaceInvaders-v0')
env.reset()
import PIL.Image
import io
def showarray(a, fmt='png'):
a = np.uint8(a)
f = io.BytesIO()
ima = PIL.Image.fromarray(a).save(f, fmt)
return f.getvalue()
imagehandle = display.display(display.Image(data=showarray(env.render(mode='rgb_array')), width=450), display_id='gymscr')
while True:
time.sleep(0.01)
env.step(env.action_space.sample()) # take a random action
display.update_display(display.Image(data=showarray(env.render(mode='rgb_array')), width=450), display_id='gymscr')
編集1:
Cartpole環境ではxvfbwrapperを使用できます。
from IPython import display
from xvfbwrapper import Xvfb
import numpy as np
import time
import pyglet
import gym
import PIL.Image
import io
vdisplay = Xvfb(width=1280, height=740)
vdisplay.start()
env = gym.make('CartPole-v0')
env.reset()
def showarray(a, fmt='png'):
a = np.uint8(a)
f = io.BytesIO()
ima = PIL.Image.fromarray(a).save(f, fmt)
return f.getvalue()
imagehandle = display.display(display.Image(data=showarray(env.render(mode='rgb_array')), width=450), display_id='gymscr')
for _ in range(1000):
time.sleep(0.01)
observation, reward, done, info = env.step(env.action_space.sample()) # take a random action
display.update_display(display.Image(data=showarray(env.render(mode='rgb_array')), width=450), display_id='gymscr')
vdisplay.stop()
ただし、標準のJupyterを使用している場合は、より良い解決策があります。 CommManagerを使用して、更新されたデータURLを含むメッセージをHTML出力に送信できます。
Colabでは、CommManagerは使用できません。より制限的な出力モジュールには、eval_js()と呼ばれるメソッドがありますが、これは少し遅いようです。
これは完全な回避策かもしれませんが、デスクトップ環境でdockerイメージを使用しましたが、うまく機能します。 Dockerイメージは https://hub.docker.com/r/dorowu/ubuntu-desktop-lxde-vnc/ にあります
実行するコマンドは
docker run -p 6080:80 dorowu/ubuntu-desktop-lxde-vnc
次に、 http://127.0.0.1:6080/ を参照して、Ubuntuデスクトップにアクセスします。
以下は、マリオブラザーズのジム環境が実行されてレンダリングされている様子を示すgifです。ご覧のとおり、かなり反応がよく、スムーズです。
私のIPython環境では、Andrew Schreiberのソリューションは画像をスムーズにプロットできません。以下は私の解決策です:
Linuxサーバーの場合、jupyterを開きます
$ xvfb-run -s "-screen 0 1400x900x24" jupyter notebook
Jupyterで
import matplotlib.pyplot as plt
%matplotlib inline
%matplotlib notebook
from IPython import display
表示反復:
done = False
obs = env.reset()
fig = plt.figure()
ax = fig.add_subplot(111)
plt.ion()
fig.show()
fig.canvas.draw()
while not done:
# action = pi.act(True, obs)[0] # pi means a policy which produces an action, if you have
# obs, reward, done, info = env.step(action) # do action, if you have
env_rnd = env.render(mode='rgb_array')
ax.clear()
ax.imshow(env_rnd)
fig.canvas.draw()
time.sleep(0.01)