This post illustrates generative LSTM via a plain vanilla LSTM.

Warm up

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import numpy as np
from matplotlib import pyplot
from matplotlib.patches import PathPatch
from matplotlib.path import Path


def create_rect():
    w,h=np.random.random(2)
    return(np.array([0,0,w,0,w,h,0,h]).reshape(4,2))


def draw_rect(input_rect):
    input_rect  =input_rect.tolist()
    input_rect.append(input_rect[0])
    codes = [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY]
    path = Path(input_rect, codes)
    axis = pyplot.gca()
    patch = PathPatch(path)
    axis.add_patch(patch)
    axis.set_xlim(-0.1,1,1)
    axis.set_ylim(-0.1,1,1)
    pyplot.show()

for i in range(5):
    draw_rect(create_rect())

Preparing Training Data

1
2
3
4
5
6
7
8
9
np.random.seed(1234)
n_samples = 10000
data      = np.array([create_rect() for _ in range(n_samples)])
data      = np.array([np.c_[data[i,0:-1,:],data[i,1:,:]] for i in range(len(data))])
X         = data[:,:,0:2]
Y         = data[:,:,2:]

X         = X.reshape(X.shape[0]*X.shape[1],1,2)
Y         = Y.reshape(Y.shape[0]*Y.shape[1],2)

Building the model

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from keras.models import Sequential
from keras.layers import LSTM, Dense

model = Sequential()
model.add(LSTM(10, input_shape=(1,2)))
model.add(Dense(2, activation='linear'))
model.compile(loss='mae', optimizer='adam')
model.summary()
n_epochs = 100
history=model.fit(X,Y, epochs=n_epochs, shuffle=False)

Test the Model

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
n_samples = 10
data      = np.array([create_rect() for _ in range(n_samples)])
data      = np.array([np.c_[data[i,0:-1,:],data[i,1:,:]] for i in range(len(data))])
X         = data[:,:,0:2]
Y         = data[:,:,2:]

X         = X.reshape(X.shape[0]*X.shape[1],1,2)
Y         = Y.reshape(Y.shape[0]*Y.shape[1],2)

Y_pred = model.predict(X)

for i in range(int(len(Y_pred)/3)):
    test = np.r_[np.zeros((1,2)),Y_pred[3*i:3*(i+1),:]]
    draw_rect(test)

Takeaways If you know how the various building blocks of keras, then it is easy to work through the various LSTM architectures and work through it