Source code for greenlearning.loss_function

from .utils.backend import tf
from .utils import config


[docs]class loss_function: """Loss function for learning Green's functions and homogeneous solutions. Inputs: matrices of neural networks G and N. """ def __init__(self, G, N): self.G = G self.N = N self.build() @property def outputs(self): return self.loss
[docs] def build(self): """Create Tensorflow placeholders and build the loss function.""" # Spatial inputs self.xF = tf.placeholder(config.real(tf), [None, None]) self.xU = tf.placeholder(config.real(tf), [None, None]) # Spatial dimension d = self.N[0].layers[0] # Number of input data n_input = len(self.G[0]) n_output = len(self.G) # Number of training points Nu = tf.shape(self.xU)[0] Nf = tf.shape(self.xF)[0] # Evaluation points for G Lu = [] Lf = [] for i in range(d): xG = tf.reshape(tf.repeat(tf.reshape( self.xU[:, i], (1, Nu)), Nf, 0), (Nu * Nf, 1)) yG = tf.reshape(tf.repeat(tf.reshape( self.xF[:, i], (Nf, 1)), Nu, 1), (Nu * Nf, 1)) Lu.append(xG) Lf.append(yG) training_G = tf.concat(Lu + Lf, 1) # Training data self.f = tf.placeholder(config.real(tf), shape=[None, None, n_input]) self.u = tf.placeholder(config.real(tf), shape=[None, None, n_output]) # Quadrature weights self.weights_x = tf.placeholder(config.real(tf), shape=[None, None]) self.weights_y = tf.placeholder(config.real(tf), shape=[None, None, 1]) # Multiply f by quadrature weights f_weights = tf.multiply(self.weights_y, self.f) # Compute the loss function # Loop over the number of outputs self.loss = 0 for i in range(n_output): # Loop over the number of inputs self.loss_i = 0 for j in range(n_input): # Evaluate Gij at all spatial points self.G_output = self.G[i][j].evaluate(training_G) # Compute integral of Gij*fj over y lossij = tf.reshape(self.G_output, (Nf, -1)) # Transpose loss1, multiply by the vector F and divide by the number of samples self.loss_i = self.loss_i + \ tf.matmul(lossij, f_weights[:, :, j], transpose_a=True) # Get output of homogeneous solution self.N_output = self.N[i].evaluate(self.xU) # Difference with u loss_N = tf.repeat(self.N_output, tf.shape(self.u)[1], 1) relative_error = tf.divide( tf.reduce_sum(tf.multiply(self.weights_x, tf.square( self.u[:, :, i] - self.loss_i - loss_N)), 0), tf.reduce_sum(tf.multiply(self.weights_x, tf.square(self.u[:, :, i])), 0)) self.loss = self.loss + tf.reduce_mean(relative_error)
[docs] def feed_dict(self, inputs_xU, inputs_xF, inputs_f, inputs_u, weights_x, weights_y): """Construct a feed_dict to feed values to TensorFlow placeholders.""" feed_dict = {self.xU: inputs_xU, self.xF: inputs_xF, self.f: inputs_f, self.u: inputs_u, self.weights_x: weights_x, self.weights_y: weights_y} return feed_dict