import tensorflow as tf

            >>> m.optimize(X, Y, 'L-BFGS-B', disp=False, ftol=.0001)
            message: 'SciPy optimizer completed successfully.'
            success: True
                  x: array([...])
            >>> print("m.a: {:.3f}".format(np.asscalar(m.a.value)))
            m.a: 0.001
            >>> print("m.b: {:.3f}".format(np.asscalar(m.b.value)))
            m.b: 1.000

        """
        X_key = X if isinstance(X, tf.Tensor) else None
        Y_key = Y if isinstance(Y, tf.Tensor) else None
        key = ("_Model__loss", X_key, Y_key)
        if key not in self.cache:
            X_tensor = (X if isinstance(X, tf.Tensor) else
                        tf.placeholder(tf.as_dtype(X.dtype)))
            Y_tensor = (Y if isinstance(Y, tf.Tensor) else
                        tf.placeholder(tf.as_dtype(Y.dtype)))
            self.cache[key] = (self._compile_loss(X_tensor, Y_tensor),
                               X_tensor, Y_tensor)
        loss, X_tensor, Y_tensor = self.cache[key]

        feed_dict = self.feed_dict
        if not isinstance(X, tf.Tensor): feed_dict[X_tensor] = X
        if not isinstance(Y, tf.Tensor): feed_dict[Y_tensor] = Y

        variables = [p.free_state for p in self.params if not p.fixed]
        variables = utils.unique(variables)
        free_state = tf.concat(0, [tf.reshape(v, [-1]) for v in variables])

