Глубокая осциллирующая потеря обучения - PullRequest
0 голосов
/ 01 мая 2020

Я строю автоэнкодер, используя tensorflow, и мои потери в процессе обучения выглядят так: test and training loss

Это на самом деле довольно красиво, но мне нужно свести к минимуму колебания, насколько это возможно, это мои гиперпараметры:

batch_size = 64
learning_rate = 0.0002
num_epochs = 50
n_training_samples = 480
threshold = 10000

Я пытался увеличить размер batch_s, уменьшить / увеличить скорость обучения, но, похоже, это не имеет значения, заранее спасибо.

Это Базовая модель:

class BaseModel(Model):
    def __init__(self, input_size):
        super(BaseModel, self).__init__()
        self.weight_initializer = tf.random_normal_initializer(
            mean=0.0, stddev=0.25)
        self.bias_initializer = tf.zeros_initializer()
        self.input_size = input_size
        self.layers_shape = [1000, 750, 30, 750, 1000]

    def init_variables(self):
        self.W1 = tf.compat.v1.get_variable(
            'W1', shape=[self.input_size, self.layers_shape[0]], 
            initializer=self.weight_initializer, dtype=tf.float32)
        self.W2 = tf.compat.v1.get_variable(
            'W2', shape=[self.layers_shape[0], self.layers_shape[1]], 
             initializer=self.weight_initializer, dtype=tf.float32)
        self.W3 = tf.compat.v1.get_variable(
            'W3', shape=[self.layers_shape[1], self.layers_shape[2]],                     
            initializer=self.weight_initializer, dtype=tf.float32)
        self.W4 = tf.compat.v1.get_variable(
            'W4', shape=[self.layers_shape[2], self.layers_shape[3]],         
            initializer=self.weight_initializer, dtype=tf.float32)
        self.W5 = tf.compat.v1.get_variable(
            'W5', shape=[self.layers_shape[3], self.layers_shape[4]], 
            initializer=self.weight_initializer, dtype=tf.float32)
        self.W6 = tf.compat.v1.get_variable(
            'W6', shape=[self.layers_shape[4], self.input_size], 
            initializer=self.weight_initializer, dtype=tf.float32)

        self.b1 = tf.compat.v1.get_variable(
            'b1', shape=[self.layers_shape[0]], 
            initializer=self.bias_initializer, dtype=tf.float32)
        self.b2 = tf.compat.v1.get_variable(
            'b2', shape=[self.layers_shape[1]], 
            initializer=self.bias_initializer, dtype=tf.float32)
        self.b3 = tf.compat.v1.get_variable(
            'b3', shape=[self.layers_shape[2]], 
            initializer=self.bias_initializer, dtype=tf.float32)
        self.b4 = tf.compat.v1.get_variable(
            'b4', shape=[self.layers_shape[3]], 
            initializer=self.bias_initializer, dtype=tf.float32)
        self.b5 = tf.compat.v1.get_variable(
            'b5', shape=[self.layers_shape[4]], 
            initializer=self.bias_initializer, dtype=tf.float32)

def forward_propagation(self, x):
    with tf.name_scope('feed_forward'):
        # First Hidden Layer
        z1 = tf.linalg.matmul(x, self.W1) + self.b1
        a1 = tf.nn.relu(z1)

        # Second Hidden Layer
        z2 = tf.linalg.matmul(a1, self.W2) + self.b2
        a2 = tf.nn.relu(z2)

        # Third Hidden Layer
        z3 = tf.linalg.matmul(a2, self.W3) + self.b3
        a3 = tf.nn.relu(z3)

        # Fourth Hidden Layer
        z4 = tf.linalg.matmul(a3, self.W4) + self.b4
        a4 = tf.nn.relu(z4)

        # Fifth Hidden Layer
        z5 = tf.linalg.matmul(a4, self.W5) + self.b5
        a5 = tf.nn.relu(z5)

        prediction = tf.linalg.matmul(a5, self.W6)
    return prediction

Это другая модель, которая определяет другие техники:

class AnomalyDetector(BaseModel):
    def __init__(self, input_size, num_variables):
        super(AnomalyDetector, self).__init__(input_size)
        self.init_variables()
        self.num_variables = num_variables
        self.optimizer = tf.keras.optimizers.Adam(learning_rate=0.0002)

    def compute_loss(self, x_train):
        mse = tf.keras.losses.MeanSquaredError()
        loss = mse(x_train, self.forward_propagation(x_train))
        return loss

    def train(self, x_train):
        with tf.GradientTape() as tape:
            gradients = tape.gradient(self.compute_loss(x_train), self.trainable_variables)
            gradient_variables = zip(gradients, self.trainable_variables)
            self.optimizer.apply_gradients(gradient_variables)

Вот как я тренирую ее:

for epoch in range(num_epochs):
    temp_loss = 0
    training_dataset.shuffle(len(list(training_dataset)))
    for step, x_train in enumerate(training_dataset):
        features = tf.reshape(x_train, [1, input_size])

        model.train(features)

        loss_values = model.compute_loss(features)
        temp_loss += loss_values

        if step > 0 and step % eval_after == 0:
            test_loss = 0
            for step_test, x_test in enumerate(test_dataset):
                features = tf.reshape(x_test, [1, input_size])
                test_loss = model.compute_loss(features)

            print('epoch_nr: %d, batch: %d/%d, mse_loss: %.3f' %
                  (epoch, step, n_batches, (temp_loss/step)))
            loss.append(temp_loss/step)
            test_losses.append(test_loss)

model.save(save_path)

plt.plot(loss, label='Loss')
plt.plot(test_losses, label='Test Loss')
plt.legend(loc="upper right")
plt.show()
...