मान लें कि मेरे पास एक द्विचर कार्य है, उदाहरण के लिए: z = x^2 + y^2। मैंने सीखा कि केरस पर मैं लैम्ब्डा लेयर्स का उपयोग करके nth-order डेरिवेटिव्स की गणना कर सकता हूं:

def bivariate_function(x, y):

    x2 = Lambda(lambda u: K.pow(u,2))(x)
    y3 = Lambda(lambda u: K.pow(u,2))(y)

    return Add()([x2,y3])

def derivative(y,x):
    return Lambda(lambda u: K.gradients(u[0],u[1]))([y,x])

f = bivariate_function(x,y)
df_dx = grad(f,x)      # 1st derivative wrt to x
df_dy = grad(f,y)      # 1st derivative wrt to y
df_dx2 = grad(df_dx,x) # 2nd derivative wrt to x
df_dy2 = grad(df_dy,y) # 2nd derivative wrt to y

हालांकि, मैं इस दृष्टिकोण को एनएन आउटपुट wrt के डेरिवेटिव के लिए नुकसान फ़ंक्शन में इनपुट पर कैसे लागू करूं? मैं (?) बस दो इनपुट को एक घनी परत में फीड नहीं कर सकता (जैसा कि ऊपर बनाया गया है)।

उदाहरण के लिए, नुकसान के रूप में उपयोग करने की कोशिश कर रहे पहले व्युत्पन्न wrt को पहले चर और दूसरे व्युत्पन्न wrt को दूसरे चर (यानी d/dx + d²/dy²) के योग के रूप में उपयोग करने का प्रयास करते हुए, Input(shape=(2,)) का उपयोग करके, मैं यहां पहुंचने में कामयाब रहा :

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 custom_loss(input_tensor,output_tensor):
    def loss(y_true, y_pred):

        df1 = grad(output_tensor,input_tensor)
        df2 = grad(df1,input_tensor)
        df = tf.add(df1[0,0],df2[0,1])      

        return df
    return loss

input_tensor = Input(shape=(2,))
hidden_layer = Dense(100, activation='relu')(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
model.fit(x=xy,y=xy, batch_size=10, epochs=100, verbose=2)

लेकिन ऐसा लगता है कि मैं इसे सही तरीके से नहीं कर रहा हूं। इससे भी बदतर, पहले युग के बाद मुझे सिर्फ nan मिल रहा है।

1
Lucas Farias 26 अप्रैल 2018, 12:56

1 उत्तर

सबसे बढ़िया उत्तर

यहां मुख्य मुद्दा सैद्धांतिक है।

आप doutput_tensor/dx + d2< को छोटा करने का प्रयास कर रहे हैं मजबूत>output_tensor/d2x. हालांकि, आपका नेटवर्क relu और softplus सक्रियणों के साथ इनपुट x-s को केवल रैखिक रूप से संयोजित करता है। ठीक है, सॉफ्टप्लस इसमें थोड़ा सा ट्विस्ट जोड़ता है, लेकिन इसमें एक नीरस रूप से बढ़ता व्युत्पन्न भी है। इसलिए व्युत्पन्न जितना संभव हो उतना छोटा होने के लिए, नेटवर्क जितना संभव हो सके नकारात्मक भार के साथ इनपुट को स्केल करेगा, व्युत्पन्न को जितना संभव हो उतना छोटा बनाने के लिए (यानी, वास्तव में एक बड़ी नकारात्मक संख्या), किसी बिंदु पर पहुंचने पर NaN. मैंने पहली परत को 5 न्यूरॉन्स तक कम कर दिया है और मॉडल को 2 युगों तक चलाया है, और वजन बन गया है:

('घना_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)])

('घना_2', [सरणी ([[-०.४३३२२७८], [०.६६२१६०२], [-०.०७८०२०७५], [-०.५७९८२६४ ], [-०.४०५६१७०३]],
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())
1
Peter Szoldan 26 अप्रैल 2018, 23:21