Ich führe ein Python 2.7-Skript auf einem p2.xlarge AWS- Server über Jupyter (Ubuntu 14.04) aus. Ich möchte meine Simulationen rendern können.
Minimales Arbeitsbeispiel
import gym
env = gym.make('CartPole-v0')
env.reset()
env.render()
env.render()
macht (unter anderem) folgende Fehler:
...
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"
Ich möchte einige, wie man die Simulationen sehen kann. Es wäre ideal, wenn ich es inline bekommen könnte, aber jede Anzeigemethode wäre nett.
Bearbeiten : Dies ist nur in einigen Umgebungen ein Problem, z. B. bei der klassischen Steuerung.
Update I.
Inspiriert davon versuchte ich Folgendes anstelle des xvfb-run -s \"-screen 0 1400x900x24\" python <your_script.py>
(was ich nicht zur Arbeit bringen konnte).
xvfb-run -a jupyter notebook
Wenn ich jetzt das ursprüngliche Skript ausführe, bekomme ich stattdessen
GLXInfoException: pyglet requires an X server with GLX
Update II
Problem Nr. 154 scheint relevant zu sein. Ich habe versucht, das Popup zu deaktivieren und die RGB-Farben direkt zu erstellen
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))
Ich verstehe ImportError: cannot import name gl_info
.
Update III
Mit Inspiration von @ Torxed ich versucht, eine Videodatei zu erstellen und sie dann zu rendern (eine völlig zufriedenstellende Lösung).
Verwenden des Codes aus " Aufzeichnen und Hochladen von Ergebnissen "
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()
Ich habe versucht, Ihren Vorschlägen zu folgen, bin aber ImportError: cannot import name gl_info
beim Laufen davongekommen env.monitor.start(...
.
Nach meinem Verständnis besteht das Problem darin, dass OpenAI einen Bildschirm verwendet pyglet
und pyglet
"benötigt", um die RGB-Farben des zu rendernden Bildes zu berechnen. Es ist daher notwendig, Python auszutricksen, um zu glauben, dass ein Monitor angeschlossen ist
Update IV
Zu Ihrer Information, es gibt Online-Lösungen mit Hummeln, die zu funktionieren scheinen. Dies sollte funktionieren, wenn Sie die Kontrolle über den Server haben. Da AWS jedoch in einer VM ausgeführt wird, können Sie dies meiner Meinung nach nicht verwenden.
Update V.
Nur wenn Sie dieses Problem haben und nicht wissen, was Sie tun sollen (wie ich), ist der Status der meisten Umgebungen so einfach, dass Sie Ihren eigenen Rendering-Mechanismus erstellen können. Nicht sehr befriedigend, aber ... du weißt schon.
quelle
VideoRecorder
Klasse als Teil vonenv.wrapper.Monitor
jetztenv.render
direkt anruft .Antworten:
Eine einfache Lösung funktioniert:
Wenn Sie sich auf einem Linux-Server befinden, öffnen Sie jupyter mit
In Jupyter$ xvfb-run -s "-screen 0 1400x900x24" jupyter notebook
Nach jedem Schrittimport 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())
Hinweis: Wenn dies in Ihrer Umgebung nicht der Fall ist
unwrapped
, übergeben Sieenv.env
anshow_state
.quelle
/bin/xvfb-run: line 181: 0: command not found
und/bin/xvfb-run: line 186: kill: (31449) - No such process
Fehler. Irgendeine Idee?24
"1400x900x24
? Ich vermute,1400
ist Monitorbreite und900
MonitorhöheDiese GitHub-Ausgabe gab eine Antwort, die für mich großartig funktionierte. Es ist schön, weil es keine zusätzlichen Abhängigkeiten (ich nehme an, Sie haben bereits
matplotlib
) oder Konfiguration des Servers erfordert .Einfach laufen, zB:
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()
Wenn
mode='rgb_array'
Sie verwenden, erhalten Sie ein anumpy.ndarray
mit den RGB-Werten für jede Position undmatplotlib
'simshow
(oder andere Methoden) zeigen diese gut an.Beachten Sie , dass diese Lösung jedes Mal ein separates Bild zeichnet , wenn Sie mehrere Male in derselben Zelle rendern . Dies ist wahrscheinlich nicht das, was Sie wollen. Ich werde versuchen, dies zu aktualisieren, wenn ich eine gute Problemumgehung dafür finde.
Aktualisieren Sie, um mehrere Male in einer Zelle zu rendern
Basierend auf dieser StackOverflow-Antwort ist hier ein funktionierender Ausschnitt (beachten Sie, dass es effizientere Möglichkeiten gibt, dies mit einem interaktiven Plot zu tun; dieser Weg scheint auf meinem Computer etwas verzögert zu sein):
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)
Update zur Steigerung der Effizienz
Auf meiner Maschine war dies ungefähr dreimal schneller. Der Unterschied besteht darin, dass
imshow
wir nicht jedes Mal aufrufen, wenn wir rendern, sondern nur die RGB-Daten im ursprünglichen Plot ändern.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)
quelle
env.render()
importiert wirdgl_info
, auch wenn sich das Fenster nicht öffnet.mode=rgb_array
ändert das nichtenv = gym.make('Breakout-v0')
mitenv = gym.make('CartPole-v0')
in Ihren Beispielen und Sie werden sehen , was ich meine. 'Breakout' ist zufällig ein Atari-Spiel, das dasatari_py.ALEInterface()
als Renderer verwendet und ein Bild zurückgibt. siehe github.com/openai/gym/blob/master/gym/envs/atari/…Ich habe es geschafft, Openai / Gym (auch mit Mujoco) auf einem kopflosen Server aus der Ferne zu rendern und zu rendern.
# 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
Verwendung:
DISPLAY=:0 ipython2
Beispiel:
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)
quelle
ContextException: Could not create GL context remote
und keine der anderen Lösungen hat für mich funktioniert, aber das hat perfekt funktioniert.Ich denke, wir sollten Renderings einfach mit OpenAI Gym als Video aufnehmen
wrappers.Monitor
und dann im Notebook anzeigen.Beispiel:
Abhängigkeiten
!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()
Als Video aufnehmen
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()
Anzeige im Notebook
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")
Ich hoffe, es hilft. ;)
quelle
/tmp/SpaceInvaders-v0
. Der Name des Videos kann unterschiedlich sein. Alternativ können Sie einen bekannten Ordner fürenv = wrappers.Monitor(env, "/tmp/SpaceInvaders-v0")
Es gibt auch diese Lösung mit
pyvirtualdisplay
(einem Xvfb-Wrapper). Eine Sache, die ich an dieser Lösung mag, ist, dass Sie sie aus Ihrem Skript heraus starten können, anstatt sie beim Start umbrechen zu müssen:from pyvirtualdisplay import Display display = Display(visible=0, size=(1400, 900)) display.start()
quelle
Ich bin selbst darauf gestoßen. Die Verwendung von xvfb als X-Server kollidiert irgendwie mit den Nvidia-Treibern. Aber schließlich hat mich dieser Beitrag in die richtige Richtung gelenkt. Xvfb funktioniert problemlos, wenn Sie den Nvidia-Treiber mit der
-no-opengl-files
Option und CUDA mit der--no-opengl-libs
Option installieren . Wenn Sie das wissen, sollte es funktionieren. Aber da ich einige Zeit gebraucht habe, bis ich das herausgefunden habe und es scheint, dass ich nicht der einzige bin, der auf Probleme mit xvfb und den nvidia-Treibern stößt.Ich habe alle notwendigen Schritte aufgeschrieben, um alles auf einer AWS EC2-Instanz mit Ubuntu 16.04 LTS einzurichten .
quelle
Ich habe die Probleme mit der Verwendung von matplotlib vermieden, indem ich einfach PIL, Python Image Library, verwendet habe:
import gym, PIL env = gym.make('SpaceInvaders-v0') array = env.reset() PIL.Image.fromarray(env.render(mode='rgb_array'))
Ich stellte fest, dass ich den XV-Frame-Puffer nicht einstellen musste.
quelle
env.render
Funktion, PIL hat nichts mit diesem Problem zu tun.SpaceInvaders-v0
. Dieses Problem wird nur durch eine bestimmte Umgebung verursacht, z. B. durch die klassische Steuerung. Ich habe das OP entsprechend bearbeitetIch suchte nach einer Lösung, die in Colaboratory funktioniert, und endete damit
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')
EDIT 1:
Sie können xvfbwrapper für die Cartpole-Umgebung verwenden.
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()
Wenn Sie mit Standard-Jupyter arbeiten, gibt es jedoch eine bessere Lösung. Mit dem CommManager können Sie Nachrichten mit aktualisierten Daten-URLs an Ihre HTML-Ausgabe senden.
Beispiel für einen IPython-Inline-Bildschirm
In Colab ist der CommManager nicht verfügbar. Das restriktivere Ausgabemodul hat eine Methode namens eval_js (), die ziemlich langsam zu sein scheint.
quelle
SpaceInvaders-v0
, aber wenn ich anrufeCartPole-v0
oderPendulum-v0
bekommeNameError: name 'base' is not defined
. Irgendeine Idee?!apt-get install python-pyglet && pip install pyglet
die Laufzeit neu zu startenIch beziehe mich hier auf meine andere Antwort: Zeigen Sie das OpenAI-Fitnessstudio nur im Jupyter-Notizbuch an
Ich habe hier ein schnelles Beispiel erstellt, das Sie teilen können: https://kyso.io/eoin/openai-gym-jupyter mit zwei Beispielen für das Rendern in Jupyter - eines als mp4 und eines als Echtzeit-GIF.
Das .mp4-Beispiel ist recht einfach.
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()
Dann in einer neuen Zelle Jupyter-Zelle oder laden Sie sie vom Server an einen Ort herunter, an dem Sie das Video ansehen können.
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')))
Wenn Sie sich auf einem Server mit öffentlichem Zugriff befinden, können Sie
python -m http.server
im Ordner mit den Turnhallenergebnissen einfach die Videos dort ansehen.quelle
Ich bin auf das gleiche Problem gestoßen und bin auf die Antworten hier gestoßen. Das Mischen half mir, das Problem zu lösen.
Hier ist eine schrittweise Lösung:
Installieren Sie Folgendes:
Starten Sie Ihr Jupyter-Notizbuch mit dem folgenden Befehl:
xvfb-run -s "-screen 0 1400x900x24" jupyter notebook
Im Notizbuch:
import gym import matplotlib.pyplot as plt %matplotlib inline env = gym.make('MountainCar-v0') # insert your favorite environment env.reset() plt.imshow(env.render(mode='rgb_array')
Jetzt können Sie dasselbe in eine Schleife einfügen, um es mehrmals zu rendern.
from IPython import display 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)
Hoffe, dass dies für alle anderen funktioniert, die noch vor einem Problem stehen. Vielen Dank an Andrews und Nathan für ihre Antworten.
quelle
AttributeError: 'ImageData' object has no attribute 'data'
und die Installationpyglet-v1.3.2
wurde für mich von der Lösung hier behoben .Ich hatte das gleiche Problem und die I_like_foxes-Lösung, um NVIDIA-Treiber ohne OpenGL-Fehler neu zu installieren. Hier sind die Befehle, die ich für Ubuntu 16.04 und GTX 1080ti verwendet habe: https://gist.github.com/8enmann/931ec2a9dc45fde871d2139a7d1f2d78
quelle
Dies ist möglicherweise eine vollständige Problemumgehung, aber ich habe ein Docker-Image mit einer Desktop-Umgebung verwendet, und es funktioniert hervorragend. Das Docker-Image finden Sie unter https://hub.docker.com/r/dorowu/ubuntu-desktop-lxde-vnc/
Der auszuführende Befehl lautet
docker run -p 6080:80 dorowu/ubuntu-desktop-lxde-vnc
Dann durchsuchen Sie http://127.0.0.1:6080/ um auf den Ubuntu-Desktop zuzugreifen.
Unten sehen Sie ein GIF, das zeigt, wie die Mario Bros-Fitnessumgebung läuft und gerendert wird. Wie Sie sehen können, ist es ziemlich reaktionsschnell und reibungslos.
quelle
Ich habe dieses Mini-Paket erstellt , mit dem Sie Ihre Umgebung in einem Browser rendern können, indem Sie Ihrem Code nur eine Zeile hinzufügen.
Fügen Sie Ihren Code in eine Funktion ein und ersetzen Sie Ihren normalen
env.render()
durchyield env.render(mode='rgb_array')
. Verkapseln Sie diese Funktion mit demrender_browser
Dekorateur.import gym from render_browser import render_browser @render_browser def test_policy(policy): # Your function/code here. env = gym.make('Breakout-v0') obs = env.reset() while True: yield env.render(mode='rgb_array') # ... run policy ... obs, rew, _, _ = env.step(action) test_policy(policy)
Wenn Sie
your_ip:5000
in Ihrem Browser besuchen ,test_policy()
wird aufgerufen und Sie können die gerenderte Umgebung in Ihrem Browserfenster sehen.quelle
In meiner IPython-Umgebung kann die Lösung von Andrew Schreiber das Bild nicht reibungslos darstellen. Folgendes ist meine Lösung:
Wenn Sie sich auf einem Linux-Server befinden, öffnen Sie jupyter mit
$ xvfb-run -s "-screen 0 1400x900x24" jupyter notebook
In Jupyter
import matplotlib.pyplot as plt %matplotlib inline %matplotlib notebook from IPython import display
Iteration anzeigen:
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)
quelle
NameError: name 'base' is not defined
für mich. Irgendeine Idee?