TensorFlow: пользовательская функция потерь для решения уравнения - В [0] нет матрицы. Вместо этого он имеет форму [8000] [Op: MatMul] - PullRequest
0 голосов
/ 09 марта 2020

Я новичок в TensorFlow и машинном обучении и хочу реализовать пользовательскую функцию потерь для решения уравнения. Мои данные - синусоида, линейно растущая по амплитуде, т.е. f (t) = t.sin (2.pi.ft) и выглядит следующим образом:

enter image description here

Я хочу, чтобы функция потерь была (Ya - Yp) ^ 2 + f ^ 2 где Ya - фактический выходной сигнал, а Yp - прогнозируемый выходной сигнал, так что сеть знает уравнение f (t) , которое он постарается свести к минимуму. Тем не менее, я сталкиваюсь с проблемой. Когда я запускаю код, я получаю ошибку В [0] не матрица. Вместо этого он имеет форму [8000] [Op: MatMul] . Я видел этот тип функции потерь, реализованный в статье (https://arxiv.org/pdf/1808.04327.pdf). Будет ли этот код работать как задумано? Если нет, как мне реализовать обучение на основе уравнений? . Данные, которые я использую, можно найти по этой ссылке https://drive.google.com/open?id=1v_jkrTJfClxaFYAa5U5qmxhny0TdlCFw Я написал код после пользовательского учебного руководства на веб-сайте TensorFlow. Любая помощь приветствуется. Спасибо.

from __future__ import absolute_import, division, print_function, unicode_literals

import os
import math
import numpy as np
import pandas as pd
import tensorflow as tf
import matplotlib as mpl
from tensorflow import keras
import matplotlib.pyplot as plt
import tensorflow.keras.backend as kb

column_names = ['Time', 'F(t)']     
dataset = pd.read_csv('sine_wave.csv', names=column_names, skipinitialspace=True)
print('\nData Set:\n', dataset.head())

train_sample = int(len(dataset)*0.8)
x_train = dataset.iloc[:train_sample, 0].values
y_train = dataset.iloc[:train_sample, 1].values
x_test = dataset.iloc[:, 0].values

def build_model():
    model = tf.keras.Sequential([
    tf.keras.layers.Dense(1, activation='relu', input_shape=(1,)),
    tf.keras.layers.Dense(50, activation='relu'),
    tf.keras.layers.Dense(50, activation='relu'),
    tf.keras.layers.Dense(50, activation='relu'),
    tf.keras.layers.Dense(1)
    ])

    return model

model = build_model()
model.summary()

def custom_loss(model, x, y, training):
  y_pred = model(x, training=training)
  y_actual = y
  f = x*kb.sin(628.318*x)
  loss = tf.reduce_mean(kb.square(y_actual-y_pred)) + tf.reduce_mean(kb.square(f))
  return loss

def grad(model, inputs, targets):
  with tf.GradientTape() as tape:
    loss_value = custom_loss(model, inputs, targets, training=True)
  return loss_value, tape.gradient(loss_value, model.trainable_variables)

optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)

loss_value, grads = grad(model, x_train, y_train)
print("Step: {}, Initial Loss: {}".format(optimizer.iterations.numpy(), loss_value.numpy()))
optimizer.apply_gradients(zip(grads, model.trainable_variables))
print("Step: {},         Loss: {}".format(optimizer.iterations.numpy(), custom_loss(model, x_train, y_train, training=True).numpy()))

# Keep results for plotting
train_loss_results = []
train_accuracy_results = []

num_epochs = 100

for epoch in range(num_epochs+1):
  epoch_loss_avg = tf.keras.metrics.Mean()
  epoch_accuracy = tf.keras.metrics.Accuracy()

  # Training loop - using batches of 32

  # Optimize the model
  loss_value, grads = grad(model, x_train, y_train)
  optimizer.apply_gradients(zip(grads, model.trainable_variables))

  # Track progress
  epoch_loss_avg(loss_value)  # Add current batch loss
  # Compare predicted label to actual label
  # training=True is needed only if there are layers with different
  # behavior during training versus inference (e.g. Dropout).
  epoch_accuracy(y_train, model(x_train, training=True))

  # End epoch
  train_loss_results.append(epoch_loss_avg.result())
  train_accuracy_results.append(epoch_accuracy.result())

  if epoch % 50 == 0:
    print("Epoch {:03d}: Loss: {:.3f}, Accuracy: {:.3%}".format(epoch, epoch_loss_avg.result(), epoch_accuracy.result()))

fig, axes = plt.subplots(2, sharex=True, figsize=(12, 8))
fig.suptitle('Training Metrics')

axes[0].set_ylabel("Loss (MSE)", fontsize=14)
axes[0].plot(train_loss_results)

axes[1].set_ylabel("Accuracy", fontsize=14)
axes[1].set_xlabel("Epochs", fontsize=14)
axes[1].plot(train_accuracy_results)
plt.show()

y_predictions = model.predict(x_test)
np.savetxt('predictions.csv', y_predictions, delimiter=',')

marker = ['b-', 'r-']
plt.plot(dataset.iloc[:, 1].values, marker[0], markersize=4, linewidth=1, label='Actual')
plt.plot(y_predictions, marker[1], markersize=4, linewidth=1, label='Predicted')
plt.xlim([0, 10000])
plt.ylim([-1, 1])
plt.xlabel('Time (t)')
plt.ylabel(r'$F(t) = t sin (2 \pi f t)$')
plt.title('Time Series Prediction')
plt.legend()
plt.show()
...