Рекомендации по подгонке нелинейной вектор-функции в тензорном потоке - PullRequest
0 голосов
/ 20 сентября 2018

Я новичок в tenorflow, поэтому извините, если следующий код не очень умный.Я хотел бы попросить вас дать рекомендации при настройке / обучении нейронной сети.Ниже приведен минимальный рабочий пример: m-мерные векторы x с действительными значениями являются входными данными (особенности, если я правильно понимаю терминологию), тогда как выходные данные (я думаю, что метки) являются n-мерными векторами f(x).

В следующем примере (в python 3.6.5) давайте используем 2d векторы x (m = 2) и 2d векторы f (n = 2), при этом я приближаю квадраткорневая функция (первый компонент f) и синусовая функция (второй компонент).

Что бы вы порекомендовали мне сделать, чтобы улучшить модель?Есть ли какие-то эмпирические правила?

Позже мне нужно разобраться с высокоразмерным вводом x и высокоразмерным выводом f (x), но сначала я хочу узнать, как добиться большего успеха в небольших примерах, таких какследующий.

Я играл с разным количеством нейронов, количеством слоев, функциями активации, оптимизаторами, размерами шагов и количеством эпох.Любые рекомендации?Я уже стандартизировал / нормализовал входы x и выходы f, т. Е. Вычислил их средние значения и стандартные отклонения и соответственно пересчитал x и f.


Пример на python 3.6.5:

Мне понадобятся эти модули

#%% Setup

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
import tensorflow as tf

Следующие строки генерируют некоторые входные данные x (x1 от 0 до 8 и x2 от 0 до 15, каждое направление дискретизируется в 30 точках) ивычислить точные значения функций f (x) и отобразить функции f1 (x) и f2 (x)

#%% Generate data

lx = (8,15)
nx = 30

x = np.array(np.meshgrid(*[l*np.linspace(0,1,nx) for l in lx])).reshape(len(lx),-1).T
f = np.array([[10*np.sqrt(sum(xx)), 10*np.sin(np.sum(xx))+20] for xx in list(x)])

dx = np.shape(x)[1]
df = np.shape(f)[1]

fig = plt.figure(figsize=(7,2))
fig.add_subplot(1,2,1, projection='3d').scatter(x[:,0],x[:,1],f[:,0])
fig.add_subplot(1,2,2, projection='3d').scatter(x[:,0],x[:,1],f[:,1])

plots of f1 and f2

Следующие строки стандартизируют / обнуляют входные и выходные данные и снова наносят на график данные (проверьте, что x и f были перемасштабированы)

#%% Standardize data

def sdata(x):
    for i in range(np.shape(x)[1]):
        x[:,i] = (x[:,i]-np.mean(x[:,i]))/np.std(x[:,i])
    return x

x = sdata(x)
f = sdata(f)

fig = plt.figure(figsize=(7,2))
fig.add_subplot(1,2,1, projection='3d').scatter(x[:,0],x[:,1],f[:,0])
fig.add_subplot(1,2,2, projection='3d').scatter(x[:,0],x[:,1],f[:,1])

x and f rescaled

Следующие строки являются настройками для нейронной сети.Вы можете изменить или добавить число в число нейро nn.Длина кортежа nn автоматически определяет количество слоев.Функция активации: af, оптимизатор opt и количество эпох nep.

#%% Neural network setup

# Number of neurons in layers, activation function, optimizer and number of epochs
nn = (16,16,16,df)
af = tf.tanh
opt = tf.train.AdamOptimizer(0.01)
nep = 3000

# Placeholders for input x, output f
xp = tf.placeholder(dtype=tf.float32, shape=[None,dx])
fp = tf.placeholder(dtype=tf.float32, shape=[None,df])
# Build sequential model, last call is output
model = xp
for i in range(len(nn)-1):
    model = tf.layers.dense(model,nn[i],activation=af)
model = tf.layers.dense(model,nn[-1],activation=None)
# Loss function (MSE), training step and initializer
loss = tf.reduce_mean(tf.square(model-fp))
trainstep = opt.minimize(loss)
init = tf.global_variables_initializer()

Следующие строки запускают сеанс тензорного потока, отображают начальные значения предсказания fpre(x) (из f(x)), вычислить значения функции потерь (среднеквадратичная ошибка, MSE), провести обучение, построить график функции потерь по эпохам, построить окончательное предсказание f (x) и построить абсолютную разницу между выходными даннымиf (x) и fpred (x)

#%% Session, train, see results

# Start session
s = tf.Session()
s.run(init)
# Plot predicted values before training at positions x
fpre = s.run(model,{xp:x})
fig = plt.figure(figsize=(7,2))
p1 = fig.add_subplot(1,2,1, projection='3d')
p1.scatter(x[:,0],x[:,1],f[:,0])
p1.scatter(x[:,0],x[:,1],fpre[:,0])
p2 = fig.add_subplot(1,2,2, projection='3d')
p2.scatter(x[:,0],x[:,1],f[:,1])
p2.scatter(x[:,0],x[:,1],fpre[:,1])
# Prepare container for loss data and print initial loss
lossd = [None]*(nep+1)
lossd[0] = s.run(loss,{xp:x,fp:f})
print(lossd[0])
# Train
for i in range(1,nep+1):
    s.run(trainstep,{xp:x,fp:f})
    lossd[i] = s.run(loss,{xp:x,fp:f})
# See loss development
print('Last loss:\n'+str(lossd[-1]))
plt.figure()
plt.plot(list(range(nep+1)),lossd)
# Plot predicted values after training at positions x
fpre = s.run(model,{xp:x})
print('Computed MSE:\n'+str(np.mean((fpre-f)**2)))
fig = plt.figure(figsize=(7,2))
p1 = fig.add_subplot(1,2,1, projection='3d')
p1.scatter(x[:,0],x[:,1],f[:,0])
p1.scatter(x[:,0],x[:,1],fpre[:,0])
p2 = fig.add_subplot(1,2,2, projection='3d')
p2.scatter(x[:,0],x[:,1],f[:,1])
p2.scatter(x[:,0],x[:,1],fpre[:,1])
# Plot difference
fig = plt.figure(figsize=(7,2))
p1 = fig.add_subplot(1,2,1, projection='3d')
p1.scatter(x[:,0],x[:,1],np.abs(f[:,0]-fpre[:,0]))
p2 = fig.add_subplot(1,2,2, projection='3d')
p2.scatter(x[:,0],x[:,1],np.abs(f[:,1]-fpre[:,1]))
# Close sessions
s.close()

Это было первоначальное предсказание

enter image description here

Это функция потерь заэпохи

enter image description here

Это окончательные прогнозы и абсолютная разница

enter image description here

Есть какие-нибудь мысли о том, как улучшить это или сделать код более эффективным?Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...