Почему пользовательская функция активации приводит к нулевым потерям и низкой точности сети?
Я пытался создать пользовательскую функцию активации с помощью tflearn, внеся следующие изменения:
добавить мою пользовательскую функцию активации в activation.py
def my_activation(x):
return tf.where(x >= 0.0, tf.div( x**2 , x + tf.constant(0.6)) , 0.01*x)
и добавить его в __init__.py
from .activations import linear, tanh, sigmoid, softmax, softplus, softsign,\
relu, relu6, leaky_relu, prelu, elu, crelu, selu, my_activation
Так как тензор потока может выполнять вычисление градиента автоматически, мне не нужно реализовывать функцию градиента. Как указано в статье Стиль программирования глубокого обучения,
Раньше, когда кто-то определял новую модель, ему приходилось выполнять производные вычисления вручную. Хотя математика достаточно проста, для сложных моделей она может быть трудоемкой и утомительной. Все современные библиотеки глубокого обучения значительно облегчают работу практикующего специалиста, автоматически решая проблему расчета градиента.
Я обучил модель на наборе данных cifar10, используя этот код: https://github.com/tflearn/tflearn/blob/master/examples/images/convnet_cifar10.py но изменил все активации relu на my_activation.
К сожалению, эта простая модификация приводит к тому, что сеть ничего не изучает:
Training Step: 46 | total loss: 0.00002 | time: 1.434s
| Adam | epoch: 001 | loss: 0.00002 - acc: 0.0885 -- iter: 04416/50000
Training Step: 47 | total loss: 0.00002 | time: 1.448s
| Adam | epoch: 001 | loss: 0.00002 - acc: 0.0945 -- iter: 04512/50000
Training Step: 48 | total loss: 0.00001 | time: 1.462s
| Adam | epoch: 001 | loss: 0.00001 - acc: 0.0927 -- iter: 04608/50000
Training Step: 49 | total loss: 0.00001 | time: 1.476s
| Adam | epoch: 001 | loss: 0.00001 - acc: 0.0896 -- iter: 04704/50000
Training Step: 50 | total loss: 0.00001 | time: 1.491s
| Adam | epoch: 001 | loss: 0.00001 - acc: 0.0919 -- iter: 04800/50000
Training Step: 51 | total loss: 0.00001 | time: 1.504s
| Adam | epoch: 001 | loss: 0.00001 - acc: 0.0890 -- iter: 04896/50000
Training Step: 52 | total loss: 0.00001 | time: 1.518s
| Adam | epoch: 001 | loss: 0.00001 - acc: 0.0944 -- iter: 04992/50000
Training Step: 53 | total loss: 0.00001 | time: 1.539s
| Adam | epoch: 001 | loss: 0.00001 - acc: 0.0989 -- iter: 05088/50000
Training Step: 54 | total loss: 0.00001 | time: 1.553s
| Adam | epoch: 001 | loss: 0.00001 - acc: 0.0951 -- iter: 05184/50000
Training Step: 55 | total loss: 0.00000 | time: 1.567s
| Adam | epoch: 001 | loss: 0.00000 - acc: 0.0964 -- iter: 05280/50000
Training Step: 56 | total loss: 0.00000 | time: 1.580s
| Adam | epoch: 001 | loss: 0.00000 - acc: 0.0931 -- iter: 05376/50000
Training Step: 57 | total loss: 0.00000 | time: 1.594s
| Adam | epoch: 001 | loss: 0.00000 - acc: 0.0903 -- iter: 05472/50000
Training Step: 58 | total loss: 0.00000 | time: 1.613s
| Adam | epoch: 001 | loss: 0.00000 - acc: 0.0851 -- iter: 05568/50000
Training Step: 59 | total loss: 0.00000 | time: 1.641s
| Adam | epoch: 001 | loss: 0.00000 - acc: 0.0835 -- iter: 05664/50000
Training Step: 60 | total loss: 0.00000 | time: 1.674s
| Adam | epoch: 001 | loss: 0.00000 - acc: 0.0834 -- iter: 05760/50000
Поскольку я только начинающий, я не знаю причину, по которой сеть стала как нулевой потерей, так и низкой точностью (выход NaN? Дедвейт?). Кто-нибудь может сказать мне, как это исправить? Спасибо!
Обратите внимание, что я не спрашиваю, как создать пользовательскую функцию активации. Вопросы о том, как сделать пользовательскую функцию:
- Как сделать пользовательскую функцию активации только с Python в Tensorflow?
- Как сделать кусочную функцию активации с Python в TensorFlow?
- Как создать пользовательскую функцию активации с помощью Keras?
- Как использовать пользовательские функции активации в TensorFlow для нейронных сетей?
- Можно ли добавить новые функции активации в TensorFlow / Theano / Torch? Как?
1 ответ
Почему пользовательская функция активации приводит к нулевым потерям и низкой точности сети?
Потому что эта сеть не распространяется через вашу новую активацию. То, что вы сделали, - это только начало создания пользовательской функции активации. Смотрите этот вопрос: "... Как объяснено в источниках, упомянутых выше, есть хак для определения градиентов функции с помощью tf.RegisterGradient
а также tf.Graph.gradient_override_map
... ".
Я на самом деле не уверен, что ваша активация намного лучше, чем tflearn.activations.leaky_relu
, но если вы действительно хотите предоставить пользовательскую активацию, вам придется кодировать градиент и зарегистрировать его, как описано выше.