Нейронная сеть поездов с пользовательской функцией потерь - PullRequest
0 голосов
/ 29 апреля 2020

У меня проблемы с обучением моей нейронной сети с пользовательской функцией потерь. Функцией потерь, которую я хочу использовать, является следующее MSE, которое состоит из MSE_y и MSE_f: enter image description here

Следует отметить, что число N_f> N_y. Поэтому я хочу вычислить прогнозы для всех данных поезда, а после этого я хочу вычислить мою MSE-функцию. Значения f_i для MSE_f рассчитываются отдельно, но для простоты они здесь просто случайные числа (в коде: f). После расчета потерь я хочу оптимизировать сеть. Проблема в том, что я не знаю точно, как я могу получить эту функцию потерь. Я пытался реализовать это следующим образом:

import numpy as np
import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten
from tensorflow.keras import Model
from tensorflow.keras.losses import Loss
import matplotlib.pyplot as plt

# Build the tf.keras model using the Keras model subclassing API:
class MyModel(Model):
    def __init__(self):
        super(MyModel, self).__init__()
        self.flatten = Flatten(input_shape=(2, 1))
        self.d1 = Dense(28, activation='sigmoid')
        self.output_ = Dense(1, activation='sigmoid')

    def call(self, x):
        x = self.flatten(x)
        x = self.d1(x)
        x = self.output_(x)
        return x

def myLoss(y_pred, y_true, f):
    loss_func = tf.reduce_mean(tf.square(y_pred-y_true)) + tf.reduce_mean(tf.square(f)) 
    return loss_func


def train(EPOCHS, train_ds, f):
    for epoch in range(EPOCHS):
        # Reset the metrics at the start of the next epoch
        train_loss.reset_states()

        Y_pred = [None] * N_y
        Y_true = [None] * N_y
        i = 0
        with tf.GradientTape() as tape:
            for point, y_true in train_ds:
                y_pred = model(point, training=True)
                Y_pred[i] = y_pred
                Y_true[i] = y_true
                i += 1
            Y_pred = tf.convert_to_tensor(Y_pred, np.float32)
            Y_true = tf.convert_to_tensor(Y_true, np.float32)

            loss = loss_object(Y_true, Y_pred, f)  

        weights = model.trainable_variables
        gradients = tape.gradient(loss, weights)
        optimizer.apply_gradients(zip(gradients, model.trainable_variables))

        train_loss(loss)     
        Loss_history.append(train_loss.result())
        print('Epoch {}, Loss: {}'.format(epoch+1, train_loss.result()))

if __name__ == "__main__":

    np.random.seed(0)
    N_y = 5
    N_f = 10
    # Create N_y= 5 training data samples, each has a x and t-value
    x_train = np.random.rand(N_y, 1, 2, 1).astype("float32")
    y_train = np.random.rand(N_y, 1).astype("float32")

    # Create additional N_f = 10 (for MSE_f)
    x_f_train = np.random.rand(N_f, 1).astype("float32")                       

    #Create tf Datasets
    train_ds = tf.data.Dataset.from_tensor_slices((x_train, y_train))
    f = tf.convert_to_tensor(x_f_train, np.float32)

    # Create an instance of the model
    model = MyModel()
    optimizer = tf.keras.optimizers.SGD()

    #Loss-Funktion
    loss_object = myLoss

    #I don't know if this metrics is correct for the loss-function?
    train_loss = tf.keras.metrics.Mean(name='train_loss')

    Loss_history = []
    EPOCHS = 10
    train(EPOCHS, train_ds, f)

    plt.figure(1)
    plt.subplot(1, 1, 1)
    plt.plot(Loss_history)
    plt.show()

Это правильный способ обучить мою сеть с помощью MSE с функцией потерь? Мне кажется, что for-l oop и списки Y_pred, Y_true в градиентной ленте являются вычислительными, а не оптимальными, но когда я помещаю его вне градиентной ленты, не существует вычислительного графа и, следовательно, градиентов для оптимизации. Нет и ничего не работает. Короче говоря, как я могу оптимизировать свою сеть с моим конкретным c функцией потери MSE? Спасибо за вашу помощь:)


Я использую следующие конфигурации:

  • Python -Версия: 3.7.6
  • Tensorflow-Version: 2.1 .0
  • Keras-версия: 2.2.4-tf
...