Все мы видели много статей, где с помощью AI-инструментов за минуты выполняется работа, на которую раньше мог легко уйти день. Особенно впечатляют примеры, где работа (успешно) идет вне зоны компетенции человека (т.е. когда AI позволяет делать то, что человек в принципе один сделать не мог бы). Но сегодня у меня получился несколько другой случай:
Задача стояла относительно тривиальная: нужно было сгенерировать look-up table (LUT) для по-канального увеличения контраста изображения (S-кривая), и применить эту кривую на фотографии с USB-камеры микроскопа. Берем ChatGPT (даже 3.5 должен прокатить, тут всего-то одна формула), за 10 секунд получаем Python-код типичной S-кривой (также ChatGPT для моего удобства сразу добавил отрисовку графика через matplotlib), настраиваем параметр "кривизны" кривой по вкусу - и можно вставлять в финальное приложение. Среди множества S-кривых/сигмоид ChatGPT использовал "логистическую функцию" - она одна из наиболее простых. Но у неё есть и недостаток - параметром "кривизны" нельзя сменить увеличение контраста на снижение (и наоборот) - впрочем, мне это особо и не нужно было, снижать контраст в целевом применении не нужно никогда (крайний случай - оставить все как есть, а это логистическая функция может).
Но праздновать завершение работы оказалось рано: сгенерированный код упрямо рисовал график, снижающий контраст вместо его увеличения. Когда я предъявил эту претензию ChatGPT - он извинился, и с каждым разом выдавал все более и более поломанный код. Просто изменить параметр кривой оказалось невозможно т.к. формула недостаточно универсальная. Что-ж, похоже тут с ChatGPT ничего не получится - но это и не конец света. В конечном итоге, границы применимости LLM известны, и чем более узкая сфера - тем проще за них выйти. Но история тут не заканчивается.
Для справки, вот исходный (наилучший) вариант от 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)
vmkazakoff
22.10.2023 19:03+26Ошибка раз: пытались доказать что-то ИИ. Оно слишком исполнительное, чтобы такой сценарий имел смысл. Оно поверит, что земля плоская. Никогда, вот вообще никогда не пытайтесь просить ИИ исправить неконкретную ошибку. Он прилетает ошибку на ровном месте там где не могло и не быть, просто чтобы услужить вам. В вашем случае надо было просто сгенерить код ещё один или два раза заново. Скорее всего выдал бы годный вариант. В чатегпт для этого далее есть кнопка регенерейт, поверьте, она не просто так там есть.
Ошибка два: продолжали диалог при том что в ответе были ошибки. ИИ это не совсем "ИИ", он просто ищет самое подходящее следующее слово исходя из контекста. Очевидно, что контекст у него - весь диалог. Если в диалоге есть ошибка - она попадет в контекст и будет влиять на ответ. Надо начать новый диалог или вернулся на пару шагов назвать и перегенерить ответы. Но продолжать диалог с ошибкой - плохо.
Оффтоп, но если уж надо найти ошибку в коде, то лучше попросить найти "все возможные и вероятные ошибки и вывести их в виде списка с описанием и водными деталями", а потом давать проверять каждую из них как отдельное задание. Но для такого надо как минимум хоть примерно понимать как должен бы работать код, в вашем случае это не проблема, но вообще это важно учитывать.
Ошибка три: использовать чат гпт для кода, но тут я надеюсь, что просто не уточнили, а использовали всё-таки специализированные модели.
Hardcoin
22.10.2023 19:03+8Никогда, вот вообще никогда не пытайтесь просить ИИ исправить неконкретную ошибку.
А вот зря. Он хорошо ищет ошибки в своем собственном ответе даже без подсказок. Конечно не всегда работает, но часто.
smind
22.10.2023 19:03подтверждаю, правильные и годные советы, к сказанному вами я использую время от времени подход псевдо-эмоциональных сообщений, мне кажется в ChatGPT есть обработка написанных капсом сообщений. доказать не могу но как будто бы это работает.
danilovmy
22.10.2023 19:03+3Вчера была статья новость про chatgpt и dalee, неявно подтверждающая, что текст капсом имеет приоритет.
ixsi
22.10.2023 19:03+2Ваши утверждения верны, но противоречат рекламным слоганам корп, про ИИ. Мне обещают простое общение, в ходе которого я получу желаемое, а не приседания, как лучше избегать проблемных мест.
a-cherepanov
22.10.2023 19:03+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 заставить перекинуть здравый смысл через колено - уже не так просто, как когда-то.
vagon333
22.10.2023 19:03+1
Каждой задаче свой инструмент.При желании, можно и за неделю осилить
Мне кажется, автор поставил задачу, для которой GPT не совсем подходит.
Претензии что фиксы не работают могут быть неверным описанием проблемы для исправления.
Иногда нужно не код ошибки передавать, а слегка изменить задачу, или вообще начать сначала.
В Chat режиме для генерации кусков кода так и поступаю.
В силу своих задач использую GPT4 в многошаговых API вызовах.
При нулевой температуре и грамотных инструкциях (prompt) получаю рабочие результаты без необходимости правки - только review/approve. Экономит массу времени/денег.BarsMonster Автор
22.10.2023 19:03+1Все так - ошибка на которую ушло основное время (с перепутанными осями) - даже в той же модели была случайностью. Потому подход "не залипать, перегенерировать там же или в другой модели" - самый эффективный по времени.
Deirel
22.10.2023 19:03Интересно! А можете, пожалуйста, подробнее рассказать, как вы используете GPT4, какими инструментами пользуетесь?
smind
22.10.2023 19:03+1как например я использую:
все xml комментарии в коде генерю через chtgpt, многие модели или dto через него же, интерфейсы для сервисов, реализации сервисов (потом допиливаю), linq с инклюдами. наборы тестовых данных.
RichardMerlock
22.10.2023 19:03+1Протестировал на 2х литкодовских зачадах - Easy и Hard выбрав наугад. На питоне генерирует правильно сразу, на С++ пришлось исправить int на long, чтобы из диапазона не вываливаться. Слава роботам! Копипастил долже, чем решал.
ris58h
22.10.2023 19:03+16Есть ощущение, что модель на этих задачах и тренеровали, в том числе.
axifive
22.10.2023 19:03Так на GitHub валяется куча решений на разных языках, конечно они были в данных для обучения.
aozeritsky
22.10.2023 19:03Я ради интереса пробовал задачи с codeforces скармливать. Правильного решения удалось добиваться всегда только после кучи уточняющих вопросов, задать которые можно только если ты уже знаешь как решить задачу. Leetcode действительно решает лучше, но все равно быстрее закодить самому. Проверял на ChatGPT 3.5. Может быть 4я версия работает лучше.
Lukerman
22.10.2023 19:03+2Простите ))) не удержался. Вроде избитая тема ! На чем она там тренируется интересно.
ZlodeiBaal
22.10.2023 19:03+1Я как-то из любопытства попробовал из LLM моделек преобразование фурье получить (на питоне без готовых FFT библиотек).
Варианты были разного уровня ржачности - https://medium.com/p/b11fc5f12f75
nikolz
22.10.2023 19:03Перефразируя Сократа , можно сказать:
Не каждый ... может задать такой вопрос, что даже GPT4 не сможет на него ответить.
------------------------
Возможно, что ответ на данный вопрос не присутствует в интернете, поэтому GPT4 не нашел решения.
Rampages
22.10.2023 19:03+1ChatGPT довольно часто ошибается в каких-то тривиальных задачах бывает, то есть ты ждешь что будет какое-то верное решение на выходе после не самого профессионального prompt, но на деле получаешь скомпилированную кашу ) причем если человек не разбирается в этой "каше", то заметить подвох крайне трудно, а иногда банальный вопрос о точности ответа заставляет ChatGPT переписать весь ответ(!).
Может есть какой-то prompt повышающий качество ответов? ну то есть чтобы ChatGPT не использовал непроверенные данные из интернета без доказательной базы?
Ну и это уже почти Classic
Opaspap
22.10.2023 19:03По своей области дополняете личную инструкцию, вроде "используй ядро линукс 6.x, 2.x нельзя"
Refridgerator
22.10.2023 19:03+3В своё время таких функций я наделал миллиард (и даже статью пытался писать), например:
Диапазон аргумента/значений -1..1, обратной функцией является та же, но с 1/n вместо n.
pocheketa
22.10.2023 19:03+1Взглянув на график - бросается в глаза # классика: "проезжая мимо станции, с меня слетела шляпа"
Если взглянуть на график - бросается в глаза # This is correct
Взглянув на график - мы увидим # This is correct
cijic
22.10.2023 19:03Здравствуйте.
Вы не пробовали другие LLM? В частности, Bard от Google.
BarsMonster Автор
22.10.2023 19:03Да, там в конце есть его упоминание. Оси не перепутал больше никто. А вот с округлением ошибка есть почти у всех.
nochkin
22.10.2023 19:03Как-то спросил я у Bard'a код для инициализации какого-то там контроллера LCD SSD2828. Надеялся увидеть команды инициализации со всеми параметрами настройки. Но в результате получил фактически нечто однострочное типа такого:
init_ssd2828();
Тот же ChatGPT мне выдал с десяток команд для начальной инициализации контроллера. Правда, команды были не по теме, но это уже мелочи.
fieldof
22.10.2023 19:03+1Мне это напоминает отличника который не запрограммировал не единой строчки кода на практики, но в принципе понимает как делать. По итогу отличник который тянет уровень джуна, а всего-то надо накодить много простыней чтобы быстро во вжух моменте грейднуться до какосек-синьора.
Надеюсь этим уже занимаются разработчики всяких копайлотов и чатжпт. А если устраиваеть соревы между нейросетями или ветвями одной как было с Go.. Кажется, это дело 3-10 лет чтобы научить НС кодить лучше 99% синьоров если добавить щепотку практики.
ru1z
А те модели, которые полу-поисковики, вроде пфинда и перплексити, дают лучший ответ или поиск в этих случаях не помогает?
upd - сам нашел ответ в тексте
> Интересной эту ошибку делает то, что она есть в коде, сгенерированной и ChatGPT, и *Bing* Copilot и Google *Bard*. Т.е. видимо такой код очень распространен в тренировочных данных
BarsMonster Автор
В статье ответ не настолько универсальный.
Perplexity единственный осилил корректное округление. Phind включил GPT-4 и написал кучу кода, который может быть правильным в плане округления.
Оси не путал никто, это я думаю мне не повезло сильно с первым вариантом.