Зачем в Tensorflow добавлять функцию активации в модель только при подготовке к ее экспорту?

#python #tensorflow #keras #activation-function

Вопрос:

В учебном пособии Tensorflow ML Basics with Keras по созданию базовой классификации текста при подготовке обученной модели к экспорту в учебном пособии предлагается включить в модель слой TextVectorization, чтобы он мог «обрабатывать необработанные строки». Я понимаю, зачем это делать.

Но тогда фрагмент кода:

 export_model = tf.keras.Sequential([
  vectorize_layer,
  model,
  layers.Activation('sigmoid')
])
 

Почему при подготовке модели к экспорту учебное пособие также включает новый слой активации layers.Activation('sigmoid') ? Почему бы не включить этот слой в исходную модель?

Ответ №1:

Перед введением TextVectorization слоя вам приходилось вручную редактировать необработанные строки. Обычно это означало удаление знаков препинания, нижнего регистра, токенизации и так далее:

 #Raw String
"Furthermore, he asked himself why it happened to Billy?"

#Remove punctuation
"Furthermore he asked himself why it happened to Billy"

#Lower-case
"furthermore he asked himself why it happened to billy"

#Tokenize
['furthermore', 'he', 'asked', 'himself', 'why', 'it', 'happened', 'to', 'billy']
 

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

Что касается вашего второго вопроса: я также нахожу довольно странным, что функция sigmoid активации не использовалась. Я полагаю, что последний слой имеет «линейную функцию активации» из-за набора данных и его выборок. Образцы можно разделить на два класса, решая линейно разделяемую задачу.

Проблема с линейной функцией активации во время вывода заключается в том, что она может выводить отрицательные значения:

 # With linear activation function

examples = [
  "The movie was great!",
  "The movie was okay.",
  "The movie was terrible..."
]

export_model.predict(examples)

'''
array([[ 0.4543204 ],
       [-0.26730654],
       [-0.61234593]], dtype=float32)
'''
 

Например, значение -0.26730654 может указывать на то, что отзыв «Фильм был в порядке» отрицательный, но это не обязательно так. Что на самом деле нужно предсказать, так это вероятность того, что конкретный образец принадлежит определенному классу. Поэтому в выводе используется сигмоидальная функция для сжатия выходных значений между 0 и 1. Затем вывод можно интерпретировать как вероятность того, что образец x принадлежит классу n :

 # With sigmoid activation function

examples = [
  "The movie was great!",
  "The movie was okay.",
  "The movie was terrible..."
]

export_model.predict(examples)

'''
array([[0.6116659 ],
       [0.43356845],
       [0.35152423]], dtype=float32)
'''
 

Ответ №2:

Иногда вы хотите узнать ответ модели перед сигмоидом, поскольку он может содержать полезную информацию, например, о форме распределения и ее эволюции. В таком сценарии удобно иметь окончательное масштабирование как отдельный объект. В противном случае пришлось бы удалять / добавлять сигмовидный слой — больше строк кода, больше возможных ошибок. Поэтому может быть хорошей практикой применять sigmoid в самом конце — непосредственно перед сохранением / экспортом. Или просто соглашение.