Перейти к содержанию

Nier: Automata ver1.1.a

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

Мой приятель понимал, возможно, лишь половину из этих слов, но он очень верил в то, что нейросеть ерунды не посоветуют — и знал, что я как раз занимаюсь чем-то подобным, поэтому сразу прибежал с этим ко мне. А я в то время как раз был на середине изучения полугодового курса «Анализ данных»: python, pandas, sql etc.

Он знал, к кому обратиться. Меня зацепила эта идея — нейросеть, которая даёт совет написать нейросеть. А чтобы усилить этот сюр, я решил написать нейросеть с помощью нейросети. Абсолютный абсурд в квадрате — как раз то, что я люблю больше всего.

Я дал нейросети развернутый промпт (это был ChatGPT 2 или 3, тогда мы ещё работали промптами), загнал его несколько раз и получил несколько вариантов решения. Ни один не работал.

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

Помню, в нашем рабочем чате я поделился первыми впечатлениями. Вот дословно, орфография оригинала сохранена:

Ребятушки, я прочитал на обеде, что написал нам ЧатГТП, и я сцу теперь кипятком впечатлен. Он не просто сделал все, что я его просил. Он сделал больше, и сделал даже то, о чем я не подумал и чего не учёл. И он сделал это лучше, чем это сделал бы я!

Но это я прочитал только первую функцию.

Проверил вторую часть. Беру свои слова обратно. ChatGPT — тупое жывотное. Такое чувство, что он просто натырил код с интернета, а потом смешал в кучу. Три раза одно и то же действие повторил, разными словами

Это тоже я. Между двумя этими сообщениями прошло минут двадцать.

Мы скармливали нейросети одно и то же ТЗ дважды, с разной детализацией, и каждый раз получали примерно одинаковый выход, с небольшими вариациями. Как если бы двух разных людей попросили сделать одно и то же — результат одинаковый, но стиль и почерк разный. Сигмоида, например: один раз через math отдельной функцией, второй раз — numpy прямо в теле.


Проблема обнаружилась в последней функции — feed_forward, которая рассчитывает значения нейронов при прямом проходе. Вот что выдал ChatGPT:

def feed_forward(inputs, layers, weights):
    layers[0] = inputs
    for i in range(len(weights)):
        weights_i = np.array(weights[i])
        layers_i = np.array(layers[i])
        dot_product = np.dot(weights_i, layers_i)  # ← здесь
        layers[i+1] = 1 / (1 + np.exp(-dot_product))
    return layers, weights

Выглядит правдоподобно. Но падает.

Дело в том, что матрица весов weights[i] хранится в форме (n_in, n_out) — для каждого нейрона входного слоя список весов к каждому нейрону следующего слоя. Вектор layers[i] имеет размер (n_in,). Операция np.dot(weights_i, layers_i) пытается перемножить (n_in, n_out) на (n_in,) — размерности не совпадают. Нужно транспонировать матрицу: weights_i.T даст форму (n_out, n_in), и тогда (n_out, n_in) × (n_in,) = (n_out,) — всё сходится.

Правка — одна точка и одна буква:

def feed_forward(inputs, layers, weights):
    layers[0] = inputs
    for i in range(len(weights)):
        weights_i = np.array(weights[i])
        layers_i = np.array(layers[i])
        dot_product = np.dot(weights_i.T, layers_i)  # транспонируем матрицу весов
        layers[i+1] = 1 / (1 + np.exp(-dot_product))
    return layers, weights

После этого нейронка заработала — и, что важнее, заработала правильно.

«Upd: я осознал, чутка поправил код ЧатГТП, и теперь оно работает. И мало того что работает, так ещё правильно работает»

Наша работа была завершена, о чем я и оповестил всех в чате:

«ОФИЦИАЛЬНО УВЕДОМЛЯЮ ВСЕХ!!! Работа над кодом нейросети завершена. На данном этапе мы можем: создавать полносвязанные нейросети с произвольным количеством слоев и нейронов, а также обучать их. […] Спасибо ЧатГПТ за проделанную работу (хотя он троешник и приходилось его ВСЁ ВРЕМЯ поправлять). Спасибо Вам, что втянули меня в этот движ! Слава Человечеству!»

Нейросеть я назвал nier — в тот момент я как раз увлечённо смотрел только что вышедший аниме-сериал Nier: Automata Ver1.1a. События разворачиваются в далеком 11945 году. Андроиды воюют с машинными формами жизни — никто из них уже не помнит, зачем. Эта война напрочь лишена смысла, потому что человечество, ради которого она велась, давно вымерло.

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

Я считаю выход этого сериала, совпавший с началом волны хайпа вокруг нейросетей, знаковым событием. С тех пор прошло два с половиной года — и с каждым днем мы все ближе к технологической сингулярности. Уже пройден тест Тьюринга — дать ответ, где проходит граница между человеческим сознанием и машинными формами жизни, становится все сложнее. Что такое сознание? что такое душа? что отличает живое и неживое? Может ли машина чувствовать, любить, страдать, сходить с ума — или всё это лишь точная имитация, зеркало, в котором мы видим только самих себя? Вопросы, поставленные в том сериале, появляются теперь в новостных лентах — и с каждым днем становятся все актуальнее.

Я не знаю, останутся ли жить наши копии в андроидах, когда человечество вымрет — но моя нейросеть, написанная нейросетью, которая посоветовала написать нейросеть — точно останется жить на GitHub. Специально для этой статьи я сдул с неё пыль, оформил как библиотеку python, дописал примеры, взяв хрестаматийные ml-датасеты — распознавание цветков Ириса, перевод градусов из Цельсия в Фаренгейта, определение победителя в крестики-нолики.

К сожалению, мы так и не стали сказочно богатыми биржевыми трейдерами. Обученная на датасете биржевых индексов моя нейросеть может предсказывать котировки цен. Это математика — не магия. А вот предсказать реальные котировки цен на бирже — она, к сожалению, не может.

Слава Человечеству!