0

I'm training a neural network to act as a nonlinear controller. Basically, the ANN (F*) must provide a signal w = F*(u) that does B(G(w)) = G(u) for some dynamical model B.

To simulate systems and nonlinearities, I'm using Python Control, and using Keras to create a Sequential model:

# Creating model:
F = Sequential (name = 'compensator')
F.add (Dense (4, input_dim = 1, activation = 'linear', name = 'input_layer'))
F.add (Dense (4, activation =  deadzoneInverse, name = 'dense_layer'))
F.add (Dense (1, activation = 'linear', name = 'output_layer'))

and adding another layer for simulation:

F.add (Dense (1, activation = simulation, name = 'simulation_layer'))

since simulation is a custom function that uses Python Control modules, in special control.matlab.lsim, it computations needs to be done in numpy arrays. The models/functions and Keras Tensors conversions can be done like:

for B inverse:

# NumPy function:
def _dstar (x):
    y = x
    if (x > 5. * eps) or (x < -5. * eps):
        y = x
    elif (x > eps):
        y = x + a
    elif (x < -eps):
        y = x - a
    else:
        y = x * (1. + a / eps)
    return np.reshape(y, (-1, 1))

# Keras conversion:
def deadzoneInverse (x):
    x_array = K.eval(x)
    y_array = _dstar (x)
    return K.variable (y_array)

and for simulation:

def _simul (x):
    x_array = x 
    t_array = np.linspace (0, currTime, int (currTime / Ts))

    y_array, _, _ = cm.lsim (G, x_array, t_array)
    y_array = B(y_array, t_array, a)

    return y_array[-1]

def simulation (x):
    x_array = K.eval(x)
    y_value = _simul(x_array)
    return K.variable (y_value)

But when I try to F.compile, I get:

InvalidArgumentError: You must feed a value for placeholder tensor 'input_layer_input_14' with dtype float and shape [?,1]
     [[Node: input_layer_input_14 = Placeholder[dtype=DT_FLOAT, shape=[?,1], _device="/job:localhost/replica:0/task:0/device:CPU:0"]()]]

Is there a better way to implement these functions, even using Python Control (and, therefore, numPy arrays evaluated)?

  • https://stackoverflow.com/questions/39921607/how-to-make-a-custom-activation-function-with-only-python-in-tensorflow the first answer to this explains how you can design a custom activation function using functions on numpy arrays. Does that help? If so, one more useful thing to know might be that py_func became numpy_function in tf2.x (tensorflow.org/api_docs/python/tf/numpy_function). – simon Oct 17 '19 at 14:47
  • 1
    That's exactly what I was looking for! I got a `NoneType object cannot be interpreted as integer` error at `F.compile`, although evaluating the function worked fine in TensorFlow (v. 1.13). Anyway, I think I can handle from here. Thanks! – Matheus Delgado Oct 18 '19 at 12:11

0 Answers0