Рубрики
Без рубрики

Субтитры к изображениям с использованием Юпитера

Субтитры к изображениям – это процесс, в котором текстовое описание создается на основе изображения. Чтобы лучше понять субтитры к изображениям, нам нужно сначала отличить их от изображений…

Автор оригинала: PACKT.

Субтитры к изображениям – это процесс, в котором текстовое описание создается на основе изображения. Чтобы лучше понять субтитры к изображениям, нам нужно сначала отличить их от классификации изображений.

Разница между классификацией изображений и субтитрами к изображениям

Классификация изображений-это относительно простой процесс, который говорит нам только о том, что находится в изображении. Например, если есть мальчик на велосипеде, классификация изображений не даст нам описания; она просто предоставит результат в виде мальчика или велосипеда. Классификация изображений может сказать нам, есть ли на изображении женщина или собака, или действие, например, катание на сноуборде. Это нежелательный результат, так как нет описания того, что именно происходит на изображении.

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

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

С другой стороны, субтитры к изображениям обеспечат результат с описанием. В предыдущем примере результатом подписи к изображению будет мальчик, едущий на велосипеде, или мужчина, катающийся на сноуборде. Это может быть полезно для создания контента для книги или, возможно, для помощи слабослышащим или слабовидящим.

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

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

Однако это значительно сложнее, поскольку обычные нейронные сети являются мощными, но они не очень совместимы с последовательными данными. Последовательные данные-это то, где у нас есть данные, которые поступают в порядке, и этот порядок действительно имеет значение. В аудио или видео слова идут в последовательном порядке; смешивание слов может изменить смысл предложения или просто сделать его полной тарабарщиной.

Рекуррентные нейронные сети с длительной кратковременной памятью

Какими бы мощными ни были сверточные нейронные сети (CNN), они не так хорошо обрабатывают последовательные данные; однако они отлично подходят для не последовательных задач, таких как классификация изображений.

Как работает CNN, показано на следующей диаграмме:

Как работает CNN, показано на следующей диаграмме:

Рекуррентные нейронные сети (RNN), которые действительно являются современными, могут обрабатывать последовательные задачи. RNN состоит из CNN, где данные принимаются в определенной последовательности.

Как работают RNNs, показано на следующей диаграмме:

Как работают RNNs, показано на следующей диаграмме:

Данные, поступающие в последовательности (xi), проходят через нейронную сеть, и мы получаем результат (yi). Затем выходные данные передаются на другую итерацию и образуют цикл. Это помогает нам запоминать данные, полученные ранее, и полезно для последовательных задач обработки данных, таких как распознавание звука и речи, перевод языка, идентификация видео и генерация текста.

Еще одна концепция, которая существует уже некоторое время и очень полезна,-это долгосрочная краткосрочная память (LSTM) с RNNs. Это способ обработки долговременной памяти и избегания простой передачи данных от одной итерации к другой. Он надежно обрабатывает данные с итераций и позволяет нам эффективно обучать RNN.

Модель субтитров Google Brain im2txt

Google Brain im2txt был использован Google в статье 2015 MS COCO Image Captioning Challenge и станет основой кода субтитров изображений, который мы будем реализовывать в этой статье. Страницу Google GitHubTensorFlow можно найти по адресу https://github.com/tensorflow/models/tree/master/research/im2txt.

В каталоге исследований мы найдем файл sim 2 txt, который был использован Google в статье 2015 MS COCO Image Captioning Challenge, которая доступна бесплатно по адресу https://arxiv.org/abs/1609.06647. Он подробно описывает RNNs, LSTM и фундаментальные алгоритмы.

Мы можем проверить, как CNN используются для классификации изображений, а также узнать, как использовать RNN LSTM для фактического создания последовательных выходных данных субтитров.

Мы можем загрузить код по ссылке GitHub; однако он не был настроен для легкого запуска, так как он не включает предварительно подготовленную модель, поэтому мы можем столкнуться с некоторыми проблемами. Мы предоставили вам предварительно подготовленную модель, чтобы избежать обучения классификатора изображений с нуля, поскольку это трудоемкий процесс.

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

Запуск кода субтитров на Юпитере

Теперь давайте запустим нашу собственную версию кода в записной книжке Jupyter. Мы можем запустить собственный ноутбук Jupyter и загрузить файл Section_1-Tensorflow_Image_Captioning.ipynb из репозитория GitHub (https://github.com/PacktPublishing/Computer-Vision-Projects-with-OpenCV-and-Python-3/blob/master/Chapter01/Section_1-Tensorflow_Image_Captioning.ipynb).

Как только мы загрузим файл в блокнот Jupyter, он будет выглядеть примерно так:

Как только мы загрузим файл в блокнот Jupyter, он будет выглядеть примерно так:

В первой части мы собираемся загрузить некоторые основные библиотеки, включая math, os и tensorflow. Мы также будем использовать нашу удобную служебную функцию %pylab inline для легкого чтения и отображения изображений в ноутбуке.

Выберите первый блок кода:

# load essential libraries
import math
importos

importtensorflow as tf

%pylab inline

Когда мы нажмем Ctrl + Enter, чтобы выполнить код в ячейке, мы получим следующий вывод:

Когда мы нажмем Ctrl + Enter, чтобы выполнить код в ячейке, мы получим следующий вывод:

Теперь нам нужно загрузить базовый код TensorFlow/Google Brain, который мы можем получить из https://github.com/PacktPublishing/Computer-Vision-Projects-with-OpenCV-and-Python-3.

Существует несколько полезных функций, но в нашем примере мы будем использовать и выполнять только некоторые из них:

# load Tensorflow/Google Brain base code
# https://github.com/tensorflow/models/tree/master/research/im2txt

from im2txt import configuration
from im2txt import inference_wrapper
from im2txt.inference_utils import caption_generator
from im2txt.inference_utils import vocabulary

Нам нужно сообщить нашей функции, где найти обученную модель и словарь:

# tell our function where to find the trained model and vocabulary
checkpoint_path = './model'
vocab_file = './model/word_counts.txt'

Код для обученной модели и словаря был добавлен в репозиторий GitHub, и вы можете получить доступ к нему по этой ссылке: https://github.com/PacktPublishing/Computer-Vision-Projects-with-OpenCV-and-Python-3

Папка содержит контрольную точку, word_counts.txt, и предварительно обученная модель. Нам нужно убедиться, что мы используем эти файлы и избегаем использования других устаревших файлов, которые могут быть несовместимы с последней версией TensorFlow. В word_counts.txt файл содержит список словаря с количеством отсчетов из нашей обученной модели, который понадобится вашему генератору подписей к изображениям.

Как только эти шаги будут завершены, мы сможем посмотреть на нашу основную функцию, которая будет генерировать подписи для нас. Функция может принимать входные данные в виде строки входных файлов (разделенных запятыми) или может быть только одним файлом, который мы хотим обработать. Для многословия задано значение tf.logging.ФАТАЛЬНЫЙ из различных доступных уровней ведения журнала, так как он сообщит нам, действительно ли что-то пошло не так:

Как только эти шаги будут завершены, мы сможем посмотреть на нашу основную функцию, которая будет генерировать подписи для нас. Функция может принимать входные данные в виде строки входных файлов (разделенных запятыми) или может быть только одним файлом, который мы хотим обработать. Для многословия задано значение tf.logging.ФАТАЛЬНЫЙ из различных доступных уровней ведения журнала, так как он сообщит нам, действительно ли что-то пошло не так:

В начальной части основного кода мы выполняем следующие шаги:

  1. Установите уровень детализации на tf.logging.РОКОВОЙ.
  2. Загрузите нашу предварительно подготовленную модель.
  3. Загрузите оболочку вывода из нашего служебного файла, предоставленного Google.
  4. Загрузите нашу предварительно обученную модель с пути контрольной точки, который мы установили в предыдущей ячейке.
  5. Запустите функцию finalize:
# this is the function we'll call to produce our captions 
# given input file name(s) -- separate file names by a,
# if more than one

defgen_caption(input_files):
    # only print serious log messages
tf.logging.set_verbosity(tf.logging.FATAL)
    # load our pretrained model
    g = tf.Graph()
withg.as_default():
model = inference_wrapper.InferenceWrapper()
restore_fn = model.build_graph_from_config(configuration.ModelConfig(),
checkpoint_path)
g.finalize()

  1. Снова загрузите файл словаря из ячейки, которую мы ранее запустили:
    # Create the vocabulary.
vocab = vocabulary.Vocabulary(vocab_file)

  1. Предварительная обработка имен файлов:
filenames = []
forfile_pattern in input_files.split(","):
  1. Выполните глобальное действие:
filenames.extend(tf.gfile.Glob(file_pattern))
  1. Создайте список имен файлов, чтобы вы могли знать, в каком файле работает генератор подписей к изображениям:
tf.logging.info("Running caption generation on %d files matching %s",
len(filenames), input_files)
  1. Создайте сеанс. Нам нужно использовать функцию восстановления, так как мы используем “ предварительно обученную модель:
withtf.Session(graph=g) as sess:
        # Load the model from checkpoint.
restore_fn(sess)

Код для этих шагов включен здесь:

#this is the function we'll call to produce our captions 
#given input file name(s) -- separate file names by a,
#if more than one

defgen_caption(input_files):
    # only print serious log messages
tf.logging.set_verbosity(tf.logging.FATAL)
    # load our pretrained model
    g = tf.Graph()
withg.as_default():
model = inference_wrapper.InferenceWrapper()
restore_fn = model.build_graph_from_config(configuration.ModelConfig(),
checkpoint_path)
g.finalize()

    # Create the vocabulary.
vocab = vocabulary.Vocabulary(vocab_file)

filenames = []
forfile_pattern in input_files.split(","):
filenames.extend(tf.gfile.Glob(file_pattern))
tf.logging.info("Running caption generation on %d files matching %s",
len(filenames), input_files)

withtf.Session(graph=g) as sess:
        # Load the model from checkpoint.
restore_fn(sess)

Теперь мы переходим ко второй половине основного кода. После восстановления сеанса мы выполняем следующие действия:

  1. Загрузите caption_generator из нашей модели и словаря, хранящегося в объекте, называемом генератором:
generator = caption_generator.CaptionGenerator(model, vocab)
  1. Составьте список подписей:
captionlist = []
  1. Повторите файлы и загрузите их в генератор beam_search для анализа изображения:
for filename in filenames:
withtf.gfile.GFile(filename, "rb") as f:
image = f.read()
captions = generator.beam_search(sess, image)
  1. Распечатайте подписи:
print("Captions for image %s:" % os.path.basename(filename))
  1. Повторите, чтобы создать несколько подписей с итерацией, уже заданной для модели:
for i, caption in enumerate(captions):
                # Ignore begin and end words.
sentence = [vocab.id_to_word(w) for w in caption.sentence[1:-1]]
sentence = " ".join(sentence)
print(" %d) %s (p=%f)" % (i, sentence, math.exp(caption.logprob)))
captionlist.append(sentence)
  1. Вернуть список подписей:
returncaptionlist

Запустите код для создания функции. Полный код см. в следующем блоке кода:

    # Prepare the caption generator. Here we are implicitly using the default
    # beam search parameters. See caption_generator.py for a description of the
    # available beam search parameters.
generator = caption_generator.CaptionGenerator(model, vocab)

captionlist = []

for filename in filenames:
withtf.gfile.GFile(filename, "rb") as f:
image = f.read()
captions = generator.beam_search(sess, image)
print("Captions for image %s:" % os.path.basename(filename))
for i, caption in enumerate(captions):
                # Ignore begin and end words.
sentence = [vocab.id_to_word(w) for w in caption.sentence[1:-1]]
sentence = " ".join(sentence)
print(" %d) %s (p=%f)" % (i, sentence, math.exp(caption.logprob)))
captionlist.append(sentence)
returncaptionlist

В следующем блоке кода мы выполним код на образцах стоковых фотографий из тестовой папки. Код создаст рисунок, покажет его, а затем запустит генератор подписей. Затем мы можем отобразить выходные данные с помощью инструкции print.

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

testfile = 'test_images/dog.jpeg'

figure()
imshow(imread(testfile))

capts = gen_caption(testfile)

Когда мы запустим наш первый тестовый образ, dog.jpeg, мы получаем следующий результат:

Когда мы запустим наш первый тестовый образ, dog.jpeg, мы получаем следующий результат:

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

Анализ заголовков результатов

Давайте возьмем несколько примеров, чтобы проверить нашу модель. Когда мы выполняем football.jpeg, мы получаем следующий результат:

Давайте возьмем несколько примеров, чтобы проверить нашу модель. Когда мы выполняем football.jpeg, мы получаем следующий результат:

Здесь у нас явно идет американский футбол на изображении, и пара мужчин, играющих в футбол, – это очень хороший результат. Однако первый результат, пара мужчин, играющих в фрисби, не является желаемым результатом, как и пара мужчин, играющих в футбол. Таким образом, в этом случае вторая подпись, как правило, будет лучшей, но она не всегда будет идеальной, в зависимости от логарифмической вероятности.

Давайте попробуем еще один пример, giraffes.jpeg:

Давайте попробуем еще один пример, giraffes.jpeg:

Очевидно, что у нас есть изображение жирафов, и первая подпись, группа жирафов, стоящих рядом друг с другом, кажется правильной, за исключением грамматического вопроса. Два других результата-группа жирафов, стоящих в поле, и группа жирафов, стоящих рядом друг с другом на поле.

Давайте рассмотрим еще один пример, headphones.jpeg:

Давайте рассмотрим еще один пример, headphones.jpeg:

Здесь мы выбрали headphones.jpeg, но результаты не включали наушники в качестве выхода. В результате появилась женщина, держащая в руке сотовый телефон, что является хорошим результатом. Второй результат, женщина, держащая мобильный телефон у уха, технически неверен, но в целом это хорошие подписи.

Давайте возьмем последний пример, ballons.jpeg. Когда мы запускаем изображение, мы получаем следующий вывод:

Давайте возьмем последний пример, ballons.jpeg. Когда мы запускаем изображение, мы получаем следующий вывод:

Результаты, которые мы получаем для этого изображения, – это женщина, стоящая на пляже и запускающая воздушного змея, женщина, запускающая воздушного змея на пляже, и молодая девушка, запускающая воздушного змея на пляже. Итак, модель получила женщину или молодую девушку, но вместо воздушного шара у нее был воздушный змей, хотя слово “воздушный шар” есть в словаре. Таким образом, мы можем сделать вывод, что модель не идеальна, но она впечатляет и может быть включена в ваше собственное приложение.

Запуск кода субтитров на Юпитере для нескольких изображений

Несколько изображений также можно добавить в качестве входной строки, разделив путь к изображению различных изображений запятыми. Время выполнения строки изображений будет больше, чем время, которое мы видели до сих пор.

Ниже приведен пример нескольких входных файлов:

input_files = 'test_images/ballons.jpeg,test_images/bike.jpeg,test_images/dog.jpeg,test_images/fireworks.jpeg,test_images/football.jpeg,test_images/giraffes.jpeg,test_images/headphones.jpeg,test_images/laughing.jpeg,test_images/objects.jpeg,test_images/snowboard.jpeg,test_images/surfing.jpeg'

capts = gen_caption(input_files)

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

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

Это завершает запуск предварительно обученной модели субтитров изображений.

Надеюсь, вам понравилось читать эту статью и вы нашли ее проницательной. Если вы хотите узнать больше о компьютерном зрении, настоятельно рекомендуется Проекты компьютерного зрения с OpenCV и Python 3 . С помощью подробного подхода, основанного на проектах, Проекты компьютерного зрения с OpenCV и Python 3 демонстрируют методы использования возможностей Python, OpenCV и TensorFlow для решения проблем компьютерного зрения, а также показывают, как создать приложение, которое может оценивать позы человека на изображениях.