Convert render to small video in Reinforcement learning - python

Below is the sample code for simulation of atari games:
import numpy as np
import matplotlib.pyplot as plt
import gym
import time
env =gym.make('BreakoutNoFrameskip-v4')
print("Observation Space :",env.observation_space)
print("Action Space :",env.action_space)
env.reset()
for i in range(1000):
action =env.action_space.sample()
obs,reward,done,info =env.step(action)
env.render()
time.sleep(0.01)
if done :
env.reset()
env.close()
plt.show()
The question:
Is it possible to create a simple video from the render? So my question is whether it is possible to convert render to mp4 format?

This saves a video of every video_every'th episode to the folder "video" while maintaining rendering to screen functionality from your post.
import gym
import time
env = gym.make('BreakoutNoFrameskip-v4')
video_every = 1
env = gym.wrappers.Monitor(env, "./video", video_callable=lambda episode_id: (episode_id%video_every)==0, force=True)
print("Observation Space :",env.observation_space)
print("Action Space :",env.action_space)
env.reset()
for i in range(1000):
action =env.action_space.sample()
obs,reward,done,info =env.step(action)
env.render()
time.sleep(0.01)
if done :
env.reset()
env.close()

Related

How do I create a configuration and trainer with rasa 1.1x?

I am following an example on datacamp which is using a deprecated version of rasa_nlu. The sample code of the datacamp example looks like this.
# Import necessary modules
from rasa_nlu.converters import load_data
from rasa_nlu.config import RasaNLUConfig
from rasa_nlu.model import Trainer
# Create args dictionary
args = {"pipeline": "spacy_sklearn"}
# Create a configuration and trainer
config = RasaNLUConfig(cmdline_args=args)
trainer = Trainer(config)
# Load the training data
training_data = load_data("./training_data.json")
# Create an interpreter by training the model
interpreter = trainer.train(training_data)
# Test the interpreter
print(interpreter.parse("I'm looking for a Mexican restaurant in the North of town"))
This example imports RasaNLUConfig from rasa_nlu.config to create a config and trainer.
My question is how do I make something like this with the newer rasa 1.1x? The code that I wrote looks like this
from rasa_nlu.training_data import load_data
#Instead of from rasa_nlu import config the deprecated version used 'from rasa_nlu.config import RasaNLUConfig'
from rasa_nlu import config
from rasa_nlu.model import Trainer
#create args dictionary
args = {"pipeline": "spacy_sklearn"}
#create a configuration and trainer
config= RasaNLUConfig(cmdline_args=args)
trainer = Trainer(config)
#load training data
training_data = load_data('/content/nluintent.md')
#Create an interpreter by training the model
interpreter = trainer.train(training_data)
print(interpreter.parse('Hi, can you help me?'))
How would I be able to train the model using the new version of Rasa?

fastai cnn_learner output table of fit_one_cycle()

I have trained a CNN using fastai on Kaggle and also on my local machine. After calling learn.fit_one_cycle(1) on Kaggle I get the following table as output:
I executed the exact same code on my local machine (with Spyder ide and Python 3.7) and everything works, but I cannot see that output table. How can I display it?
This is the complete code:
from fastai import *
from fastai.vision import *
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
bs = 32
path = 'C:\\DB\\UCMerced_LandUse\\UCMerced_LandUse\\Unfoldered_Images'
pat = r"([^/\d]+)[^/]*$"
fnames = get_image_files(path)
data = ImageDataBunch.from_name_re(path, fnames, pat, ds_tfms=get_transforms(),
size = 224, bs = bs, num_workers = 0).normalize(imagenet_stats)
learn = cnn_learner(data, models.resnet34, metrics=[accuracy])
learn.fit_one_cycle(1)
The problem was that the console in Spyder was set to 'execute in current console' which doesn't seem to be able to displaye the result table. Setting it to 'execute in an external system terminal' solved the problem.

Display OpenAI gym in Jupyter notebook only

I want to play with the OpenAI gyms in a notebook, with the gym being rendered inline.
Here's a basic example:
import matplotlib.pyplot as plt
import gym
from IPython import display
%matplotlib inline
env = gym.make('CartPole-v0')
env.reset()
for i in range(25):
plt.imshow(env.render(mode='rgb_array'))
display.display(plt.gcf())
display.clear_output(wait=True)
env.step(env.action_space.sample()) # take a random action
env.close()
This works, and I get see the gym in the notebook:
But! it also opens an interactive window that shows precisely the same thing. I don't want this window to be open:
I made a working example here that you can fork: https://kyso.io/eoin/openai-gym-jupyter with two examples of rendering in Jupyter - one as an mp4, and another as a realtime gif.
The .mp4 example is quite simple.
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()
Then in a new cell
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')))
I just found a pretty nice work-around for this. This will work for environments that support the rgb_array render mode. Then we can use matplotlib's imshow with a quick replacement to show the animation. The following should work inside one cell of a jupyter notebook.
import os
import gym
import matplotlib.pyplot as plt
os.environ["SDL_VIDEODRIVER"] = "dummy"
from IPython.display import clear_output
env = gym.make("LunarLander-v2")#, render_mode="human")
env.action_space.seed(42)
observation, info = env.reset(seed=42, return_info=True)
for _ in range(1000):
observation, reward, done, info = env.step(env.action_space.sample())
if done:
observation, info = env.reset(return_info=True)
clear_output(wait=True)
plt.imshow( env.render(mode='rgb_array') )
plt.show()
env.close()
This worked for me in Ubuntu 18.04 LTS, to render gym locally. But, I believe it will work even in remote Jupyter Notebook servers.
First, run the following installations in Terminal:
pip install gym
python -m pip install pyvirtualdisplay
pip3 install box2d
sudo apt-get install xvfb
That's just it. Use the following snippet to configure how your matplotlib should render :
import matplotlib.pyplot as plt
from pyvirtualdisplay import Display
display = Display(visible=0, size=(1400, 900))
display.start()
is_ipython = 'inline' in plt.get_backend()
if is_ipython:
from IPython import display
plt.ion()
# Load the gym environment
import gym
import matplotlib.pyplot as plt
%matplotlib inline
env = gym.make('LunarLander-v2')
env.seed(23)
# Let's watch how an untrained agent moves around
state = env.reset()
img = plt.imshow(env.render(mode='rgb_array'))
for j in range(200):
# action = agent.act(state)
action = random.choice(range(4))
img.set_data(env.render(mode='rgb_array'))
plt.axis('off')
display.display(plt.gcf())
display.clear_output(wait=True)
state, reward, done, _ = env.step(action)
if done:
break
env.close()

How to display a heatmap created in python using rpy2?

I am currently trying to generate a heatmap in python from a text file, using R commands (with rpy2). It works fine in R, but when I take it to python, the Quartz interface displays quickly and then closes. I would like either to be able to save the quartz display to a file, or directly save my heatmap to a file without displaying it.
Here is the code I have been using:
import rpy2.robjects as robjects
robjects.r('''
library("gplots")
data = read.csv("/Users/.../Heatmap_data.txt")
DF = data.frame(data)
MD = data.matrix(DF,rownames.force=NA)
heatmap.2(MD, scale="none", col=redgreen(100), cexRow=0.1, key=FALSE, symkey=FALSE, trace="none", Colv=FALSE)
''')
I'm using python 2.7, on OS X Yosemite.
Thank you for any help.
import numpy as np
import rpy2.robjects as ro
import rpy2.robjects.numpy2ri
ro.numpy2ri.activate()
R = ro.r
data = np.random.random((10, 10))
R.png(file='/tmp/out.png')
R.heatmap(data)
R("dev.off()")
writes to the file /tmp/out.png without displaying the image:
.
Preventing the displayed image from immediately closing can be done like this:
script.py:
import numpy as np
import rpy2.robjects as ro
import rpy2.robjects.numpy2ri
import rpy2.rinterface as rinterface
import time
import threading
ro.numpy2ri.activate()
R = ro.r
def ion():
def r_refresh(interval = 0.03):
while True:
rinterface.process_revents()
time.sleep(interval)
t = threading.Thread(target=r_refresh)
t.daemon = True
t.start()
ion()
data = np.random.random((10, 10))
R.heatmap(data)
R("dev.copy(png,'/tmp/out2.png')")
R("dev.off()")
try:
# for Python2
raw_input()
except NameError:
# for Python3
input()
The raw_input or input call prevents the Python interpreter from exiting, thus allowing the window to stay open, until the user presses Enter.
The ion function calls rinterface.process_revents() periodically so the
displayed window will react to GUI events such as resizing or being closed.
dev.copy(png,'/tmp/out2.png') saves the already-displayed image to a
file.

python matplotlib animation save error when using multiprocessing

I'm creating a matplotlib animation that runs through a sequence of images from file. The files that I'm visualizing are typically quite large and there is a significant load time (~5sec) for each stack of images. I've managed to get the animation to run smoothly by staggering the loading processes with multiprocessing, but I'm having trouble saving the animation as a video file.
Here's the code:
from matplotlib import animation
import pylab as plt
import numpy as np
import multiprocessing as mp
import logging
logger = mp.log_to_stderr(logging.INFO)
import time
def qloader(queue, threshold=100, nfiles=3):
'''trigger a load process if number of items in queue drops below threshold'''
while nfiles:
if queue.qsize() < threshold:
logger.info( 'qsize {}'.format(queue.qsize()) )
time.sleep( 1 ) #pretend to load data
data = np.random.rand(25,100,100)
logger.info( 'Adding data to queue' )
for d in data:
queue.put(d)
logger.info( 'Done adding data!' )
nfiles -= 1
else:
queue.put( None ) #sentinal
def update(frame, im, queue):
'''update the image'''
logger.info( 'Updating frame %d'%frame )
data = queue.get()
if data is None:
print( 'Queue is empty!' )
return
im.set_data( data )
return im
#create data queue
mgr = mp.Manager()
queue = mgr.Queue()
threshold = 20 #
#start load process
p = mp.Process( name='loader', target=qloader, args=(queue, threshold) )
p.start()
#start animation
fig, ax = plt.subplots()
im = ax.imshow( np.random.rand(100,100) )
ani = animation.FuncAnimation( fig, update, frames=75, interval=100, repeat=0, fargs=(im, queue) )
ani.save('foo.mp4', 'ffmpeg')
The code runs without errors, but the file it produces is somehow corrupted. When I try view it with vlc I get a long repeating error stream...
$ vlc foo.mp4
VLC media player 2.0.8 Twoflower (revision 2.0.8a-0-g68cf50b)
[0xf69108] main libvlc: Running vlc with the default interface. Use 'cvlc' to use vlc without interface.
[0x7f37fcc01ac8] mp4 demux error: cannot find any /moov/trak
[0x7f37fcc01ac8] es demux error: cannot peek
...
[0x7f37fcc01ac8] ps demux error: cannot peek
[0x7f37fcc01ac8] mpgv demux error: cannot peek
[0x7f37fcc01ac8] mjpeg demux error: cannot peek
[0x7f37fcc01ac8] ps demux error: cannot peek
[0x7f3824000b78] main input error: no suitable demux module for `file/://.../foo.mp4'
...
I've tried saving in various file formats, using various writers and encoders, with much the same result.
This problem only occurs when using multiprocessing to load the data. If I just create the data with data = np.random.rand(75,100,100), the animation saves without problems.
Question: How do I get matplotlib.animation to play along with multiprocessing?
By default animation.MovieWriter uses a subprocess.PIPE to feed the frames to the writer. This does not seem to work when using multiprocessing for some reason. Changing the last line to
ani.save('foo.mp4', 'ffmpeg_file')
tells the writer to temporarily save the frames to disc before composing the movie, which side-steps the problem.

Categories