Нейронная сеть Keras для предсказания изменения угла частицы не предсказывает правильно - PullRequest
0 голосов
/ 06 августа 2020

Я собрал регрессионную модель keras, чтобы предсказать изменение угла отдельной частицы при предоставлении данных об этой частице. Чтобы получить данные, я создал программу, моделирующую броуновское движение между n частицами. Как и случайный angular шум, в зависимости от того, насколько близко друг к другу частицы они будут вызывать изменение угла друг друга.

Не так уж важно, как работает мой код, но по сути он выводит массив, содержащий координаты x, y всех частиц относительно отдельной частицы, значение тета всех частиц и расстояние между всеми частицами и отдельной частицей. Все эти параметры находятся на каждом временном шаге. Каждое «изображение», которое я использую для обучения сети, представляет собой все эти параметры в определенный момент времени. Итак, в целом входная переменная - это x, y, угол, расстояние, а выходная переменная - это изменение тета целевой частицы

Для моей нейронной сети я сначала нормализовал все свои данные, чтобы они находились между -1 и 1, а затем изменил его форму для подачи в NN:

import numpy as np
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout

## NORMALIZE IMAGES ##########################################################

# all images and labels imported, so obviously wont run without data. This is
# designed for running data with m iterations, n particles, 4 parameters
# (size of test data array is [m,n,4]). 

L = 5
# length of 'box' that houses particles
n = 10
# number of particles

train_images[:,:,0:2] = train_images[:,:,0:2]/L
# normalise [x,y] from -L:L to -1:1.
train_images[:,:,2:3] = train_images[:,:,2:3]/(2*np.pi)
# normalise theta value from -2pi:2pi to -1:1
train_images[:,:,3:4] = (train_images[:,:,3:4]/(L*np.sqrt(2))*2)-1
# normalise distance value from 0:sqrt(2)L to -1:1

test_images[:,:,0:2] = test_images[:,:,0:2]/L
test_images[:,:,2:3] = test_images[:,:,2:3]/(2*np.pi)
test_images[:,:,3:4] = (test_images[:,:,3:4]/(L*np.sqrt(2))*2)-1

## FLATTEN IMAGES ############################################################

train_images = train_images.reshape((-1, 4*(n-1))) 
# reshape so each input is a single dimension
# 4*(n-1) due to 4 parameters, adn n-1 particles (since one is redundant info)
test_images = test_images.reshape((-1, 4*(n-1)))

## BUILDING THE MODEL ########################################################

model = Sequential([
  Dense(64, activation='tanh', input_shape=(4*(n-1),)),
  Dense(16, activation='tanh'),
  Dropout(0.25),
  Dense(1, activation='tanh'),
])

## COMPILING THE MODEL #######################################################

model.compile(
  optimizer='adam',
  loss='mean_squared_error',
  #metrics=['mean_squared_error'],
)

## TRAINING THE MODEL ########################################################

history = model.fit(
  train_images, # training data
  train_labels, # training targets
  epochs=10,
  batch_size=32,
  #validation_data=(test_images, test_labels),
  shuffle=True,
  validation_split=0.2,
)

Я использовал различные типы активации для разных слоев (relu, sigmoid, tanh ...), но ни один, похоже, не дает мне правильные результаты. Истинные значения моих данных (изменение угла частицы) - это значения в диапазоне от 0,02 до -0,02, но получаемые мной значения намного меньше и, как правило, имеют преимущественно один знак (положительный / отрицательный).

В настоящее время я использую функцию потерь «средняя абсолютная ошибка», так как я хочу минимизировать разницу между реальным и прогнозируемым значением. При этом я замечаю, что после всего лишь одной эпохи потери уже невероятно малы:

Epoch 1/10
12495/12495 [==============================] - 13s 1ms/step - loss: 0.0010 - val_loss: 3.3794e-05
Epoch 2/10
12495/12495 [==============================] - 13s 1ms/step - loss: 3.4491e-05 - val_loss: 3.3769e-05
Epoch 3/10
12495/12495 [==============================] - 13s 1ms/step - loss: 3.4391e-05 - val_loss: 3.3883e-05
Epoch 4/10
12495/12495 [==============================] - 13s 1ms/step - loss: 3.4251e-05 - val_loss: 3.4755e-05
Epoch 5/10
12495/12495 [==============================] - 13s 1ms/step - loss: 3.4183e-05 - val_loss: 3.4273e-05
Epoch 6/10
12495/12495 [==============================] - 13s 1ms/step - loss: 3.4175e-05 - val_loss: 3.3770e-05
Epoch 7/10
12495/12495 [==============================] - 13s 1ms/step - loss: 3.4160e-05 - val_loss: 3.3646e-05
Epoch 8/10
12495/12495 [==============================] - 13s 1ms/step - loss: 3.4131e-05 - val_loss: 3.3629e-05
Epoch 9/10
12495/12495 [==============================] - 14s 1ms/step - loss: 3.4145e-05 - val_loss: 3.3581e-05
Epoch 10/10
12495/12495 [==============================] - 13s 1ms/step - loss: 3.4148e-05 - val_loss: 3.4647e-05

Вот пример результатов, которые я получаю от этого:

Prediction:  4.8542774e-05
Actual:  0.006994473448353978

Есть ли что-нибудь явно не так, что я сделал, чтобы получить эти результаты? Извините, если я не предоставил достаточно информации.

1 Ответ

0 голосов
/ 07 августа 2020

Это проблема регрессии, последний слой не активирован. Уменьшите количество единиц с 32 до 16 в 1-м слое, так как это предотвратит переобучение

...