Основной вопрос здесь теоретический.
Вы пытаетесь минимизировать d output_tensor / d x + d 2 output_tensor / д 2 х * +1022 *. Ваша сеть просто линейно объединяет входные данные x -s, однако, с активациями relu
и softplus
. Что ж, softplus добавляет немного изюминки к этому, но у этого также есть монотонно увеличивающаяся производная. Поэтому для того, чтобы производная была настолько малой, насколько это возможно, сеть будет просто увеличивать входной сигнал до максимально возможного с отрицательными весами, чтобы сделать производную как можно меньшей (то есть действительно большим отрицательным числом), в какой-то момент достигнув NaN . Я уменьшил первый слой до 5 нейронов и запустил модель для 2 эпох, и вес стал:
( 'dense_1',
[массив ([[1,0536456, -0,32706773, 0,0072904, 0,01986691, 0,9854533],
[-0,3242108, -0,56753945, 0,8098554, -0,7545874, 0,2716419]],
DTYPE = float32),
массив ([0,01207507, 0,09927677, -0,01768671, -0,12874101, 0,0210707],
dtype = float32)])
( 'dense_2',
[массив ([[- 0,4332278], [0,6621602], [-0,07802075], [-0,5798264], [-0,40561703]],
DTYPE = float32),
массив ([0.11167384], dtype = float32)])
Вы можете видеть, что второй слой держит отрицательный знак, где первый имеет положительный, и наоборот. (Уклоны не получают никакого градиента, потому что они не способствуют производной. Ну, не совсем верно из-за softplus
, но более или менее.)
Таким образом, вам нужно придумать функцию потерь, которая не расходится в сторону экстремальных значений параметров, поскольку она не будет обучаемой, она будет просто увеличивать значения весов до тех пор, пока они NaN .
Это была версия, которую я запускал:
import tensorflow as tf
from keras.models import *
from keras.layers import *
from keras import backend as K
def grad(f, x):
return Lambda(lambda u: K.gradients(u[0], u[1]), output_shape=[2])([f, x])
def ngrad(f, x, n):
if 0 == n:
return f
else:
return Lambda(lambda u: K.gradients(u[0], u[1]), output_shape=[2])([ngrad( f, x, n - 1 ), x])
def custom_loss(input_tensor,output_tensor):
def loss(y_true, y_pred):
_df1 = grad(output_tensor,input_tensor)
df1 = tf.Print( _df1, [ _df1 ], message = "df1" )
_df2 = grad(df1,input_tensor)
df2 = tf.Print( _df2, [ _df2 ], message = "df2" )
df = tf.add(df1,df2)
return df
return loss
input_tensor = Input(shape=(2,))
hidden_layer = Dense(5, activation='softplus')(input_tensor)
output_tensor = Dense(1, activation='softplus')(hidden_layer)
model = Model(input_tensor, output_tensor)
model.compile(loss=custom_loss(input_tensor,output_tensor), optimizer='sgd')
xy = np.mgrid[-3.0:3.0:0.1, -3.0:3.0:0.1].reshape( 2, -1 ).T
#print( xy )
model.fit(x=xy,y=xy, batch_size=10, epochs=2, verbose=2)
for layer in model.layers: print(layer.get_config()['name'], layer.get_weights())