Telegram Web Link
Forwarded from Архив КС/РФ(Сиона-Футуриста) (Красный)
Последние годы интеллектуальные системы, основанные на машинном обучении были на пике хайпа. Как правило, именно их имеют ввиду, когда говорят об ИИ. Для пользователя, пользующегося умным программным продуктом, разницы между экспертными системами, построенными на основе базы знаний или же обработки бигдаты нет никакой. При этом, "под капотом" она принципиальна.

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

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

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

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

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

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

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

Так что будущее мне видится в слиянии двух подходов — человеческого и машинного.

Eshu Marabo
Весь вечер гоняю замеры скорости для диссертационного проекта. Пока складывается ощущение, что я попросту ошибся с языком: самая вычислительно сложная часть, сделанная в виде копипасты куска кода на С, работает быстрее примитивнейших операций, написанных на С#.

Постараюсь выжать из шарпа по-максимуму, но пока вдалеке мне видится кошмарная глыба С++ надвигающаяся на меня.
Эшу быдлокодит pinned «Создал небольшой дневничок. Тут будет IT, немного науки и что-то из жизни препода. А также репосты понравившихся новостей. Политоты не будет. Кратко обо мне. Один из авторов канала @rufuturism, программист, препод в одном из средних московских ВУЗов на 0.1…»
О пользе нормального DevOps, точнее о вреде его отсутствия.

Мне нужно было внести мизерную правку в моих ботов: добавить логику обработки пересланных в бота для обратной связи сообщений.

Если сообщение - пересланное (т.е. свойство ForwardFrom у него не пустое), вызываем функцию пересылки и пересылаем его. Добавил минуты за полторы. А потом началось веселье. Мои боты стоят на линукс сервере, там же PostgreSQL, к которой они цепляются. Ботов, которыми пользуются люди, как бы "прод", я обновляю простеньким скриптом для командной строки на 20 строчек.

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

И вот нашелся скрипт и обновления и фиксы стали накатываться сразу после проверки локально. А не поленился бы я научиться настраивать CD/CI - например Github Actions - проблем бы не было вообще: все проверки и автодеплой запускались бы из моего аккаунта на Github.
Немного погрузился по работе в малость подзабытые нейросети. Оказалось, что за два года, которые прошли с момента, когда я изучал их, мои знания малость протухли.

Появилась новаях архитектура сетей - transformer. Буду разбираться.

Я конечно знаю, что IT развивается стремительно, но не настолько же. Как калейдоскоп фреймворков на js для фронтэнда блин.
Forwarded from Архив КС/РФ(Сиона-Футуриста) (Красный)
​​Язык машины

Мы продолжаем писать о практических применениях машинного обучения и том, что скрыто под его "капотом".

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

Всё это относится к огромной дисциплине NLP Это natural language processing, то есть "обработка естественного языка", а вовсе не псевдонаучное "нейролингвистическое программирование".

NLP появилось примерно тогда же, когда первые ЭВМ: очень заманчиво отдавать команды компьютеру на родном языке. Даже в те лохматые времена уже были первые "алисы", способные корректно обработать абстракции и нелогичности в нашей речи. Однако, катастрофически не хватало вычислительных мощностей и математического аппарата, равно как его общедоступных реализаций.

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

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

Большой прорыв случился в 2013 году, когда никому неизвестный на тот момент чешский аспирант Томаш Миколов предложил новый подход к представлению слов в численном виде: учитывать не только значение самого слова, но и набор ближайших к нему слов. Мы видим к чему это привело через семь лет.

Приведенные к численным значениям слова уже доступны для обработки нейросетями. Кроме того, доступны большие наборы данных как текстов, так и "оцифрованных" словарей. Так, по ссылке доступно для свободного скачивания 150 Гб русскоязычных текстов и 14 Гб уже готовой к использованию "оцифровки".

Для применения в каких-либо "общеязыковых" задачах и анализу текста на русском литературном языке всё готово. Открываем Google Colaboratory, скачиваем датасеты, открываем хабр и чувствуем себя настоящим специалистом по данным. А вот небольшой шажок в сторону — например анализ специфического сленга или терминов потребует существенно больше усилий.

Eshu Marabo
Эшу быдлокодит
Весь вечер гоняю замеры скорости для диссертационного проекта. Пока складывается ощущение, что я попросту ошибся с языком: самая вычислительно сложная часть, сделанная в виде копипасты куска кода на С, работает быстрее примитивнейших операций, написанных на…
Ну чтож, продолжаю тему производительности диссертационного проекта.

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

Пока потолок - около 2-4 FPS на приличном компьютере. Цель - 25.

Упёрся в узкое место: скопипащенный кусок на С отрабатывает за 0.5 секунды минимум, а применять его нужно к каждой картинке.

Вывод: параллелить, а то и вообще выносить вычисления на видеокарту. На С я пока не готов к таким подвигам, потому для начала реализую алгоритм на c#, оптимизирую по максимуму и посмотрим, нужно ли будет что-то менять.

Соответственно, в следующем сообщении выложу статью с описанием алгоритма.

#диссер
#csharp
Forwarded from Sci-Hub
[email protected]
2.3 MB
Herráez, M. A., Burton, D. R., Lalor, M. J., & Gdeisat, M. A. (2002). Fast two-dimensional phase-unwrapping algorithm based on sorting by reliability following a noncontinuous path. Applied Optics, 41(35), 7437. doi:10.1364/ao.41.007437
Эшу быдлокодит
Ну чтож, продолжаю тему производительности диссертационного проекта. Я пишу программу для записи изображений с микроскопа. Цель - иметь возможность писать поток в 2 мегапикселя в реальном времени (захват изображения камерой, несложные математические преобразования…
Нас ждёт увлекательное путешествие в мир векторных инструкций (SIMD, возможно - вставок ассемблера в С#, или, как крайняя мера - знакомство с CUDA или OpenGL).

Будет весело и страшно больно и познавательно, не переключайтесь.
Media is too big
VIEW IN TELEGRAM
Впервые за долгое время наблюдал сегодня занятное физическое явление: переохлажденную жидкость. Вода (сенежская) стояла на неотапливаемом крыльце. Берешь бутылку - жидкая. Заносишь в дом, вроде бы в тепло. Но малейшее механическое воздействие заставляет воду в бутылке превратиться в ледяную кашу. На видео - пример превращения.

P.S. Адские звуки на фоне - это кот, а не кристаллизация воды в бутылке.
Реализовал алгоритм из научной статьи на c#. Получилось далеко не сразу: на первый взгляд адекватное описание в статье оказалось сложнореализуемым и несколько расходилось с кодом, выложенным на гитхабе.

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

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

Видимо, придется создавать все объекты, используемые мной, при старте программы и в процессе просто модифицировать их. Кроме того, предстоят эксперименты с сортировкой.
В оптимизации процедуры развертки фазы для микроскопа ч дошел до предела, который позволяет c# без использования магии: проигрыш в 2.7 раз относительно чистого с.

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

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

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

С# в любом случае несет какие-то накладные расходы на функции, взятые из CLR (виртуальная машина платформы .Net). Кроме того, в C почти все манипуляции в коде осуществляются на уровне указателей.

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

У меня остается узкое место - сортировка здоровенного одномерного массива (примерно 4 млн элементов). Изначально, как в реализации на С, так и в методе, предлагаемым в для сортировки в С# используется алгоритм быстрой сортировки (quicksort), как один из наиболее шустрых. У меня на сортировку массива уходит до 40% всего времени.

Пришло время заменить его на хорошо распараллеливаемый алгоритм сортировки слиянием и начать распараллеливать вообще всё.

#csharp #диссер
Forwarded from Архив КС/РФ(Сиона-Футуриста) (Футуристъ)
Одна из важнейших научных новостей конца года - принято решение о слиянии двух ключевых фондов, осуществляющих финансирование российской науки: РНФ (Российский научный фонд) и РФФИ (Российский фонд фундаментальных исследований). Решение получило, мягко говоря, противоречивую оценку от научного сообщества.

Опишу в двух словах, как работает финансирование российской науки. Деньги могут прийти или от организации, в которой работают ученые, или от отраслевого министерства (Минсельхоз, Минобрауки, Минздрав) или от федерального фонда — РНФ или РФФИ. Деньгами на науку могут распоряжаться и другие организации, но на фоне вышеназванных это мелочи.

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

РНФ — только крутые команды, ценз на набор публикаций, необходимых для подачи заявки и отчетность, там совершенно конский. И только РФФИ занимается сбросом небольших "вертолетных" денег на российскую науку. Гранты у РФФИ небольшие, их не хватает на полноценное содержание научного коллектива и проведение исследований. Но получить их относительно просто, чтобы отчитаться достаточно просто что-то делать, прорывных успехов они не требуют.

Именно РФФИ позволяет не разбежаться коллективам, которые по каким-то причинам остались без постоянного источника денег. При слиянии обещают сохранить всё лучшее из того, что было, но зачем трогать то, что прекрасно работает и выполняет свою роль, сложившуюся исторически? Да и сомнительно, чтобы сброс "вертолетных денег" на науку относился к лучшим практикам по мнению министерства.

Eshu Marabo
Начал оптимизировать сортировку в своем диссертационном проекте, всплыла прекрасная иллюстрация такого понятия как вычислительная сложность алгоритма.

Тестовый массив - 4 миллиона элементов (классов, содержащих поле типа double, по которому и осуществляется сортировка).

Проверил четыре варианта сортировки массива:
1. Стандартный метод Array.Sort, предоставляемый c# из коробки (под капотом там quicksort O(n*log(n)), как писал выше). Результат - 2.2 секунды
2. Нагугленная реализация quicksort O(n*log(n)) для c#. Результат - 2.7 секунды
3. Нагугленная реализация сортировки вставками O(n^2) . Результат - бесконечность, за 45 минут не отсортировалась даже половина массива, я остановил тест.
4. Нагугленная реализация сортировки слиянием mergesort O(n*log(n)). Результат 4.08 секунды.

Уже из этих цифр видно различия в вычислительной сложности: n^2 по сравнению с n*log(n) начинает проигрывать просто феерически. И да, такой массив - это обыденность: по объему данных это примерно две картинки в full hd.

Выигрыш метода Array.Sort у простой реализации быстрой сортировки "в лоб" заслуживает отдельного внимания, обязательно залезу в исходный код .Net Core и расскажу чем он отличается.

#csharp #диссер
Продолжаю про оптимизацию сортировки массива в диссертационном проекте.

Более-менее успешно распараллелил сортировку: использовал нечто гибридное. Массив разделяется на несколько частей, каждая сортируется параллельно, после чего сливаются во едино функцией Merge из реализации сортировки слиянием из прошлого поста (п. 4).

Результаты меня несколько огорчили. Рост про производительности бесспорно есть. Время обработки сократилось с 2.2 секунд до 1.5 с использованием двух потоков. При этом, с ростом числа потоков, скорость растет на какие-то смешные значения, а то и падает за счёт того, что приходится ждать запаздывающие потоки.

Фантастический сюрприз поджидал меня далее. Я сортирую массив объектов по одному из полей с типом double. При этом используется стандартный инструмент для сравнения пользовательских типов данных внутри метода Array.Sort - реализация интерфейса IComparer. По сути, в сортировку передается функция, с помощью которой можно сравнивать экземпляры сортируемых классов.

Я решил посмотреть, сколько будет сортироваться массив моего размера (4млн) double. 0.08 секунды, почти в 25(!) раз быстрее. Теперь думаю, как по-ловчее перевести алгоритм на такую сортировку.

#csharp
Эшу быдлокодит
Продолжаю про оптимизацию сортировки массива в диссертационном проекте. Более-менее успешно распараллелил сортировку: использовал нечто гибридное. Массив разделяется на несколько частей, каждая сортируется параллельно, после чего сливаются во едино функцией…
Небольшое уточнение к прошлому посту. В мои замеры прокралась ошибка, на самом деле среднее время сортировки массива из double-ов составляет 0.37 секунды.

Несмотря на это, шестикратная разница в скорости - это тоже неплохо.

Кроме того, у метода Array.Sort есть перегрузка, которая предлагает сортировать один массив относительно другого. Замерял её производительность, вынеся поле, по которому сортирую в отдельный массив. Результат - 1.1 секунды. Т.е. простой вынос поля, по которому осуществляется сортировка в отдельный массив и отказ от использования реализации IComparer там, где это не нужно, уже дает двукратный рост производительности.

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

#csharp
Forwarded from Алексей Кутепов | Java-developer (Alexey Kutepov)
Forwarded from Data is data
с новым годом :)
Итого подошла к концу эпопея с оптимизацией реализации алгоритма развертки фазы, написанного на с#. В качестве эталона используется реализация на чистом С, скопированная из репозитория библиотеки sklearn-image.

Итог оптимизации: производительность на С и С# практически сравнялась, теперь я отстаю примерно на
20% вместо 400% в начале пути.

Произведенные манипуляции:
1. Обновление классов вместо их пересоздания. Подробнее - тут

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

3. Правильное использование сортировки. Узким местом в алгоритме являлась сортировка массива, размером равного удвоенному числу пикселей.

После долгих экспериментов с сортировкой, я сделал две вещи:
А) вынес поле сортируемых классов в отдельных массив и использовал сорировку "по ключу" - т.е. сортировал один массив по данным из другого.
Б) Раскопав код коробочного метода сортировки я обнаружил, что он отлично работает на массивах с повторяющимися значениями. Потому я округлил используемый мной параметр до третьего знака (задача позволяет), в результате чего выгадал ещё процентов 30 скорости сортировки. Про эту реализацию Быстрой сортировки напишу отдельно.

Итого, я разогнал FPS своего приложения до 8 на 2 мега пикселях. Немного поколдовать над интеграцией с Arduino и им можно пользоваться. SIMD и другие оптимизационные шаманства оказались неприменимы, единственное, откуда я могу получить рост производительности - распараллеливание.

Я уже получил levelup и кучу экспиренса, но задача - преобразование картинки в реальном времени - не решена. Я алгоритм конечно распараллелю, но появилась новая вводная - 5 мегапикселей, потому следующий большой пункт назначения - CUDA.

#csharp #диссер
Обещанный пост о вариации быстрой сортировки, использующейся в c# в коробочном методе Array.Sort.

Суть алгоритма заключается в следующем: Берется опорный элемент, примерно по середине массива. Элементы, большие него помещаются справа от него, меньшие - слева.

Над половинками рекурсивно проводится та же операция, до тех пор, пока массив не отсортируется.

Нашел реализацию в репозитории Майкрософт с прошлой версией .Net. Ниже прикладываю вырванный оттуда рабочий кусок кода.

На первый взгляд он выглядит диковато: каскад из двух операторов do... while и двух простых while являются антитезой понятия "читаемый и понятный код".

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

Программисты Microsoft таки едят хлеб недаром.

#csharp
2025/07/09 20:17:02
Back to Top
HTML Embed Code: