Как стать автором
Поиск
Написать публикацию
Обновить
Криптонит
Разрабатываем. Исследуем. Просвещаем
Сначала показывать

Сегодня у нас задачка с подвохом для тех, кто пишет на Java. Какой результат будет выведен в консоль? Пишите в комментариях!

import java.util.stream.Stream;
public class Main {
    public static void main(String[] args) {
        Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
        Integer result = prepareStream(stream);
        System.out.printf("Result after stream processing: %s%n", result);
    }

    private static Integer prepareStream(Stream<Integer> stream) {
        System.out.printf("Incoming stream with: %d elements%n", stream.count());
        return stream
                .map(integer -> integer++ + ++integer)
                .filter(integer -> integer % 3 == 0)
                .reduce(0, Integer::sum);
    }
}

Дальше будет решение, поэтому если не хотите спойлеров — не читайте!

.

.

.

Подвох в том, что будет выброшено исключение:

Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
 at java.base/java.util.stream.AbstractPipeline.<init>(AbstractPipeline.java:203)
 at java.base/java.util.stream.ReferencePipeline.<init>(ReferencePipeline.java:96)
 at java.base/java.util.stream.ReferencePipeline$StatelessOp.<init>(ReferencePipeline.java:800)
 at java.base/java.util.stream.ReferencePipeline$3.<init>(ReferencePipeline.java:191)
 at java.base/java.util.stream.ReferencePipeline.map(ReferencePipeline.java:190)
 at Main.prepareStream(Main.java:16)
 at Main.main(Main.java:7)

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

System.out.printf("Incoming stream with: %d elements%n", stream.count());

Ну а после того, как мы избавимся от лога, который нам все ломает, правильный ответ будет — 18.

С учетом postfix и prefix инкремента числа в каждой итерации мы получаем:
.map(1 → 1 + 3)...(5 → 5 + 7)

Потом после фильтрации по делению на 3 без остатка в стриме остаются числа 6 и 12. И при помощи операции reduce() находим сумму этих чисел.

Теги:
-1
Комментарии0

Система искусственного интеллекта AlphaEvolve, разработанная в подразделении Google DeepMind, побила рекорд немецкого математика Фолькера Штрассена.

Ещё в 1969 году Штрассен разработал алгоритм умножения комплексных матриц 4×4, который требует 49 скалярных умножений. До настоящего времени этот результат был непревзойдённым.

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

AlphaEvolve — инновационная система, которая меняет подход к разработке алгоритмов. Эта AI-платформа, основанная на языковых моделях Gemini, сочетает генеративные способности с эволюционным подходом, позволяя автономно создавать и оптимизировать алгоритмы. Она уже доказала свою эффективность, улучшив работу дата-центров Google, ускорив обучение ИИ, а также решив сложные математические задачи.

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

Сгенерированные алгоритмы проходят автоматическую оценку по заданным метрикам, что минимизирует ошибки и галлюцинации, характерные для обычных языковых моделей. Эволюционный цикл — генерация, тестирование, отбор лучших решений — позволяет находить оптимальные алгоритмы за считанные часы вместо дней и даже недель. Это отличает AlphaEvolve от узкоспециализированных предшественников, таких как AlphaFold или AlphaTensor.

AlphaEvolve увеличила эффективность Google Borg (внутренней системы управления кластерами в дата-центрах) на 0,7%. Кажется немного, но это достигнуто на уже глубоко оптимизированной платформе и высвободило сотни серверов.

Из 50+ открытых задач в математическом анализе, геометрии и комбинаторике AlphaEvolve воспроизвела лучшие решения в 75% случаев и улучшила их в 20% случаев.

Сейчас AlphaEvolve оптимизирует системы-на-кристалле Tensor и улучшает код на Verilog (языке для описания и моделирования электронных систем). Помимо ИТ, потенциал системы охватывает такие сложные дисциплины, как материаловедение, фармацевтику и биохимию. DeepMind планирует открыть ранний доступ к AlphaEvolve для исследователей.

Но в ИТ-компании "Криптонит" уверены, что настоящих исследователей нейросети не заменят, они им помогут стать ещё эффективнее.

"Нужно самому достаточно хорошо разбираться в математике, чтобы сформулировать математическую задачу для ИИ, а затем проверить сгенерированное им решение. Если бы у Фолькера Штрассена в конце 60-х был ИИ, он бы наверняка решил с его помощью ещё несколько математических задач, считавшихся в то время непомерно сложными", — пояснила естественная нейросеть пресс-служба ИТ-компании "Криптонит".

Подробнее: White paper AlphaEvolve

Теги:
+3
Комментарии0

Мои коллеги по ИТ-компании "Криптонит" пишут на Go. Я попросила их придумать ошибку — сможете её найти? Ждём в комментариях ваши варианты.

package main

import "fmt"

type User struct {
 name string
 meta map[string]string
 }

func (u *User) SetMeta(key, value string) {
 u.meta[key] = value
 }

func main() {
 u := &User{name: "Alice"}
 u.SetMeta("role", "admin")
 fmt.Println("Meta:", u.meta)
 }

.

.

.

ОСТОРОЖНО! ДАЛЬШЕ СПОЙЛЕР

В main() мы создаём указатель на User, но не инициализируем вложенную map[string]string (Meta)

Присвоение значения через u.Meta[key] = value, вызовет панику (panic: assignment to entry in nil map), потому что u.Meta всё ещё nil, и в Go нельзя присваивать значения в nil-мапу.

Одним из вариантов было бы добавить функцию NewUser(), создавать пользователя через нее, и сразу инициализировать мапу:

 func NewUser(name string) *User {
 return &User{
 name: name,
 meta: make(map[string]string),
 }
 }

func main() {
 u := NewUser("Alice")
 u.SetMeta("role", "admin")
 fmt.Println("Meta:", u.meta)
 }

Второй вариант решения изменить SetMeta что бы инициализировать мапу, если она равна nil

 func (u *User) SetMeta(key, value string) {
 if u.meta == nil {
 u.meta = make(map[string]string)
 }
 u.meta[key] = value

Ошибку и решение нам помог составить Алексей Косов, системный инженер департамента инфраструктуры в «Криптоните». Его материал про особенности, применение, плюсы и минусы Golang можно прочитать в этой статье.

Теги:
+4
Комментарии4

Исследователи из Шанхайской лаборатории искусственного интеллекта разработали ZeroGUI — инновационный подход, который позволяет автоматизировать обучение агентов без участия человека.

Он сочетает возможности больших визуально-языковых моделей (VLM) и онлайн-обучение с подкреплением (RL).

Обучение ИИ-агентов для работы с графическими интерфейсами (GUI) традиционно требует ручной разметки данных и создания сценариев действий

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

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

Система предлагает три основных компонента:

  • Автоматическая генерация задач c помощью VLM, создающей разнообразные задания на основе текущего состояния интерфейса. Например, для Android генерируются задачи вроде настройки будильника или изменения параметров воспроизведения видео. Для повышения разнообразия VLM создаёт сразу несколько задач, включая невыполнимые, чтобы агент учился их распознавать.

  • Автоматическая оценка вознаграждения использует VLM для анализа траекторий действий агента (последовательности скриншотов) и присвоения вознаграждения (успех/неудача). Чтобы минимизировать ошибки, ZeroGUI применяет систему голосования: VLM несколько раз оценивает траекторию, а итоговое вознаграждение требует единогласного решения;

  • Двухэтапное обучение с подкреплением включает тренировку на сгенерированных задачах для формирования базовых навыков и адаптацию во время тестирования для конкретных задач.

Эксперименты на платформах OSWorld (десктоп) и AndroidLab (мобильные устройства) показали следующие результаты: ZeroGUI улучшил успех выполнения задач на 14% для модели UI-TARS-7B и на 63% для модели Aguvis-7B. Полученные результаты демонстрируют универсальность подхода для разных моделей и сред.

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

На днях в офисе я столкнулась с коллегами из направления системного программирования в «Криптоните». Они пишут на С++ — а ошибки на этом языке у нас ещё не было!

Поэтому я попросила их придумать код с ошибкой специально для Хабра — и вот что получилось!

Итак, есть ли в этом коде проблема кроме narrowing conversion? Ждём ваши варианты в комментариях.

#include <cstdint>
#include <vector>

struct Type
{
    Type(uint16_t, uint32_t = {}) 
    {}
};

int main()
{
    std::vector<Type> vector;
    std::uint32_t object_id{};

    // Есть предупреждение о narrowing conversion
    vector.insert(vector.begin(), {0, object_id}); 

    // Нет narrowing conversion
    vector.push_back({0, object_id}); 

    // Нет narrowing conversion
    vector.insert(vector.begin(), Type{0, object_id}); 
}

АККУРАТНО, ДАЛЬШЕ СПОЙЛЕР!

Проблема в том, что в строке

 vector.insert(vector.begin(), {0, object_id});

в вектор вставляется 2 элемента типа Type, а не один, как ожидает программист.

Причина в том, что метод insert у вектора имеет перегрузку (номер 5), которая вторым параметром принимает std::initializer_list. А компилятор, видя фигурные скобки в коде, в первую очередь пытается создать объект такого типа.

И тут ему это удается, потому что у конструктора Type второй параметр имеет значение по умолчанию, следовательно, Type умеет создаваться, если в конструктор передали только один аргумент. В итоге компилятор успешно создает std::initializer_list с двумя элементами типа Type.

Так как создание std::initializer_list выполняется с использованием uniform initialization, то компилятор следит за корректностью преобразований. В примере объект типа std::uint32_t передается в конструктор Type, который принимает первым параметром std::uint16_t. То есть, возникает риск потери точности (32 бита не могут поместиться в 16 бит).

Об этом компилятор и предупреждает. Вот упрощенный пример, где видим то же самое предупреждение.

Может возникнуть вопрос, почему создание Type от 0 не вызывает предупреждение, ведь 0 - это int, а он, скорее всего 32 бита и тоже не помещается в 16 бит. Но тут литерал. Компилятор видит, что 0 вмещается в 16 бит и не предупреждает. Но если поместить int в переменную, то также возникает предупреждение.

Теги:
Всего голосов 3: ↑3 и ↓0+3
Комментарии0

«Криптонит» приглашает на Spark-митап в Москве 29 мая!

Приглашаем на наш Spark-митап: обсудим кейсы, практики применения и тренды развития!

Когда и где пройдёт?
29 мая в 18:30 в Музее криптографии (https://cryptography-museum.ru/)

Кому Spark Meetup полезен?

  • инженерам данных и аналитикам данных

  • программистам со знанием Spark и Scala

  • всем смежным специальностям из телекома, банков, промышленности и ретейла

Кто будет выступать с докладами?
Эксперты из «Криптонита», Positive Technologies и М2. Программу можно посмотреть тут — https://clc.to/SparkMeetup

Как зарегистрироваться?
Вот по этой ссылке — https://clc.to/SparkMeetup

Будет ли трансляция?
Обязательно будет. Ссылку разместим позже на странице мероприятия — поэтому советуем зарегистрироваться на оффлайн-встречу, даже если вы не сможете прийти. Так вы точно не потеряете ссылку на онлайн

Нужно что-то платить?
Нет, митап бесплатный — ждём всех неравнодушных к программированию на Spark!

Зарегистрироваться — https://clc.to/SparkMeetup

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии0

Посмотрите на код ниже — где в нём проблема? Пишите ваши мысли в комментариях, а ниже мы дадим решение ошибки.

object UnitError {

def printMsg(message: String): Unit = {
 println(message)
 }

def process(data: List[Int]): List[Unit] = {
 for (element <- data) yield {
 printMsg(s"Элемент: $element")
 }
 }

def main(args: Array[String]): Unit = {
 val nums = List(1, 2, 3)
 val res = process(nums)
 println(s"Результат: $res") // Вывод List[Unit] даёт неожиданный результат
 }
 }

Дальше будет решение — если не хотите спойлеров, пролистните текст ниже.

Ошибка заключается в неверной конструкции при использовании функции process. Она возвращает пустые значения: List((), (), ()). Происходит это потому, что yield собирает результаты каждой итерации. В итоге получается список, состоящий из пустых значений Unit — по одному на каждый элемент в data.

Unit в Scala — это аналог void в Java и Си-подобных языках, означающий пустое значение. В данном примере yield собирает результаты printMsg(...), которые все являются Unit (пустыми).

Программисты, привыкшие к императивным языкам и переходящие на Scala, интуитивно ожидают, что такая конструкция будет возвращать какие-то преобразованные данные, например — как это делает map в JavaScript. То есть, начинающие скалисты могут ожидать здесь на выходе список элементов, а получат пустой вывод.

Исправление

Если требуется вернуть список преобразованных значений, тогда нужно использовать эти значения в yield.

def printMsg(message: String): String = { // Теперь возвращает String
 println(message)
 message // Возвращает саму строку
 }

def process(data: List[Int]): List[String] = { // Теперь функция возвращает List[String]
 for {
 element <- data
 } yield {
 printMsg(s"Обрабатываем элемент: $element") // Теперь выводится результат String
 }
 }
Теги:
Рейтинг0
Комментарии1

Большие языковые модели (LLM) обычно требуют мощного оборудования и потому запускаются в облачных сервисах, а без подписки их функционал ограничен. Однако Google Gemma 3 — исключение.

Google Gemma 3 — это семейство открытых моделей, некоторые из которых достаточно легковесны, что их можно использовать локально.

Модели Gemma 3 созданы на основе Gemini 2.0 и доступны в четырёх вариантах: 1B, 4B, 12B и 27B, где B — миллиарды параметров. Самая лёгкая модель 1B работает только с текстом, а все остальные — мультимодальные, то есть обрабатывают текст и картинки.

Модели на 4B, 12B и 27B параметров поддерживают более 140 языков и хорошо справляются с переводом текстов, модель на 1B параметров работает только с английским.

Главная особенность Gemma 3 — умение обрабатывать длинные запросы и анализировать объёмные документы благодаря большому контекстному окну (128K токенов для моделей 4B, 12B и 27B).

Вариант 4B особенно универсален: сжатая версия (int4) требует всего 3 ГБ видеопамяти, а несжатая версия (BF16) — около 8 ГБ VRAM, что позволяет запускать модель на видеокартах среднего класса.

Модели Gemma 3 совместимы с Windows, Linux и macOS.

  • Поддержка Apple Silicon через MLX даёт возможность запускать Gemma 3 на Mac и iPhone (инструкция).

  • Для запуска Gemma 3 можно использовать Python-библиотеку transformers (инструкция).

  • Ещё один способ установки Gemma 3 на компьютер — через фреймворк Ollama. Он прост в установке и доступен на Windows, Linux и macOS.

  • Для удобства работы с моделью можно добавить веб-интерфейс Open WebUI.

Помимо Gemma 3, для локальной установки подходят и другие облегчённые модели, но у них своя специфика:

  • Llama 3.3: требует больше ресурсов и не является полностью открытой;

  • Mistral 7B, Qwen2.5 и Phi-3 Mini: легковесны, но имеют меньшее контекстное окно;

  • DeepSeek-R1: конкурент Gemma 3 27B по качеству, но требует значительно больше ресурсов.

Теги:
Всего голосов 5: ↑5 и ↓0+8
Комментарии0

Что такое «совершенные» и «избыточные» числа? Рассказывают эксперты ИТ-компании «Криптонит».

Наверняка вы знакомы с понятием «делители числа». Например, у шестёрки кроме неё самой есть три делителя: 1, 2, и 3. Если сложить их, получится ровно шесть (1+2+3=6). Числа, у которых сумма делителей, не считая самого числа, равна самому числу, называются совершенными.

Если же сумма делителей оказывается больше самого числа, то такие числа называются избыточными. Самое малое избыточное число: 12. У него много делителей: 1, 2, 3, 4, 6. Если их сложить, получится 16, а 16 > 12.

Понятия совершенных и избыточных чисел возникли ещё в Древней Греции. Их описали пифагорейцы, заложившие основы учения о свойствах чисел и их классификации.

Какие же свойства есть у избыточных чисел?

  • 12 — наименьшее избыточное число. Проверьте сами!

  • все числа, кратные избыточному числу, также являются избыточными. Раз 12 – избыточное число, значит 24, 36, 48 и т.д. тоже будут избыточными;

  • существуют как чётные, так и нечётные избыточные числа;

  • наименьшее нечётное избыточное число – 945. Сможете ли назвать все его делители?

У совершенных чисел свойства другие:

  • все известные совершенные числа чётные;

  • возможность существования нечётных совершенных чисел не доказана и не опровергнута;

  • сумма обратных величин всех делителей совершенного числа, включая само число, всегда равна двум. Пример для обратных делителей числа 6: 1/1 + 1/2 + 1/3 + 1/6 = 2;

  • все известные совершенные числа заканчиваются на 6 или 8 (6, 28, 496 и т.д.);

  • совершенные числа используются для вычисления простых чисел Мерсенна.

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

Изучение свойств чисел помогает развивать математическое мышление, писать эффективные алгоритмы и понимать более сложные математические концепции.

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии0

Приглашаем на новую встречу «Ключ к профессии»!

В это воскресенье в 14:00 эксперты из «Криптонита» и других брендов расскажут про профессию «инженер данных»: чем занимается этот специалист, какими навыками он должен обладать и как им стать.

Успейте зарегистрироваться — билетов всё меньше и меньше!

Для кого?
Для старшеклассников и студентов

Зачем?
Участники смогут задать вопросы экспертам, послушать доклады о профессиях, пообщаться с рекрутерами и оставить им своё резюме на стажировку

Сколько стоит?
Участие бесплатное, но нужно зарегистрироваться

Где проходит?
В Музее криптографии. Вот тут карта, как проехать

Кто будет выступать?

  • Михаил Богомазов, руководитель группы направления обработки данных в «Криптоните»;

  • Полина Толстова, ведущий дата-инженер, платформа «Голосовой антифрод», билайн;

  • Анна Кудрявцева, руководитель группы по работе с молодыми талантами, Positive Technologies;

  • Алиса Фадеева, директор по развитию цифровых талантов, ВЭБ.РФ

Зарегистрироваться

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии0

В это воскресенье (20 апреля) в 13:30 приглашаем на «Ключ к профессии»! Осталось всего 40 билетов!

Эта встреча будет посвящена профессии «криптограф». Мы с представителями других брендов расскажем про особенности этой специальности, о навыках криптографов и о том, как им стать.

Успейте зарегистрироваться — сделать можно это по вот этой ссылке.

Для кого?
Для старшеклассников и студентов

Зачем?
Участники смогут задать вопросы экспертам, послушать доклады о профессиях, пообщаться с рекрутерами и оставить им своё резюме на стажировку

Сколько стоит?
Участие бесплатное, но на каждое мероприятие нужно зарегистрироваться

Где проходит?
В Музее криптографии. Вот тут карта, как проехать

Кто будет выступать?

  • Иван Чижов, заместитель руководителя лаборатории криптографии по научной работе в «Криптоните»

  • Алиса Коренева, начальник отдела криптографического анализа в «Коде Безопасности»

  • Евгений Алексеев, заместитель руководителя департамента информационной безопасности компании «КриптоПро»

  • Андрей Жиляев, старший исследователь Центра научных исследований и перспективных разработок в компании «ИнфоТеКС» и другие

Зарегистрироваться

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии0

На ноль делить нельзя... а вообще-то можно! Давайте разберёмся, откуда взялся этот запрет. Покажем на примерах.

Возьмём какое-нибудь число (пусть будет 2) и разделим его на 0,1. Получим 20. Теперь разделим 2 на 0,01. Получим 200. При делении 2 на 0,000001 уже получится 2 000 000. Легко увидеть, что чем ближе знаменатель будет к нулю, тем больше получится результат. Соответственно, результат деления на ноль устремляется в бесконечность. С отрицательными числами всё то же самое, только со знаком минус.

Если же мы делим ноль на ноль, то… получим ещё одну неопределённость. Есть Теорема Лопиталя, помогающая раскрывать неопределённости такого вида, но правила их раскрытия зависят от контекста и свойств анализируемых функций. Согласно IEEE 754 деление нуля на ноль даёт NaN (not a number, не число).

В общем случае говорят, что результат операции деления на ноль не определён.

В практических расчётах деление на ноль — явная ошибка, поскольку обратная операция оказывается невыполнима. Нет такого числа, которое можно умножить на ноль и получить исходное делимое.

Операция деления на ноль имеет смысл только в специализированной алгебраической структуре, которую описывает Теория колеса (Wheel theory). Её суть в том, что вводится понятие обратного числа, а деление заменяется умножением на обратное число. Числовая ось замыкается в кольцо через элемент ∞, а операция деления на ноль определяется как умножение ноля на ∞. Её результат записывается как ⊥, а этот элемент помещается вне кольца. По сути в Теории колеса подменяется смысл операции деления на ноль, поэтому она и становится возможной.

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

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

Теги:
Всего голосов 5: ↑4 и ↓1+4
Комментарии3

На картинке — код на Rust, и в нём затаилась ошибка. Я специально попросила её сделать моих коллег, разработчиков ИТ-компании «Криптонит».

Зачем? Чтобы потом попросить её найти и написать о ней в комментариях (ох, уж эти сммщики).

Итак, где тут ошибка?

СЕЙЧАС БУДЕТ СПОЙЛЕР!

Так в чём же ошибка?

В третьей строке возникает ошибка попытки доступа к элементу за пределами массива.
for i in 1..=numbers.len() выполнит итерацию по элементам, начиная со второго, а не с первого.

Ошибка заключается в попытке доступа к элементу с индексом [5] на последней итерации цикла. Такого элемента в массиве нет, в результате получаем аварийное завершение программы.

Также следует обратить внимание, что первый элемент массива с индексом [0] игнорируется. Это не является ошибкой с точки зрения выполнения программы, однако скорее всего является логической ошибкой в коде

Итак, в языке rust индексация элементов начинается с 0 и заканчивается len() - 1.
В массиве из 5 элементов допустимо обращение к [0], [1], [2], [3] и [4] элементам.

Рекомендуемый способ перебора элементов коллекции с автоматической индексацией на rust — использование цепочки вызовов iter().enumerate().

Вот как это выглядит

fn main() { 
    let numbers = vec![10, 20, 30, 40, 50];
    for (index, number) in numbers.iter().enumerate() { 
        println!("Элемент {index}: {number}");
    } 
}

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

Теги:
Всего голосов 5: ↑3 и ↓2+1
Комментарии1

Что такое метод дистилляции знаний? Рассказывают наши коллеги из лаборатории искусственного интеллекта. #нейрословарь

В сфере искусственного интеллекта используются разные методы оптимизации нейросетей. Среди них метод KD (knowledge distillation) часто применяется для переноса «знаний» от более сложной модели (учителя) к более простой (ученику).

Идея дистилляции знаний в том, чтобы научить упрощённую модель не только предсказывать верные классы, но и подражать поведению «учителя». Особенно это востребовано для смартфонов, интернета вещей (IoT) и граничных вычислений (edge-computing), словом — везде, где нужно «добавить нейронку» на слабое железо.

При обучении «ученика» используются как мягкие, так и жёсткие цели (one-hot метки как в обычном обучении). «Мягкие цели» содержат больше информации, чем простые метки классов. Они показывают не только какой класс правильный, но и как учитель воспринимает другие классы, какие из них считает более вероятными.

Для этого на стороне «учителя» увеличивается гиперпараметр «температура». Он смягчает распределение вероятностей классов, выдаваемое функцией softmax, в результате чего вероятности неправильных классов заметнее отличаются друг от друга.

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

Есть три разновидности KD:

  • оффлайн — учитель обучается без взаимодействия с учеником, а затем генерирует ему мягкие цели;

  • онлайн — учитель и ученик обучаются параллельно, чтобы адаптироваться друг к другу;

  • cамодистилляция — модель учит сама себя. Одни слои сети играют роль «учителя» для других слоёв.

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

Также дистилляция знаний используется для сжатия. Она позволяет создавать более компактные модели, которые занимают меньше места в памяти и работают быстрее. В частности, так создавались облегчённые версии больших языковых моделей (LLMs), включая BERT () и DeepSeek.

Теги:
Рейтинг0
Комментарии0

Ближайшие события

На картинке — код на JavaScript с ошибкой, который написал специально для Хабра руководитель группы разработки интерфейсов компании «Криптонит» Василий Беляев.

Кто увидел, где ошибка и как её можно решить — пишите в комментариях! А решение этой ошибки оставили под картинкой.

Где здесь ошибка?
Где здесь ошибка?

Если запустим этот код, то получим ошибку

Uncaught TypeError: this.clearHistory is not a function

Проблема находится на строчках 11-13 (на картинке)

this.timeout = setTimeout (function () {
        this.clearHistory();
    }, 0);

Когда мы вызываем setTimeout, то вызываем метод объекта window, и меняем область видимости с нашего конструктора на window ( window.setTimeout() ).

Именно по этой причине у нас метод clearHistory пытается вызываться у объекта window ( window.clearHistory() )

Как можно решить эту проблему?

Вариант 1

const MyItem = function () {
    this.clearStorage = function () {
        console.log ('Очищаем хранилища...');
    };
    this.clearHistory = function () {
        console.log ('Очищаем историю...');
    };
};
MyItem.prototype.refresh = function () {
    this.clearStorage();
    this.timeout = setTimeout (() => {
        this.clearHistory();
    }, 0);
};
const mуItem = new MyItem();
mуItem.refresh();

Заменить анонимную функцию на стрелочную функцию. У них отсутствует свой контекст, и они работают в контексте области видимости, включающий их самих.

Вариант 2

const MyItem = function () {
    this.clearStorage = function () {
        console.log ('Очищаем хранилища...');
    };
    this.clearHistory = function () {
        console.log ('Очищаем историю...');
    };
};
MyItem.prototype.refresh = function () {
    this.clearStorage();
    this.timeout = setTimeout (
        this.clearHistory.bind(this), 0
    );
};
const mуItem = new MyItem();
mуItem.refresh();

Явно передать контекст через метод .bind()

Вариант 3

const MyItem = function () {
    this.clearStorage = function () {
        console.log ('Очищаем хранилища...');
    };
    this.clearHistory = function () {
        console.log ('Очищаем историю...');
    };
};
MyItem.prototype.refresh = function () {
    this.clearStorage();
    const self = this;
    this.timeout = setTimeout (() => {
        self.clearHistory();
    }, 0);
};
const mуItem = new MyItem();
mуItem.refresh();

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

А как бы вы решили эту ошибку?

Теги:
Всего голосов 6: ↑3 и ↓3+2
Комментарии5

Kryptonite ML Challenge подходит к концу!

Члены жюри, наши эксперты из лаборатории ИИ, отсмотрели все присланные решения и определились с финалистами!

В это воскресенье, 16 марта, в 12:00 пройдёт онлайн-питчинг проектов, а затем официальное закрытие Kryptonite ML Challenge.

Всех приглашаем присоединиться к трансляции — она будет в нашем паблике VK. Оставляем ссылку.

Теги:
Рейтинг0
Комментарии0

Всем привет! Я работаю в ИТ-компании «Криптонит» и как-то раз услышала от наших коллег из лаборатории искусственного интеллекта про Moët MoE. Расспросила у них про эту архитектуру — делюсь!

MoE (Mixture of Experts, набор экспертов) — архитектура нейросети, в которой используется набор из нескольких специализированных подсетей меньшего размера. Каждая из них играет роль эксперта и специализируется на определённом типе задач.

Распределяет задачи между экспертами отдельный механизм, который в разных источниках называется шлюзом (gate) или маршрутизатором (router). Анализируя пользовательский запрос и формат входных данных, он решает, кому из экспертов поручить выполнение задания.

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

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

На базе MoE построены известные модели с миллиардами параметров, такие как OpenAI GPT-4, Mixtral 8x7B, GLaM, NLLB-200 и другие.

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

Помимо работы с текстом, ИИ-сервисы на базе MoE находят применение в генерации изображений, видеороликов и музыки, а также в рекомендательных системах. Лаборатория искусственного интеллекта компании «Криптонит» тоже применяет MoE в решении задач обработки текста и аудио.

Теги:
Всего голосов 2: ↑2 и ↓0+2
Комментарии0

Уже завтра заканчивается регистрации на Kryptonite ML Challenge! Если вы не ждали знак, что пора регистрироваться — вот он!

На нашем соревновании нужно создать модель, которая умеет:

  • распознавать фальшивые изображения;

  • сравнивать реальные фотографии одного и того же человека;

  • различать снимки разных людей.

Успей победить DeepFake!

Регистрация открыта до 28 февраля — https://clc.to/kryptonite-ml

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Деревья решений и случайный лес

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

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

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

Чтобы устранить эти недостатки, был разработан более продвинутый метод машинного обучения на основе деревьев решений — случайный лес (random forest). Это ансамблевый метод машинного обучения, применяемый в основном для анализа медицинских данных, маркетинговых исследований и кредитного скоринга.

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

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

Такой подход повышает точность предсказаний и снижает влияние эффекта переобучения. Однако он требует в разы больше ресурсов и теряет лёгкость интерпретации.

Теги:
Рейтинг0
Комментарии0

Как-то один из наших коллег (а я работаю в ИТ-компании «Криптонит») услышал забавный разговор в метро.
 
— Ой, давай не будем стоять в очереди! Вон турникет с оплатой лицом свободный, пошли там пройдём.
— Ты что, доверяешь биометрии!? А если твоё лицо украдут?
— Там проезд со скидкой 10 рублей.
— А, тогда пошли.

 
Ситуация смешная, но вопрос серьёзный. В России с 2018 года работает Единая биометрическая система (ЕБС). Как любая система, она подвержена атакам, и специалисты внутри ЕБС постоянно с ними борются.
 
Так как же защищают ЕБС?

  • Применяют не один вендор биометрических процессоров (они стоят в ядре), а несколько. Это позволяет минимизировать ложные срабатывания; атаки на предъявляемые образцы и всё, что с этим связано.

  • Проверяют объекты «на живость» (liveness). То есть применяют технологию, которая на этапе идентификации отличает живого человека от маски или дипфейка.

  • Используют модуль аномалий. Специалисты на стороне ЕБС разработали модуль, который отслеживает аномалии при транзакционном взаимодействии с системой.

Это значит, что «универсального» средства защиты нет, а использовать приходится несколько инструментов одновременно. Именно так выглядит постоянная борьба «белых» специалистов и тех, кто хочет взламывать нейронки.
 

Об этом на V встрече экспертного сообщества по криптографии и большим данным рассказал руководитель направления по продуктам ИБ от Центра биометрических технологий Илья Александров. Встречу организовал «Криптонит» при поддержке Музея криптографии.

Смотрите запись встречи
📺 на Rutube
📺 в VK видео

#аудитИИ

Теги:
Всего голосов 4: ↑2 и ↓20
Комментарии3

Информация

Сайт
kryptonite.ru
Дата регистрации
Дата основания
Численность
501–1 000 человек
Местоположение
Россия