• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Написание AIM нейросети

OverlordGameDev

RAM
Пользователь
Регистрация
14.07.2024
Сообщения
106
Реакции
131

Предисловие:​

После написания огромной статьи о разработке игры мне захотелось отвлечься и написать что-то более легкое. Так как я геймдев-разработчик, то и сегодняшняя статья будет о создании софта для игр, а точнее, о построении аима на базе нейронной сети, используя YOLO из библиотеки Ultralytics.

Что такое Yolo:​

YOLO — это метод из Python-библиотеки, который позволяет распознавать объекты на изображениях и видео. Проще говоря, это нейронная сеть, которая занимается распознаванием объектов. Код, написанный в статье, будет работать с распознанными объектами и информацией о них. В данной статье будет использоваться последняя стабильная версия YOLOv8.

Создание обученной модели для определения объектов:​

Для того чтобы нейронная сеть могла определять объекты, ее нужно обучить, а именно предоставить файл с материалом, содержащим заранее подготовленные объекты. Для обучения понадобится достаточно большое количество скриншотов из игры, в которой должна работать нейросеть. Минимальное количество скриншотов — примерно 2 тысячи, но чем больше, тем лучше.

Скриншоты желательно должны быть размером 640 на 640 пикселей. Около 10% скриншотов должны быть пустыми, то есть без игроков, но в естественной среде игры, например, на карте. Это нужно для того, чтобы нейросеть не определяла случайные объекты как игроков, а имела примеры как игрока, так и всего остального. После подготовки скриншотов необходимо создать разметку на этих изображениях, выделяя объекты игроков. Для этого есть несколько программ и сервисов, таких как: Label Studio, LabelImg и Roboflow. В данной статье будет использован сервис Roboflow.

Чтобы начать разметку, нужно перейти на сайт https://roboflow.com и создать новый проект.
1724033924143.png

1724033944445.png

После создания проекта с подготовленными ранее скриншотами нужно начать делать разметку. Это довольно простое, но времязатратное занятие.
1724033992384.png

1724034010557.png

Вот и всё. Нужно просто выбрать инструмент выделения и начать обводить объекты игроков. После того как все скриншоты будут обработаны таким способом, нужно получить датасет с этими скриншотами и файлами разметки.
1724034050816.png

1724034083807.png

1724034103834.png

1724034128834.png

1724034146403.png

В итоге скачанный датасет с сайта должен выглядеть так же, как и на скриншоте:
1724034179249.png


Теперь нужно запустить обучение на данном датасете. Для этого потребуется достаточно мощный компьютер. Например, на компьютере с 12-ядерным Xeon и 32 GB ОЗУ, система просто зависала намертво при обучении на датасете с 16K скриншотов. Обучение удалось завершить лишь на компьютере с Ryzen 7, 64 GB ОЗУ и файлом подкачки в 100 GB. Если у вас есть компьютер подобной мощности, для обучения нужно лишь установить библиотеку Ultralytics, затем открыть консоль и ввести следующую команду:
Код:
yolo task=detect mode=train imgsz=640 data=Полный путь до файла data.yaml epochs=45 batch=8 name=Имя для готового файла
Единственное, что вы можете изменить для себя, это количество эпох.

Что такое эпохи при обучении модели:​

Эпохи — это количество раз, сколько нейросеть пройдётся по всем данным датасета от начала до конца. С каждой эпохой у неё будет всё больше данных, и определение объектов будет становиться лучше. Однако, если задать слишком большое количество эпох, нейросеть может начать определять случайные объекты, поэтому с этим лучше не перебарщивать.

После того как обучение закончится, в папке с датасетом появится файл best.pt. Это и есть готовый файл модели. После его получения можно приступать к написанию логики на Python.

Написание логики на Python:​

Инструкции по созданию проекта на Python и открытию его в PyCharm не будет, поэтому сразу можно приступить к написанию кода. Первым делом нужно добавить необходимые библиотеки:
Python:
import os
import torch
from ultralytics import YOLO
import dxcam

Что за библиотека torch и cuda:​

Torch — это библиотека, работающая с моделями машинного обучения. В коде она будет использована для определения устройства (CPU или GPU), а также YOLO будет использовать Torch для загрузки обученной модели.

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

С установкой библиотеки Torch совместно с CUDA могут возникнуть некоторые сложности, особенно при установке по отдельности или через PyCharm. Для упрощения процесса можно создать BAT-файл. Но для начала необходимо создать в папке с проектом папку requirements. В этой папке создайте текстовый файл с названием requirements_gpu.txt. Внутри этого файла укажите следующие библиотеки:
Код:
torch==2.4.0+cu124
torchvision==0.19.0+cu124
--extra-index-url https://download.pytorch.org/whl/cu124

После сохранения файла нужно перейти в корневую папку проекта и создать BAT-файл, внутри которого будет следующая команда:
Код:
python -m venv venv && call .\venv\Scripts\activate.bat && pip install -r requirements\requirements_gpu.txt

pause

После этого необходимо запустить BAT-файл и дождаться полной установки. Остальные библиотеки можно установить обычным способом. Теперь можно продолжить написание кода. Первое, что нужно сделать, — это создать переменные, в которых будут храниться размеры экрана и размеры FOV (зона, в которой будут делаться скриншоты и детектить объекты).
Python:
screen_width = 1366
screen_height = 768
fov_width = 500
fov_height = 500

Далее нужно инициализировать CUDA.
Python:
device = 'cuda' if torch.cuda.is_available() else 'cpu'
P.S. device = 'cuda' — если найдена библиотека torch, то функция is_available() проверяет наличие CUDA. Если CUDA доступна, функция возвращает значение больше нуля, и device устанавливается как 'cuda'. Если CUDA недоступна, функция возвращает False, и device устанавливается как 'cpu'.

Теперь нужно открыть модель обучения, используя устройство, которое было определено, то есть CPU или GPU.
Python:
model = YOLO(os.path.abspath("models\\best.pt"))
model.to(device)

Далее нужно вычислить центр экрана и левый верхний угол FOV, чтобы центрировать его.

Для вычисления центра экрана по координате X берётся ширина экрана, указанная в переменной screen_width, и делится на 2. Полученное значение будет центром по ширине. Например, если ширина экрана 1366 пикселей, то деление на 2 даёт 683 пикселя, и это будет центр по ширине.
Python:
center_x = screen_width // 2

Аналогично ширине, для вычисления центра экрана по координате Y берётся значение из переменной screen_height и делится на 2. Полученное значение будет центром по высоте экрана.
Python:
center_y = screen_height // 2

Теперь переходим к вычислению левого верхнего угла FOV. Ширина прямоугольника FOV (x) делится на 2, затем из центра ширины экрана вычитается разделённая ширина прямоугольника. В итоге получается, что половина прямоугольника находится левее центра экрана.
Python:
fov_x = center_x - fov_width // 2

Также по аналогии нужно делать и с высотой FOV. Высота прямоугольника FOV делится на 2, затем из центра высоты экрана вычитается разделённая высота прямоугольника.
Python:
fov_y = center_y - fov_height // 2
В итоге получается, что половина прямоугольника находится выше центра экрана. Ниже представлен график для большей ясности (надеюсь, он понятен):
1724034714663.png


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

Функция скриншота:​

Для этого первым делом нужно создать функцию screenshot. Внутри функции необходимо инициализировать объект камеры из библиотеки. Для скриншотов в данном случае будет использоваться библиотека dxcam.
P.S. Данная библиотека показала себя намного лучше, чем популярная mss, и скорость создания скриншота была в 2 раза выше.
Python:
import dxcam
def screenshot():
   camera = dxcam.create()

Затем нужно создать цикл while True и в нем создать переменную, которая будет захватывать скриншот, начиная с точки (x, y) FOV.
Python:
frame = camera.grab(region=(fov_x, fov_y, fov_x + fov_width, fov_y + fov_height))

Также нужно добавить проверку, чтобы если скриншот пуст, цикл начинал выполнение заново.
Python:
if frame is None:
   continue

Далее нужно вызывать функцию (которой пока еще нет), которая будет обрабатывать полученные скриншоты и определять на них объекты (в качестве аргумента frame передается объект скриншота).
Python:
detection(frame)

С функцией создания скриншота закончено. Теперь нужно создать функцию для обработки скриншота и определения на нем объектов.

Функция обработки и детекции объектов на скриншотах:​

Функция будет называться detection. Внутри созданной функции первым делом нужно инициализировать объект с информацией о первом обработанном скриншоте.
Python:
results = model.predict(frame, verbose=True)[0]
model.predict — это функция, которая возвращает список с найденными объектами на обработанных скриншотах. verbose=True — это флаг, который означает, что будет выводиться информация о результате обнаружения. [0] означает, что будет извлечен объект с информацией о первом скриншоте. В данном коде в любом случае будет только один объект, так как в обработку всегда идет только один скриншот, но все же это нужно уточнять.

Далее нужно написать условие if, в котором будет проверяться, чтобы в объекте скриншота были объекты игроков.
Python:
if len(results.boxes) > 0:
Работа продолжается, если в объекте boxes (который находится внутри объекта первого скриншота) есть хотя бы один объект с информацией о найденных объектах игрока..

Далее, если объекты игроков найдены, необходимо инициализировать первый объект игрока.
Python:
box = results.boxes[0]

Затем нужно инициализировать координаты первого найденного игрока.
Python:
box_cord = box.xyxy[0].tolist()

Далее нужно вычислить центр объекта игрока по координатам x и y.
Python:
center_x_obj = (box_cord[0] + box_cord[2]) / 2
center_y_obj = (box_cord[1] + box_cord[3]) / 2

Теперь нужно вычислить центр объекта по координатам x и y относительно экрана.
Python:
center_x_obj += fov_x
center_y_obj += fov_y
Знак += означает, что переменной присваивается её текущее значение, к которому прибавляется второе значение. Это сокращает запись кода и делает его более читаемым.
Пример:
Код:
center_x_obj += fov_x эквивалентно center_x_obj = center_x_obj + fov_x.
center_y_obj += fov_y эквивалентно center_y_obj = center_y_obj + fov_y.

Далее можно добавить настройку высоты по y, чтобы была возможность стрелять не в центр объекта, а в голову, если есть желание, но это не обязательно.
Python:
center_y_obj -= (box_cord[3] - box_cord[1]) * aim_target
В выражении box_cord[3] - box_cord[1] вычисляется высота объекта по y, после чего это значение умножается на aim_target.

Теперь необходимо вычислить расстояние объекта от центра экрана.
Python:
dx = center_x_obj - center_x
dy = center_y_obj - center_y

После этого нужно вызвать функцию наводки (которой пока что нет) и передать в нее переменные dx и dy.
Python:
aim(dx, dy)

Функция наводки на найденный объект:​

Теперь можно приступить к написанию функции наводки на найденный объект игрока. Для этого нужно создать функцию с названием aim, принимающую переменные dx и dy, и внутри этой функции добавить проверку if на нажатие левой кнопки мыши. Для работы с мышью будет использоваться библиотека win32api.
Python:
import win32api
import win32con
def aim(dx, dy):
   if 0 > win32api.GetKeyState(win32con.VK_LBUTTON):

Внутри проверки if нужно разделить расстояния до объекта на несколько равных частей, указанных в переменной aim_step (которую тоже нужно создать).
Python:
aim_step = 2
aim_step_x = dx / aim_step
aim_step_y = dy / aim_step

Далее нужно создать цикл, который будет повторяться столько раз, сколько указано в переменной aim_step. Внутри цикла нужно перемещать мышь, используя библиотеку win32api, на координаты, указанные в aim_step_x и aim_step_y.
Python:
for i in range(aim_step):
   win32api.mouse_event(win32con.MOUSEEVENTF_MOVE, int(aim_step_x), int(aim_step_y), 0, 0)
time.sleep(aim_time_sleep)
Таким образом, получается, что путь до объекта разделен, например, на 5 частей, и мышь будет передвигаться 5 раз на разделенное число. Таким образом, мышь доходит до объекта не за одно действие, а в несколько шагов, и так как после каждого шага указана пауза, мышь перемещается более плавно, а не телепортируется в конечную точку.

P.S. Для time.sleep нужно импортировать библиотеку time.

На этом вся нейронная сеть готова. Осталось лишь задать запуск функции создания скриншота при запуске программы.
Python:
if __name__ == "__main__":
   screenshot()

Весь код нейронной сети:​

Python:
import os
import time
import win32api
import torch
import win32con
from ultralytics import YOLO
import dxcam


screen_width = 1366
screen_height = 768
fov_width = 500
fov_height = 500
aim_step = 2
aim_time_sleep = 0.017
aim_target = 0.25


device = 'cuda' if torch.cuda.is_available() else 'cpu'
if torch.cuda.is_available():
   print("Используется CUDA")
else:
   print("Используется CPU")


model = YOLO(os.path.abspath("models\\best.pt"))
model.to(device)

center_x = screen_width // 2
center_y = screen_height // 2

fov_x = center_x - fov_width // 2
fov_y = center_y - fov_height // 2


def screenshot():
   camera = dxcam.create()


   while True:
       frame = camera.grab(region=(fov_x, fov_y, fov_x + fov_width, fov_y + fov_height))
       if frame is None:
           continue
       detection(frame)


def aim(dx, dy):
   if 0 > win32api.GetKeyState(win32con.VK_LBUTTON):
       aim_step_x = dx / aim_step
       aim_step_y = dy / aim_step

       for i in range(aim_step):
           win32api.mouse_event(win32con.MOUSEEVENTF_MOVE, int(aim_step_x), int(aim_step_y), 0, 0)
           time.sleep(aim_time_sleep)


def detection(frame):
   results = model.predict(frame, verbose=True)[0]

   if len(results.boxes) > 0:
       box = results.boxes[0]
       box_cord = box.xyxy[0].tolist()
       center_x_obj = (box_cord[0] + box_cord[2]) / 2
       center_y_obj = (box_cord[1] + box_cord[3]) / 2
       center_x_obj += fov_x
       center_y_obj += fov_y
       center_y_obj -= (box_cord[3] - box_cord[1]) * aim_target
       dx = center_x_obj - center_x
       dy = center_y_obj - center_y
       aim(dx, dy)


if __name__ == "__main__":
   screenshot()

Статья в виде документа: https://docs.google.com/document/d/1ny3V6XrqH89oT2YxsPbTk_scHVG0Yqv9PRrklAyFSjk/edit?usp=sharing

Вывод:​

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

Сделано OverlordGameDev специально для форума xss.pro
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Я так понимаю это читы нового поколения. Можешь записать видео? Запусти нейронку на видосе и покажи как это работает в игре на практике. И насколько лучше нейросеть справляется обычного аима тоже интересно.
 
Вот что непонятнно:
Геймдев разработчик, занятый разработкой игр, находит как-то ресурс xss, регистрируется на нем и пишет статью.
Зачем это все геймдев разрабу?
Почему он вот этим занялся вместо написать еще одну игру и получать за нее еще больше денег.
Или я че-то не понимаю про геймдев или это все очень странно.
 
Почему он вот этим занялся вместо написать еще одну игру и получать за нее еще больше денег
Насколько я знаю в геймдеве сейчас все очень плохо, люди не работающие в крупных студиях получают копейки (если их вообще получают). Так что вероятно ТС это один из числа сотен тысяч инди-разрабов, живущих на копейки.
Да и что мешает человеку хотеть развиваться в разных направлениях? Я вот в перерывах между кодерством и asm-одрочкой ретро музыку пишу:)
 
Зачем это все геймдев разрабу?
Почему он вот этим занялся вместо написать еще одну игру и получать за нее еще больше денег.
Или я че-то не понимаю про геймдев или это все очень странно.
игру написать - это не в магазин сходить
 
Ну так моя непонятка в том как игродела могло сюда занести вообще.
И да игру написать это не в магаз сходить, но в чем смысл игроделу таратить свое время на окологеймдев статьи на непрофильном ресурсе.
По мне так игроделы это люди из другого мира, которым сюда просто не нужно.
Я могу представить малварщика у которого хобби игры, но мне сложно представить игродела у которого хобби малвара.
 
Теперь нужно запустить обучение на данном датасете. Для этого потребуется достаточно мощный компьютер.
Для таких задач уже давно не нужны мощные компы) Существует сервис colab.google, который предоставляет nvidia tesla t4 для обучения моделей, плюс имеет хорошую интеграцию с YOLOv8. Достаточно подать на вход размеченные данные и на выходе получить обученную ONNX-модель
 
но мне сложно представить игродела у которого хобби малвара.
Малварщик != читодел. Игры и читы - темы смежные, да и форум не только для малварщиков.
 
Я так понимаю это читы нового поколения. Можешь записать видео? Запусти нейронку на видосе и покажи как это работает в игре на практике. И насколько лучше нейросеть справляется обычного аима тоже интересно.
На днях запишу
 
Малварщик != читодел. Игры и читы - темы смежные, да и форум не только для малварщиков.
Ага но и форм то не про читы и тд.
Просто я представил себя игроделом, ну и допустим читы мне тоже интересны. Но я всеравно не понимаю как бы я вышел на этот форм, и зачем бы я сюда писал про читы, просто невижу тропинок из геймдева сюда, отсюда в геймдев вижу =)
Единственно думаю автор изначально с этого форума а в геймдев уже ушел после.
 
Вот что непонятнно:
Геймдев разработчик, занятый разработкой игр, находит как-то ресурс xss, регистрируется на нем и пишет статью.
Зачем это все геймдев разрабу?
Почему он вот этим занялся вместо написать еще одну игру и получать за нее еще больше денег.
Или я че-то не понимаю про геймдев или это все очень странно.
Все очень просто, как и писали ниже, дела не очень в ру геймдеве если ты не в большой фирме. Я в основном работал по фрилансу, но сейчас на один заказ просто нереальное количество претендентов. Мне сказали что на данном форуме платят за уникальные темы, поэтому я решил начать писать свой проект в соло и пока он не готов, получать деньги со статей о написании этого игрового проекта. Тема о разработке игры отняла морально больше сил чем я рассчитывал, поэтому решил отвлечься, а нейрочиты достаточно интересная и не обычная тема, к тому же она близка к самому геймдеву, поэтому и написал данную статью. Честно говоря я уже убил почти 2 месяца на статьи но пока ещё не получил с них деньги, так что возможно, я просто пропаду от сюда и пойду работать в Тинькофф)
 
Ага но и форм то не про читы и тд.
Просто я представил себя игроделом, ну и допустим читы мне тоже интересны. Но я всеравно не понимаю как бы я вышел на этот форм, и зачем бы я сюда писал про читы, просто невижу тропинок из геймдева сюда, отсюда в геймдев вижу =)
Единственно думаю автор изначально с этого форума а в геймдев уже ушел после.
Сюда я честно говоря попал вообще по чистой случайности от малознакомого человека. Честно говоря я всё ещё не верю что мне заплатят за темы)
 
Все очень просто, как и писали ниже, дела не очень в ру геймдеве если ты не в большой фирме. Я в основном работал по фрилансу, но сейчас на один заказ просто нереальное количество претендентов. Мне сказали что на данном форуме платят за уникальные темы, поэтому я решил начать писать свой проект в соло и пока он не готов, получать деньги со статей о написании этого игрового проекта. Тема о разработке игры отняла морально больше сил чем я рассчитывал, поэтому решил отвлечься, а нейрочиты достаточно интересная и не обычная тема, к тому же она близка к самому геймдеву, поэтому и написал данную статью. Честно говоря я уже убил почти 2 месяца на статьи но пока ещё не получил с них деньги, так что возможно, я просто пропаду от сюда и пойду работать в Тинькофф)
А можно тебя пораспрашивать про геймдев? Мне правда очень интересно, думаю и другим будет интересно узнать про это.
 
Я так понимаю это читы нового поколения. Можешь записать видео? Запусти нейронку на видосе и покажи как это работает в игре на практике. И насколько лучше нейросеть справляется обычного аима тоже интересно.
На счёт того что нейросеть лучше обычного аима, нейросеть абсолютно не лучше и вряд-ли станет, единственный ее плюс перед классическими читами - защита от бана античитом
 
Сюда я честно говоря попал вообще по чистой случайности от малознакомого человека. Честно говоря я всё ещё не верю что мне заплатят за темы)
Конечно, без проблем. Я вообще не кодер по большей степени а 3д моделлер. Языки пришлось учить по ходу дела. Питон для написания своих плагинов для блендер. C# для работы с юнити.
У меня так же своя игра есть в стим, но это был первый опыт и весьма неудачный, за несколько лет всё ещё не вывел деньги т.к минимальная сумма не набралась)
 
На счёт того что нейросеть лучше обычного аима, нейросеть абсолютно не лучше и вряд-ли станет, единственный ее плюс перед классическими читами - защита от бана античитом
Лучше незначит более меткая, это баланс между меткостью и беспалевностью.
 
Лучше незначит более меткая, это баланс между меткостью и беспалевностью.
Ну лично у меня такое мнение: к нейронке нужно привыкать, за тебя она все не сделает, на даль детектит плохо т.к игроков практически от столба не отличить. Если игроку не важен бан- лучше брать читы. Если хочется играть долго и на основе- нейронка, но нужно быть готовым к проигрышам
 
Лучше незначит более меткая, это баланс между меткостью и беспалевностью.
Мне кажется нейронку корректнее сравнивать с макросами а не читами
 
Конечно, без проблем. Я вообще не кодер по большей степени а 3д моделлер. Языки пришлось учить по ходу дела. Питон для написания своих плагинов для блендер. C# для работы с юнити.
У меня так же своя игра есть в стим, но это был первый опыт и весьма неудачный, за несколько лет всё ещё не вывел деньги т.к минимальная сумма не набралась)
Ну отлично, это на самом деле интересно когда сюда приходят люди из других миров. Тем более ты еще и 3дшник что тоже очень интересно.
Я буду тебе набрасывать вопросов и постепенно попытаемся выстроить картину что же происхдит в мире геймдева и 3д.

Про 3д.
1 Почему клепать ассеты в стор не вариант?
2 Почему фрилансить как 3дшник не вариант?

Про разработку.
1 Почему тебе обязательно нужно работать в фирме? Ты ведь фулл стек умеешь и арт и код.
2 Почему не вариант пилить мобилки гперказуал? Там ведь цикл разработки короткий а ты еще и артист так что вопрос графона сам закроешь. Тем более юнька.
3 Что насчет фриланса в геймдеве, я вроде видел такую тему что можно у "изателей" брать заказ на игру, это выглядит так что тебе дают тз(обычно какой то простенький мобиломусор) что нужно и какую то небольшую сумму на разработку.
 
Ну лично у меня такое мнение: к нейронке нужно привыкать, за тебя она все не сделает, на даль детектит плохо т.к игроков практически от столба не отличить. Если игроку не важен бан- лучше брать читы. Если хочется играть долго и на основе- нейронка, но нужно быть готовым к проигрышам
Я бы делал чит с минимальной доводкой до попадания, если чит видит что тебе до попадания нехватает пару пикселов то доводит.
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх