Мне нужен градиент комбинации «вход-цель», касающийся потери (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, градиенты должны быть высокими, а не нулевыми. Что здесь не так? Единственное соединение, которое я могу установить, эточто для примеров с нулевым градиентом значение вероятности, для которого целевой горячий вектор имеетего, довольно маленький (