Все мы видели много статей, где с помощью AI-инструментов за минуты выполняется работа, на которую раньше мог легко уйти день. Особенно впечатляют примеры, где работа (успешно) идет вне зоны компетенции человека (т.е. когда AI позволяет делать то, что человек в принципе один сделать не мог бы). Но сегодня у меня получился несколько другой случай:

Задача стояла относительно тривиальная: нужно было сгенерировать look-up table (LUT) для по-канального увеличения контраста изображения (S-кривая), и применить эту кривую на фотографии с USB-камеры микроскопа. Берем ChatGPT (даже 3.5 должен прокатить, тут всего-то одна формула), за 10 секунд получаем Python-код типичной S-кривой (также ChatGPT для моего удобства сразу добавил отрисовку графика через matplotlib), настраиваем параметр "кривизны" кривой по вкусу - и можно вставлять в финальное приложение. Среди множества S-кривых/сигмоид ChatGPT использовал "логистическую функцию" - она одна из наиболее простых. Но у неё есть и недостаток - параметром "кривизны" нельзя сменить увеличение контраста на снижение (и наоборот) - впрочем, мне это особо и не нужно было, снижать контраст в целевом применении не нужно никогда (крайний случай - оставить все как есть, а это логистическая функция может).

Но праздновать завершение работы оказалось рано: сгенерированный код упрямо рисовал график, снижающий контраст вместо его увеличения. Когда я предъявил эту претензию ChatGPT - он извинился, и с каждым разом выдавал все более и более поломанный код. Просто изменить параметр кривой оказалось невозможно т.к. формула недостаточно универсальная. Что-ж, похоже тут с ChatGPT ничего не получится - но это и не конец света. В конечном итоге, границы применимости LLM известны, и чем более узкая сфера - тем проще за них выйти. Но история тут не заканчивается.

Графики вариантов S-кривых для увеличения контраста
Графики вариантов S-кривых для увеличения контраста

Для справки, вот исходный (наилучший) вариант от ChatGPT (можно потренироваться и найти тут ошибки):

import numpy as np
import matplotlib.pyplot as plt

def create_s_curve_lut():
    # Define parameters for the sigmoid curve
    a = 10.0  # Adjust this parameter to control the curve's shape
    b = 127.5  # Midpoint of the curve (127.5 for 8-bit grayscale)

    # Create the S-curve LUT using the sigmoid function
    lut = np.arange(256)
    lut = 255 / (1 + np.exp(-a * (lut - b) / 255))

    # Normalize the LUT to the 0-255 range
    lut = (lut - np.min(lut)) / (np.max(lut) - np.min(lut)) * 255

    return lut.astype(np.uint8)

# Create the S-curve LUT
s_curve_lut = create_s_curve_lut()

# Plot the S-curve for visualization
plt.plot(s_curve_lut, range(256))
plt.xlabel("Input Values (0-255)")
plt.ylabel("Output Values (0-255)")
plt.title("S-curve Contrast Enhancement LUT")
plt.show()

# You can access the S-curve LUT with s_curve_lut

Не сумев добится нужной формы кривой я поставил крест на LUT от ChatGPT и переделал (если так можно говорить про пару строчек кода из google) используя регуляризованную неполную бета-функцию. Покрутил параметры a=b пока не получил на графике кривую по вкусу (аналогично тому, что выставляю обычно руками в графическом редакторе) и наконец применил LUT на тестовое изображение используя в OpenCV. К моему полному удивлению, функция уменьшила контраст, а не увеличила его. Как так?

Медитирование не позволило быстро найти ошибку. Я написал тестовый кусочно-линейный LUT для увеличения контраста - и на изображении он дал ожидаемый результат. Лишь добавив кусочно-линейный LUT на график - корень проблемы стал виден: когда я выкинул функцию генерации S-curve LUT от ChatGPT, я оставил код рисования графика. Там ChatGPT старательно напечатал заголовок графика и названия осей.. но сделал конкретную подставу используя данные оси X - в Y, и наоборот. Т.к. параметры plt.plot используются без имени - не используя регулярно / не помня порядок параметров человеку очень легко тут не заметить ошибку.

Таким образом, когда я настраивал фактор формы кривой - я настраивал его на перевернутом графике, и сделал его уменьшающим контраст. Когда я обвинял ChatGPT в том, что он неправильную формулу мне сделал - и он соглашаясь со мной судорожно пытался что-то исправить - у него не было шансов. Т.к. формула была правильная, а ошибка была в отображении графика. Конечно, если ChatGPT указать на ошибку в выводе графика - он радостно соглашается и исправляет её (но так я и сам могу). Это подстава уровня #define true false на компьютерах общего пользования.

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

Посмотреть код ошибки
plt.plot(s_curve_lut, range(256)) #It's a TRAP!
plt.plot(range(256), s_curve_lut) #This is correct

Но и это оказался не конец: Если взглянуть на график - бросается в глаза легкая асимметричность кривой GPT-TRAP в районе 255. Это банальная ошибка округления : вычисленное вещественное число результата просто приводят к uint8 (=отбрасывают дробную часть), а значит результат (и яркость изображения) будет в среднем на 0.5 единицы / 0.25% меньше, а пиксели с полной яркостью (255) будут намного более редкими. Интересной эту ошибку делает то, что она есть в коде, сгенерированной и ChatGPT, и Bing Copilot и Google Bard. Т.е. видимо такой код очень распространен в тренировочных данных и все модели решили что "умножить на 255 и привести к uint8" - это успех. Технически конечно в диапазон мы попали, но результат не безупречен.

Посмотреть код ошибки
#Rounding error, fractional part is discarded
lut = (lut - np.min(lut)) / (np.max(lut) - np.min(lut)) * 255 

#This is correct
lut = np.round((lut - np.min(lut)) / (np.max(lut) - np.min(lut)) * 255) 

Выводы:

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

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

  • Если получаем нерабочий результат - зачастую проще спросить несколько разных моделей и сравнить результаты : сейчас в дополнение к ChatGPT (3.5/4) есть Copilot, Bard, Replit и другие. Никто из них не выдал идеальный код с первой попытки, но по этому пути мне не пришлось бы залипать с графиком.

  • Некоторые ошибки - могут быть системными для многих языковых моделей, видимо унаследованные из частично пересекающегося набора данных для обучения, где эти ошибки были широко представлены (т.к. языковые модели на текущий момент доверяют примерам для обучения безусловно, в отличие от людей). Т.е. модели пока не могут превзойти по качеству данные для обучения. Непонятно, сколько работы еще предстоит чтобы "превзойти учителя". Может так оказаться, что это тот случай когда 10% работы занимают 90% времени. Но прогресс в последние 3 года движется стремительно, возможны и сюрпризы.

Комментарии (33)


  1. ru1z
    22.10.2023 19:03
    +2

    пару строчек кода из google

    А те модели, которые полу-поисковики, вроде пфинда и перплексити, дают лучший ответ или поиск в этих случаях не помогает?

    upd - сам нашел ответ в тексте

    > Интересной эту ошибку делает то, что она есть в коде, сгенерированной и ChatGPT, и *Bing* Copilot и Google *Bard*. Т.е. видимо такой код очень распространен в тренировочных данных


    1. BarsMonster Автор
      22.10.2023 19:03
      +1

      В статье ответ не настолько универсальный.
      Perplexity единственный осилил корректное округление. Phind включил GPT-4 и написал кучу кода, который может быть правильным в плане округления.

      Оси не путал никто, это я думаю мне не повезло сильно с первым вариантом.


  1. vmkazakoff
    22.10.2023 19:03
    +26

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

    Ошибка два: продолжали диалог при том что в ответе были ошибки. ИИ это не совсем "ИИ", он просто ищет самое подходящее следующее слово исходя из контекста. Очевидно, что контекст у него - весь диалог. Если в диалоге есть ошибка - она попадет в контекст и будет влиять на ответ. Надо начать новый диалог или вернулся на пару шагов назвать и перегенерить ответы. Но продолжать диалог с ошибкой - плохо.

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

    Ошибка три: использовать чат гпт для кода, но тут я надеюсь, что просто не уточнили, а использовали всё-таки специализированные модели.


    1. Hardcoin
      22.10.2023 19:03
      +8

      Никогда, вот вообще никогда не пытайтесь просить ИИ исправить неконкретную ошибку.

      А вот зря. Он хорошо ищет ошибки в своем собственном ответе даже без подсказок. Конечно не всегда работает, но часто.


      1. zartdinov
        22.10.2023 19:03
        +2

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


        1. Hardcoin
          22.10.2023 19:03

          Согласен. Но иногда даже этого не требуется.


    1. smind
      22.10.2023 19:03

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


      1. danilovmy
        22.10.2023 19:03
        +3

        Вчера была статья новость про chatgpt и dalee, неявно подтверждающая, что текст капсом имеет приоритет.


    1. ixsi
      22.10.2023 19:03
      +2

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


      1. a-cherepanov
        22.10.2023 19:03
        +1

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


    1. Fell-x27
      22.10.2023 19:03

      Ошибка раз: пытались доказать что-то ИИ. Оно слишком исполнительное, чтобы такой сценарий имел смысл. Оно поверит, что земля плоская.

      Ну нет, не поверит. В платной версии можно настраивать его поведение, давать мета-указания, которые будут приниматься во внимание всегда и будут сохранены в профиле. Первым делом я написал там, чтобы он не стеснялся настаивать на фактах и спорить со мной, если я не прав. Пригодилось уже кучу раз. Вот примеры такого поведения: https://chat.openai.com/share/5641354a-075b-4168-93cf-fe6aef890a0c
      https://chat.openai.com/share/13fbf934-5489-447a-8a8d-e03fa2645dc4

      Но даже и без этих инструкций chatGPT уже не настолько наивный, как раньше. Даже V3.5 заставить перекинуть здравый смысл через колено - уже не так просто, как когда-то.


  1. vagon333
    22.10.2023 19:03
    +1


    Каждой задаче свой инструмент.

    При желании, можно и за неделю осилить

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

    В силу своих задач использую GPT4 в многошаговых API вызовах.
    При нулевой температуре и грамотных инструкциях (prompt) получаю рабочие результаты без необходимости правки - только review/approve. Экономит массу времени/денег.


    1. BarsMonster Автор
      22.10.2023 19:03
      +1

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


    1. Deirel
      22.10.2023 19:03

      Интересно! А можете, пожалуйста, подробнее рассказать, как вы используете GPT4, какими инструментами пользуетесь?


      1. smind
        22.10.2023 19:03
        +1

        как например я использую:

        все xml комментарии в коде генерю через chtgpt, многие модели или dto через него же, интерфейсы для сервисов, реализации сервисов (потом допиливаю), linq с инклюдами. наборы тестовых данных.


  1. RichardMerlock
    22.10.2023 19:03
    +1

    Протестировал на 2х литкодовских зачадах - Easy и Hard выбрав наугад. На питоне генерирует правильно сразу, на С++ пришлось исправить int на long, чтобы из диапазона не вываливаться. Слава роботам! Копипастил долже, чем решал.


    1. ris58h
      22.10.2023 19:03
      +16

      Есть ощущение, что модель на этих задачах и тренеровали, в том числе.


      1. axifive
        22.10.2023 19:03

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


      1. aozeritsky
        22.10.2023 19:03

        Я ради интереса пробовал задачи с codeforces скармливать. Правильного решения удалось добиваться всегда только после кучи уточняющих вопросов, задать которые можно только если ты уже знаешь как решить задачу. Leetcode действительно решает лучше, но все равно быстрее закодить самому. Проверял на ChatGPT 3.5. Может быть 4я версия работает лучше.


  1. Lukerman
    22.10.2023 19:03
    +2

    Простите ))) не удержался. Вроде избитая тема ! На чем она там тренируется интересно.


  1. ZlodeiBaal
    22.10.2023 19:03
    +1

    Я как-то из любопытства попробовал из LLM моделек преобразование фурье получить (на питоне без готовых FFT библиотек).
    Варианты были разного уровня ржачности - https://medium.com/p/b11fc5f12f75


  1. dlinyj
    22.10.2023 19:03
    +2

    С возвращением, как мы долго ждали статей от вас :).


  1. MaFrance351
    22.10.2023 19:03
    +3

    Давным-давно читал ваши статьи, очень рад, что вы снова начали писать!


  1. nikolz
    22.10.2023 19:03

    Перефразируя Сократа , можно сказать:

    Не каждый ... может задать такой вопрос, что даже GPT4 не сможет на него ответить.

    ------------------------

    Возможно, что ответ на данный вопрос не присутствует в интернете, поэтому GPT4 не нашел решения.


  1. Rampages
    22.10.2023 19:03
    +1

    ChatGPT довольно часто ошибается в каких-то тривиальных задачах бывает, то есть ты ждешь что будет какое-то верное решение на выходе после не самого профессионального prompt, но на деле получаешь скомпилированную кашу ) причем если человек не разбирается в этой "каше", то заметить подвох крайне трудно, а иногда банальный вопрос о точности ответа заставляет ChatGPT переписать весь ответ(!).

    Может есть какой-то prompt повышающий качество ответов? ну то есть чтобы ChatGPT не использовал непроверенные данные из интернета без доказательной базы?

    то есть даже если ответ верный, то если переспросить может быть вот так.
    то есть даже если ответ верный, то если переспросить может быть вот так.
    Ну и это уже почти Classic
    можно еще применить к скаффолдингу
    можно еще применить к скаффолдингу


    1. Opaspap
      22.10.2023 19:03

      По своей области дополняете личную инструкцию, вроде "используй ядро линукс 6.x, 2.x нельзя"


  1. Refridgerator
    22.10.2023 19:03
    +3

    В своё время таких функций я наделал миллиард (и даже статью пытался писать), например:

    \frac{(1+x)^n-(1-x)^n}{(1-x)^n+(1+x)^n}

    Диапазон аргумента/значений -1..1, обратной функцией является та же, но с 1/n вместо n.


  1. pocheketa
    22.10.2023 19:03
    +1

    Взглянув на график - бросается в глаза # классика: "проезжая мимо станции, с меня слетела шляпа"
    Если взглянуть на график - бросается в глаза # This is correct
    Взглянув на график - мы увидим # This is correct


  1. Opaspap
    22.10.2023 19:03
    +2

    Когда уже этот парад "я не умею пользоваться штангенциркулем" закончится ?


  1. cijic
    22.10.2023 19:03

    Здравствуйте.

    Вы не пробовали другие LLM? В частности, Bard от Google.


    1. BarsMonster Автор
      22.10.2023 19:03

      Да, там в конце есть его упоминание. Оси не перепутал больше никто. А вот с округлением ошибка есть почти у всех.


    1. nochkin
      22.10.2023 19:03

      Как-то спросил я у Bard'a код для инициализации какого-то там контроллера LCD SSD2828. Надеялся увидеть команды инициализации со всеми параметрами настройки. Но в результате получил фактически нечто однострочное типа такого:

      init_ssd2828();

      Тот же ChatGPT мне выдал с десяток команд для начальной инициализации контроллера. Правда, команды были не по теме, но это уже мелочи.


  1. fieldof
    22.10.2023 19:03
    +1

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

    Надеюсь этим уже занимаются разработчики всяких копайлотов и чатжпт. А если устраиваеть соревы между нейросетями или ветвями одной как было с Go.. Кажется, это дело 3-10 лет чтобы научить НС кодить лучше 99% синьоров если добавить щепотку практики.