Мир глазами ИИ
Многие слышали, что ИИ может видеть. Не просто ставить прямоугольники на объектах и определять, что это за объект, а видеть по-настоящему. Понимать, что изображено на картинке, и в тексте передавать детали увиденного. Сейчас мы воспроизведем эту технологию у себя на компьютере и немного покопаемся в мозгах ИИ. Может быть эти манипуляции наведут на более серьезные мысли по поводу интеллекта машин и натолкнут на вопрос: «А так ли сильно он отличается от человеческого?»
Colab
Нам снова нужен будет бесплатный GPU. Идем в Колабу по ссылке https://colab.research.google.com
В этой статье не будем повторяться по поводу того, как подготовить для работы среду. В начале предыдущей статьи Генерация картинок на любом железе без Midjourney очень подробно описано, что и как надо сделать, чтобы идти дальше.
Install
Первым делом устанавливаем необходимые зависимости. Копируем этот код в первую пустую ячейку блокнота:
!pip install transformers timm einops -q
Запускаем этот код в ячейке. Наводим курсор на код и жмем CTRL+ENTER, или для маков СOMMAND+ENTER. Или жмем на кнопку слева ячейки. Ждем выполнения.
Импорты
В следующую ячейку копируем такой код:
from transformers import AutoModelForCausalLM, AutoTokenizer
from PIL import Image
import torch
import locale
locale.getpreferredencoding = lambda: «UTF-8»
model_id = «vikhyatk/moondream2»
revision = »2024–03–05»
# Check if CUDA (GPU support) is available and then set the device to GPU or CPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# Load the model and tokenizer
model = AutoModelForCausalLM.from_pretrained(model_id, trust_remote_code=True, revision=revision).to(device)
tokenizer = AutoTokenizer.from_pretrained(model_id, revision=revision)
Запускаем. Ждем, когда код выполнится.
Подготовка для дальнейшей работы закончилась, теперь самое интересное.
Загрузка картинок
Нам нужны будут картинки, чтобы давать их модели на опознание. Их можно сохранить в среде блокнота, но они при перезагрузке пропадут. Есть способ хранить картинки на Гугл Диске и монтировать папку хранения к блокноту каждый раз при перезапуске среды. Этого в статье делать не будем. Поступим проще — картинки будем получать по ссылке. Чтобы это реализовать, нам потребуется следующий код:
!wget -O image.jpg https://nukadeti.ru/content/images/essence/tale/261/1248.jpg
Запускаем код.
Картинка
Давайте посмотрим, что мы скачали.
Копируем и запускаем такой код:
image = Image.open('image.jpg') #
если картинка сохранена в отдельной папке среды блокнота, то указываем путь к изображениюimage
Вот такую картинку мы загрузили:
Зрение
Переходим к подключению зрения ИИ.
Копируем следующий код в новую ячейку
image = Image.open('image.jpg') #path of the input image
question = 'What do you see in the image?'
enc_image = model.encode_image (image).to (device)
# Generate the answer
answer = model.answer_question (enc_image, question, tokenizer)
# If the output is a tensor, move it back to CPU for further operations like print
if isinstance (answer, torch.Tensor):
answer = answer.cpu ()
print (answer)
В этом коде есть переменная question, c помощью которой мы будем задавать модели вопросы. Их мы будем формулировать на её родном английском языке, чтобы она нас лучше понимала. Это нетрудно сделать с помощью, например, GoogleПереводчик.
Попробуем узнать, что видит ИИ на картинке. Итак, первый вопрос: What do you see in the image?
Перевод: Что ты видишь на картинке?
Запускаем код в ячейке. Ответ модели такой: A painting is depicted in this image, featuring a rabbit, a fox, and another animal. The animals are seated on a bench, with a wooden house in the background. The ground is covered with grass.
Перевод: На этом изображении изображена картина, на которой изображены кролик, лиса и еще одно животное. Животные сидят на скамейке на фоне деревянного дома. Земля покрыта травой.
Модель не уверена, что за третий персонаж в этом сюжете. Зададим уточняющий вопрос: Who is depicted sitting on the bench next to the fox?
Перевод: Кто изображен сидящим на скамейке рядом с лисой?
Просто копируем этот вопрос на английском в значение переменной question и запускаем код в ячейке.
Ответ: A cat is depicted sitting on a bench next to a fox.
Перевод: Кот изображен сидящим на скамейке рядом с лисой.
Верно!
Спросим вот что: Which of the characters depicted is the smallest?
Перевод: Какой из изображенных персонажей самый маленький?
Ответ: The smallest character is a rabbit, depicted in a grey outfit and standing in front of a house. The other two characters are a fox and a cat, also present in the house.
Перевод: Самый маленький персонаж — кролик, изображенный в сером наряде и стоящий перед домом. Два других персонажа — лиса и кот, также присутствуют в доме.
С цветом наряда зайца-кролика можно не согласиться. Но модели некоторые оплошности можно и простить. Она у нас тоже маленькая :).
Будем уточнять дальше. What color are the cat’s pants?
Перевод: Какого цвета штаны у кота?
Ответ: Green
Перевод: Зеленый
What color is the bunny’s shirt?
Перевод: Какого цвета рубашка у зайчика?
Ответ: Orange
Перевод: Оранжевый
Неплохо.
А теперь давайте зададим вопрос несколько другой, посерьезнее.
Is there a threat to the hare in this image?
Перевод: Есть ли угроза для зайца на этом изображении?
Ответ: No, there is no threat to the hare in this image. The scene features a cat and a fox sitting on a bench, while a rabbit is standing nearby. The rabbit is not in any immediate danger, and there is no indication that predators are present.
Перевод: Нет, никакой угрозы зайцу на этом изображении нет. В сцене кот и лиса сидят на скамейке, а рядом стоит кролик. Кролику не грозит непосредственная опасность, и нет никаких признаков присутствия хищников.
Заметим, что хищники-то есть, но модель оценивает настроение лисы как дружелюбное, и поэтому не может отнести ее к хищнику — носителю угрозы для зайца. Хотя формально ИИ ошибся в деталях, но по существу вопроса ответил правильно. Защищать его мы не будем, модель настолько крошечная, что и такой результат для нее на уровне гениальности.
Задание со звездочкой
Загрузим другое изображение.
!wget -O image.jpg https://cdnn21.img.ria.ru/images/15580/75/155807501_0:0:0:0_600x0_80_0_0_257bb0d3ef49560de8ae7109d11ec9f1.jpg
Посмотрим, что загрузили
image = Image.open('image.jpg') #path of the input image
image
Такая вот картинка. Это уже не сказки.
Спросим у модели, что она видит, с помощью такого вопроса: Describe the signs of aggression in the image, if any.
Перевод: Опишите признаки агрессии на изображении, если они есть.
Ответ: In the center of the image, a group of people are engaged in a fight. One individual is holding a flag, while another person is holding a drum. The background features buildings, trees, and additional people, along with a road.
Перевод: В центре изображения группа людей ведет драку. Один человек держит флаг, а другой держит барабан. На заднем плане изображены здания, деревья и дополнительные люди, а также дорога.
Гифки
Данная модель может анализировать не только статичные изображения, но и гифки. Долго на этой возможности останавливаться не станем. Просто покажем, что это тоже возможно.
Скачаем гифку с помощью такого кода.
!wget -O tenor.gif https://media1.tenor.com/m/ZuAyMucnnJEAAAAC/spongebob-squarepants.gif
Посмотрим, что мы скачали. Запустим следующий код.
# Load the GIF file
gif_path = 'tenor.gif' # Replace with your gif path
gif = Image.open(gif_path)
gif
Скопируем код в новую ячейку для покадрового анализа гифок. Гифка — это тоже видео, но с маленькой частотой кадров. Поэтому видео анализировать также можно. Но тут смотрите за ресурсами. Одно дело — одна картинка, другое, например, 24 картинки в секунду. Т.е. этой модели нужно будет на одну секунду видео обрабатывать по 24 картинки. Это долго. Нужно больше железа, чем мы располагаем в данный момент.
Код:
# Load the GIF file
gif_path = 'tenor.gif' # Replace with your gif path
gif = Image.open(gif_path)
question = «Which character is in the image?»
frame_count = 0
answers = []
while True:
try:
# Seek to the next frame
gif.seek (frame_count)
# Process every 5th frame
if frame_count % 10 == 0:
# Convert the frame to a format compatible with the model
frame = gif.convert ('RGB')
# Process the frame with the model
enc_image = model.encode_image (frame).to (device)
answer = model.answer_question (enc_image, question, tokenizer)
if isinstance (answer, torch.Tensor):
answer = answer.cpu ()
# Append the answer
answers.append (answer)
frame_count += 1
except EOFError:
# Exit the loop when the end of the GIF is reached
break
# Concatenate and print all answers
all_answers = '\n'.join (answers)
print (all_answers)
Вот список вопросов для примера:
Which character is in the image?
What is the character in the image doing?
What is the text at the bottom of the image?
Последовательно задаем их модели. Получаем ответы. Это ГубкаБоб. Персонаж на изображении стоит и, кажется, говорит с улыбкой на лице. На заднем плане есть текст. Надпись на изображении гласит: Happy April Fool’s Day!
Модель будет выдавать описание каждого кадра. Для того, чтобы получить общее описание видео, нужно будет загрузить все ответы этой модели в другую для саммаризации. Но это тема отдельной статьи.
ИИ-художник
Прикоснемся к некоторым скрытым процессам, которые происходят не только в «голове» машины, но случаются и у людей.
Скачаем другую картинку:
!wget -O image.jpg https://pentaschool.ru/upload_2/Dizajn-detskoj.jpg
Посмотрим
image = Image.open('image.jpg') #path of the input image
image
Милота.
Мы усложним задачу и зададим не один-два вопроса, а сразу серию с уточнениями деталей. Будем наращивать контекст для дальнейших манипуляций с ним. Позже мы попросим модель нарисовать увиденное на этой картинке. Проверим её художественные способности.
Создадим список вопросов в новой ячейке:
questions = '''What do you see in the image?
Describe the child's appearance?
Describe the child's face?
Describe the child's hair?
What color is the child's eyes?
What toys are in the image?
Are there any other toys in the image besides the teddy bear?'''
Запускаем этот код в ячейке. Теперь мы готовы задавать эти вопросы по очереди и, соответственно, сразу получать ответы на них.
Код для следующей ячейки:
image = Image.open('image.jpg') #path of the input image
enc_image = model.encode_image (image).to (device)
for question in questions.splitlines ():
# Generate the answer
answer = model.answer_question (enc_image, question, tokenizer)
# If the output is a tensor, move it back to CPU for further operations like print
if isinstance (answer, torch.Tensor):
answer = answer.cpu ()
print (answer)
Ответ:
A boy is seated on a bed, holding a book in his hands. The bed is adorned with pillows, and a blue toy is present. The background features a white wall and a window.
A child is depicted in this image, seated on a bed and dressed in a yellow t-shirt and shorts. The child is holding a book in one hand and appears to be smiling. The background features a few pillows and toys.
The child’s face is smiling, and there is a slight curl at the end of the hair. The child is seated on a bed, holding a book in one hand.
The child has blonde hair, which is described as «blond» in some descriptions.
The child has blue eyes.
The image features a child sitting on a bed, holding a book. Nearby, there are blue pillows and a blue teddy bear.
Yes, there are other toys present in the image, including a teddy bear and a doll.
Перевод:
Мальчик сидит на кровати, держа в руках книгу. Кровать украшена подушками и присутствует синяя игрушка. На заднем плане — белая стена и окно.
На этом изображении изображен ребенок, сидящий на кровати и одетый в желтую футболку и шорты. Ребенок держит книгу в одной руке и, кажется, улыбается. На заднем плане несколько подушек и игрушек.
Лицо ребенка улыбается, на кончиках волос имеется небольшой завиток. Ребенок сидит на кровати, держа в одной руке книгу.
У ребенка светлые волосы, которые в некоторых описаниях описываются как «светлые».
У ребенка голубые глаза.
На изображении изображен ребенок, сидящий на кровати и держащий в руках книгу. Рядом синие подушки и синий плюшевый мишка.
Да, на изображении присутствуют и другие игрушки, в том числе плюшевый мишка и кукла.
Дальше нам придётся пойти на компромисс. По нашему замыслу мы хотим сделать из этих ответов один промт и передать его в другую модель, чтобы она нарисовала картину. Так мы сможем увидеть, как модель увидела эту картинку. Простите за тавтологию, но в этом случае, думаю, что она уместна. Человек увидит, как видит машина.
Для этого нужно вернуться в предыдущую статью о генерации изображений Генерация картинок на любом железе без Midjourney
У нас не получится отправить этот промт целиком. Модель для генерации тоже крохотная, она принимает не больше 77 токенов. Поэтому пойдем на хитрость и сделаем саммаризацию того большого ответа с описаниями картинки, т.е. постараемся сократить количество слов в тексте и при этом максимально сохранить смысл. Для данного примера саммаризация делалась на bioGPT, т.е. с использованием головы хомо сапиенса. Так тоже можно. Получим примерно следующее:
prompt = '''Create a painting in anime style:
Wide frame. A three year old smiling boy with blue eyes is seated on a bed and dressed in a t-shirt and shorts, holding a book in his hands. The child has blonde hair slightly curl at the end of the hair. The bed is adorned with while pillows. Blue teddy bear is present. White wall and a window.
'''
В итоге модель генерации отдала несколько вариантов изображений, из которых наиболее подходящим для целей этой статьи оказалось следующее:
Кто-то скажет, что не одно и то же. Есть различия. Но давайте зададим теперь уже себе следующий вопрос:
«Много ли людей могут запомнить то, что изображено на фотографии в деталях?»
Таких людей немного. Проверьте себя. Не смотрите на оригинал. Постарайтесь сами вспомнить, что там было изображено. Вам будет легче это сделать, чем среднестатистическому человеку, потому что только что вы напоминали себе о деталях изображения, когда читали уточняющие вопросы и ответы на них. А если бы их не было, и вам показали эту картинку на 3 или 5 секунд? Ну и, в конце концов, художника каждый может обидеть. Он так видит :)
На этом примере, наверное, можно разглядеть некоторые признаки «человечности» машины. Может именно из-за таких различий и собственного видения реальности художниками, нам интересны произведения искусства. И может быть, машины будут нам интересны, если люди оставят место в сознании ИИ для несовершенств. У нас будет повод говорить с машинами, учить их, учиться у них и радоваться успехам. Может, в этой разнице между реальностью и выдумкой кроется что-то большее, чем последовательность цифр. Может там и спрятана человечность.