Keras, градиенты по отношению к потерям и весам исчезают, если пробники для фактического правого класса малы ( - PullRequest
2 голосов
/ 29 октября 2019

Мне нужен градиент комбинации «вход-цель», касающийся потери (categoryor_crossentropy) обученной модели. Для большинства примеров градиенты выглядят хорошо, но чем дальше обучается сеть, тем больше комбинаций вход-цель, для которых все градиенты равны нулю. Почему, так как это происходит, когда вероятности абсолютно не соответствуют цели?

Я определяю сеть следующим образом:

X_train, Y_train, X_test, Y_test = get_data(dataset) #load Mnist data

layers = [
            Conv2D(64, (3, 3), padding='valid', input_shape=(28, 28, 1)),  # 0
            Activation('relu'),  # 1
            BatchNormalization(),  # 2
            Conv2D(64, (3, 3)),  # 3
            Activation('relu'),  # 4
            BatchNormalization(),  # 5
            MaxPooling2D(pool_size=(2, 2)),  # 6
            Dropout(0.5),  # 7
            Flatten(),  # 8
            Dense(128),  # 9
            Activation('relu'),  # 10
            BatchNormalization(),  # 11
            Dropout(0.5),  # 12
            Dense(10),  # 13
            Activation('softmax'), #14
        ]

for layer in layers:
    model.add(layer)

model.compile(
    loss='categorical_crossentropy',#'mean_squared_error',#
    optimizer='adadelta',
    metrics=['accuracy']
    )

Далее я пишу функцию, которая вычисляет градиенты (http://sujitpal.blogspot.com/2017/10/debugging-keras-networks.html). Для отладки я строю прогнозы и градиенты последнего слоя

def get_weight_grad(model, X_train, Y_train):
    weights = model.trainable_weights  # weight tensors
    gradients = model.optimizer.get_gradients(model.total_loss, weights)
    input_tensors = [model.inputs[0],  # input data
                     model.sample_weights[0],  # how much to weight sample
                     model.targets[0],  # labels
                     K.learning_phase(),  # train or test mode
                     ]
    get_gradients = K.function(inputs=input_tensors, outputs=gradients)
    for i in range(len(X_train)):
        x = np.expand_dims(X_train[i], axis=0)
        y = np.expand_dims(Y_train[i], axis=0)
        print()
        print('y',y)

        inputs = [x, [1], y, 0]
        grads = get_gradients(inputs)
        print('grads_last', grads[-1])
        preds = model.predict_proba(x, verbose=0, batch_size=1)
        print('preds', preds)    

Теперь я тренирую эпоху по эпохе. Перед каждой эпохой я вызываю функцию get_weight_grads для вычисления градиентов для каждой возможной метки. .

for epoche in range(10):
    print('epoch', epoche )
    for i in range(10):
        y = np.zeros(10)
        y[i] = 1 # create all possible target values
        x = np.expand_dims(X_train[10], axis=0)
        y = np.expand_dims(y, axis = 0 )
        get_weight_grad(model, x,  y)

    model.fit_generator(
        datagen.flow(X_train, Y_train, batch_size=batch_size),
        steps_per_epoch=len(X_train) / batch_size,
        epochs=1,
        verbose=1,
        validation_data=(X_test, Y_test))

Градиенты до первой тренировочной эпохи выглядят, как и ожидалось, не равными нулю. Но после тренировочных эпох просмотра некоторые градиенты исчезают до нуля. Здесь я показываю отпечаток после эпохи 6.

y [[1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]
grads_last [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]  ########### The problem is e.g. HERE
preds [[2.3776792e-10 1.5075612e-07 1.1485033e-05 9.9945003e-01 1.4578478e-07
  5.3489784e-04 1.3318672e-08 1.8227190e-06 1.4657907e-06 3.3539639e-08]]

y [[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]]
grads_last [ 2.3776789e-10 -9.9999982e-01  1.1485031e-05  9.9944991e-01
  1.4578477e-07  5.3489779e-04  1.3318671e-08  1.8227188e-06
  1.4657904e-06  3.3539635e-08]
preds [[2.3776792e-10 1.5075612e-07 1.1485033e-05 9.9945003e-01 1.4578478e-07
  5.3489784e-04 1.3318672e-08 1.8227190e-06 1.4657907e-06 3.3539639e-08]]

y [[0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]]
grads_last [ 2.3776792e-10  1.5075612e-07 -9.9998862e-01  9.9945003e-01
  1.4578478e-07  5.3489784e-04  1.3318672e-08  1.8227190e-06
  1.4657907e-06  3.3539639e-08]
preds [[2.3776792e-10 1.5075612e-07 1.1485033e-05 9.9945003e-01 1.4578478e-07
  5.3489784e-04 1.3318672e-08 1.8227190e-06 1.4657907e-06 3.3539639e-08]]

y [[0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]]
grads_last [ 2.37767889e-10  1.50756108e-07  1.14850318e-05 -5.50014956e-04
  1.45784767e-07  5.34897787e-04  1.33186715e-08  1.82271890e-06
  1.46579055e-06  3.35396351e-08]
preds [[2.3776792e-10 1.5075612e-07 1.1485033e-05 9.9945003e-01 1.4578478e-07
  5.3489784e-04 1.3318672e-08 1.8227190e-06 1.4657907e-06 3.3539639e-08]]

y [[0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]]
grads_last [ 2.3776786e-10  1.5075609e-07  1.1485031e-05  9.9944985e-01
 -9.9999976e-01  5.3489773e-04  1.3318670e-08  1.8227187e-06
  1.4657904e-06  3.3539632e-08]
preds [[2.3776792e-10 1.5075612e-07 1.1485033e-05 9.9945003e-01 1.4578478e-07
  5.3489784e-04 1.3318672e-08 1.8227190e-06 1.4657907e-06 3.3539639e-08]]

y [[0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]]
grads_last [ 2.37767889e-10  1.50756108e-07  1.14850318e-05  9.99449968e-01
  1.45784767e-07 -9.99465108e-01  1.33186715e-08  1.82271890e-06
  1.46579055e-06  3.35396351e-08]
preds [[2.3776792e-10 1.5075612e-07 1.1485033e-05 9.9945003e-01 1.4578478e-07
  5.3489784e-04 1.3318672e-08 1.8227190e-06 1.4657907e-06 3.3539639e-08]]

y [[0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]]
grads_last [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
preds [[2.3776792e-10 1.5075612e-07 1.1485033e-05 9.9945003e-01 1.4578478e-07
  5.3489784e-04 1.3318672e-08 1.8227190e-06 1.4657907e-06 3.3539639e-08]]

y [[0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]]
grads_last [ 2.37767889e-10  1.50756108e-07  1.14850318e-05  9.99449968e-01
  1.45784767e-07  5.34897787e-04  1.33186715e-08 -9.99998212e-01
  1.46579055e-06  3.35396351e-08]
preds [[2.3776792e-10 1.5075612e-07 1.1485033e-05 9.9945003e-01 1.4578478e-07
  5.3489784e-04 1.3318672e-08 1.8227190e-06 1.4657907e-06 3.3539639e-08]]

y [[0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]]
grads_last [ 2.37767889e-10  1.50756108e-07  1.14850318e-05  9.99449968e-01
  1.45784767e-07  5.34897787e-04  1.33186715e-08  1.82271890e-06
 -9.99998569e-01  3.35396351e-08]
preds [[2.3776792e-10 1.5075612e-07 1.1485033e-05 9.9945003e-01 1.4578478e-07
  5.3489784e-04 1.3318672e-08 1.8227190e-06 1.4657907e-06 3.3539639e-08]]

y [[0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]]
grads_last [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
preds [[2.3776792e-10 1.5075612e-07 1.1485033e-05 9.9945003e-01 1.4578478e-07
  5.3489784e-04 1.3318672e-08 1.8227190e-06 1.4657907e-06 3.3539639e-08]]

например, для последней примерной выходной комбинации метка, поскольку прогнозы полностью отличаются от значений цели y, градиенты должны быть высокими, а не нулевыми. Что здесь не так? Единственное соединение, которое я могу установить, эточто для примеров с нулевым градиентом значение вероятности, для которого целевой горячий вектор имеетего, довольно маленький (

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