Compare commits

...

71 Commits

Author SHA1 Message Date
Basyrov Rustam
a80e20862c add jenkins to CV 2025-06-02 17:22:05 +03:00
Basyrov Rustam
6bddd048ca remove test stuff 2025-06-02 17:14:34 +03:00
Basyrov Rustam
fd3225b8b3 Test 2025-06-02 17:10:58 +03:00
Basyrov Rustam
eb295fdf41 fix "about me" page 2025-06-02 13:55:09 +03:00
Basyrov Rustam
4ebb210103 fix typo 2025-05-30 16:06:44 +03:00
Basyrov Rustam
3595549e62 add date 2025-05-30 16:03:24 +03:00
Basyrov Rustam
e61c314311 add some references 2025-05-30 16:03:21 +03:00
Basyrov Rustam
304c3cc1d4 remove some stuff 2025-05-30 15:48:31 +03:00
Basyrov Rustam
457a1d397b finish article type-pred 2025-05-30 15:44:35 +03:00
Basyrov Rustam
96910eea02 add signature calculating note 2025-05-30 15:29:09 +03:00
Basyrov Rustam
f180169558 new index to working ToC 2025-05-30 14:04:51 +03:00
Basyrov Rustam
8456b95098 some new settings
going to mkdocs-material
2025-05-30 14:03:11 +03:00
Basyrov Rustam
ac172c0357 add code block descriptions 2025-05-30 13:39:37 +03:00
Basyrov Rustam
d04ae45f10 some addings 2025-05-29 21:04:48 +03:00
Basyrov Rustam
9f012896d8 add link to Gauss's smoothing 2025-05-29 21:04:42 +03:00
Basyrov Rustam
80a547df3b add png's 2025-05-29 21:04:12 +03:00
Basyrov Rustam
8af5a68a39 neural network 2025-05-12 21:01:19 +03:00
Basyrov Rustam
b71d1d4809 new stage 2025-05-11 20:11:03 +03:00
rustam
424e72f232 two heads 2025-05-10 15:54:28 +03:00
Basyrov Rustam
709bb61cf3 Intro 2025-05-09 19:08:31 +03:00
Basyrov Rustam
7d93ef9790 references 2025-05-09 18:48:21 +03:00
Basyrov Rustam
1bfac10d9a pics? 2025-05-09 18:46:24 +03:00
Basyrov Rustam
48d07c7d65 headers 2025-05-06 17:27:21 +03:00
Basyrov Rustam
d21f1db4bf Merge branch 'main' into filetype_prediction 2025-05-05 22:33:27 +03:00
Basyrov Rustam
2ad1e0c48d fix typo in article name 2025-05-05 22:33:20 +03:00
Basyrov Rustam
b5d706683c init new article 2025-05-04 22:07:46 +03:00
Basyrov Rustam
344ee7a343 Merge pull request #4 from rustbas/dev
ACH
2025-04-23 19:13:48 +03:00
Basyrov Rustam
9a36e5d7d2 date 2025-04-23 19:12:05 +03:00
Basyrov Rustam
8ff36d994d some pretty/typos 2025-04-23 18:40:55 +03:00
Basyrov Rustam
ee294e1d37 typos 2025-04-23 17:04:28 +03:00
Basyrov Rustam
775c3e6936 finish ach article 2025-04-23 17:03:45 +03:00
Basyrov Rustam
7e995357f9 add *.bak to .gitignore 2025-04-23 16:39:09 +03:00
Basyrov Rustam
170f9555d2 fix typos (aspell) 2025-04-23 16:38:54 +03:00
Basyrov Rustam
6af8d049b9 some stuff 2025-04-23 16:36:36 +03:00
Basyrov Rustam
3ba1a5da15 some add 2025-04-21 22:22:22 +03:00
rustam
2eebeefdde ACH 2025-04-03 13:29:02 +03:00
Basyrov Rustam
aae89afff0 init page 2025-04-01 14:14:14 +03:00
Basyrov Rustam
4c78c1990f init new section 2025-04-01 14:14:04 +03:00
Basyrov Rustam
6bb96d67de init page 2025-04-01 13:33:28 +03:00
Basyrov Rustam
971107a38e fix typo 2025-01-28 17:48:27 +03:00
Basyrov Rustam
8a4d5e673a another fix 2025-01-24 14:18:25 +03:00
Basyrov Rustam
ffa3fc8b00 fix 2025-01-24 14:17:32 +03:00
Basyrov Rustam
0d95d51d55 fix date 2025-01-24 14:10:15 +03:00
Basyrov Rustam
df0bbb0f4b Merge branch 'dev' 2025-01-24 14:04:33 +03:00
Basyrov Rustam
72133bd71f fix typos 2025-01-24 14:04:11 +03:00
Basyrov Rustam
c0d7ce44c7 article 2025-01-24 11:15:29 +03:00
Basyrov Rustam
dba60d8a77 add distccmon-text picture 2025-01-24 11:15:25 +03:00
Basyrov Rustam
49fa395a10 init motivation 2025-01-23 22:01:31 +03:00
Rustam
8d50afe15b init article about vagrant and distcc 2025-01-12 12:08:31 +03:00
rustbas
719826c1a5 Merge pull request #3 from rustbas/dev
`stat-madness.md`
2024-11-16 08:06:46 +00:00
Basyrov Rustam
744f329f68 some fixes 2024-11-16 11:05:26 +03:00
Basyrov Rustam
d648934dd3 add pics 2024-11-16 10:13:54 +03:00
Basyrov Rustam
9c0dd24b78 init article
without pictures!
2024-11-13 19:28:07 +03:00
Basyrov Rustam
87c033da3a Merge branch 'dev'
Some checks failed
ci / deploy (push) Has been cancelled
2024-11-04 00:35:52 +03:00
Basyrov Rustam
e36e9f8bbb Init README.md 2024-11-04 00:35:43 +03:00
Basyrov Rustam
38b092b567 Merge branch 'dev'
Some checks are pending
ci / deploy (push) Waiting to run
2024-11-01 21:59:00 +03:00
Basyrov Rustam
3c66d4a3d6 add links 2024-11-01 21:58:41 +03:00
Basyrov Rustam
70998fe74b add date 2024-11-01 21:58:36 +03:00
Basyrov Rustam
185aa1c47c fix bullet list 2024-11-01 21:58:29 +03:00
Basyrov Rustam
4f53829af4 init manpage article 2024-11-01 19:56:44 +03:00
Basyrov Rustam
a2cb0a4ca1 Merge branch 'dev' 2024-10-31 10:05:48 +03:00
Basyrov Rustam
a6d1e86cda change order 2024-10-31 10:05:41 +03:00
Basyrov Rustam
1b00fb9950 Merge branch 'dev' 2024-10-31 10:04:14 +03:00
Basyrov Rustam
7cc2691693 some cosmetic and rename article 2024-10-31 10:04:08 +03:00
Basyrov Rustam
b92c2fcc1a pretty fixes 2024-10-30 18:41:04 +03:00
Rustam
fbe8ec627a Merge branch 'dev' 2024-10-07 18:47:52 +03:00
Rustam
e464dde870 Merge branch 'dev' 2024-10-07 18:46:32 +03:00
rustbas
e3aa74b1af Merge pull request #2 from rustbas/dev
init "about" page
2024-10-07 15:46:11 +03:00
Rustam
0e5036527a Merge branch 'dev' 2024-09-24 23:45:33 +03:00
Rustam Basyrov
993a601e21 fix footnote typo 2024-09-24 18:43:13 +03:00
rustbas
380e1b0295 Merge pull request #1 from rustbas/dev
Dev
2024-09-24 18:17:09 +03:00
22 changed files with 1069 additions and 35 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
venv/
*.bak

1
README.md Normal file
View File

@@ -0,0 +1 @@
# blog

217
docs/common/ach.md Normal file
View File

@@ -0,0 +1,217 @@
# Немного про принятие решений и нейросети
## Мотивация
Сейчас очень распространились нейросети различных форматов: для работы
с текстом, видео, аудио, для обработки и прогнозирования данных. В
твиттере ажиотаж вокруг новой возможности ChatGPT: обработка
изображений в стиле студии Ghibli, известной по фильмам "Мой сосед
Тоторо", "Унесенные призраками" и пр.
Нейросети применяются не только для "развлечений", но и в весьма
ответственных областях, например, анализ снимков рентгена, разработке
программ. Для последнего даже был придуман термин [Vibe Coding](https://en.wikipedia.org/wiki/Vibe_coding).
Я, в некоторой степени, являюсь луддитом по отношению к нейросетям,
которые генерируют тексты. Это обусловлено преимущественно тем, что
люди относятся к ним, как к некой "палочке-выручалочке", которая
представляет собой кнопку "сделать красиво". Такой подход не только
снижает *критичное отношение* к окружающему миру (зачем придумывать
решение, если нейросеть может сгенерировать его за меня, *даже если он
будет некорректный*), но уменьшает общее качество деятельности.
Но даже так, я не являюсь противником нейросетей *просто по
существу*. У всего есть качественные области применения, иногда не
совсем очевидные.
Здесь я хочу рассказать об **анализе конкурирующих гипотез**,
**мозговом штурме** и **попытке применения в них нейросетей**.
## Большие языковые модели
Должен признать, что у меня весьма смутное представление о работе
таких нейросетей *под капотом*.
В моем понимании, суть их работы заключается в том, при анализе
запроса любого толка, они "понимают", какие слова будут уместны в
контексте этого запроса (получается такая очень сложная "китайская
комната"[2]).
Результатом же работы нейросети является текст, который я воспринимаю
как *случайное число*, которое параметризовали запросом (*prompt*),
примерно как случайное число из нормального распределения
параметризуется математическим ожиданием и дисперсией. Хотя, есть и
[другое мнение](https://x.com/tsoding/status/1896205552415658463).
А если есть случайность, то значит можно её можно использовать.
## Суть анализа конкурирующих гипотез
**Анализ конкурирующих гипотез** - методология, разработанная Ричардом
Хоером в 70-х годах. Целью создания метода было уменьшение влияния
когнитивных сдвигов (*bias*) на работу аналитиков при анализе и принятии
решений.
Особенность метода заключается в том, что вместо сопоставления каждой
гипотезе всех доказательств, наоборот, каждое доказательство
противопоставляется всем гипотезам.
Пошаговая инструкция к методу:
1. Определить все **возможные** гипотезы. Лучше использовать *команду
аналитиков* с различным опытом, чтобы реализовать **мозговой
штурм**.
2. Создать список всех существенных доказательств, аргументов "за" и
"против, а также фактов, которые могут помочь в анализе гипотез.
3. Подготовить матрицу, где номер строки будет отвечать за номер
аргумента, а номер столбца за номер гипотезы.
4. Проверить матрицу: уточнить формулировку гипотез, удалить аргументы,
которые не имеют диагностической ценности.
5. Сопоставьте каждое доказательство каждой гипотезе. Двигайтесь
по столбцам.
6. Проанализируйте, как устойчивы ваши заключение к аргумента.
Посмотрите, как изменится вывод в случае, если какие-то аргументы
окажутся ложными.
7. Составьте отчет. Проверьте правдоподобность каждой гипотезы, *не
только самой приятной*.
8. Оцените дальнейшие шаги для улучшения оценки.
Можно долго вдаваться в детали реализации метода. В нашем случае, нас
интересует часть, где необходимо придумать как можно большее число
вариантов, используя **мозговой штурм**.
### Применение нейросетей
Когда нет большой *команды аналитиков*, можно попробовать заменить их
нейросетью. В данном случае, нейросеть можно применить в двух местах:
1. В п. 1 для определения всех **возможных** гипотез. Само собой,
качество этих гипотез определяет аналитик, но их генерацию можно
частично делегировать ИИ.
2. В п.2 можно попробовать определить области, где **искать
доказательства** за и против. Нужно помнить, что доказательства
также могут представлять собой *отсутствие* чего-либо.
## Пример
Приведу пример (полученный также с помощью ИИ): "Почему в городе
резко выросло число ДТП на конкретном перекрестке?".
Полученный список гипотез:
```
- Инфраструктурные факторы
1. **Изменение дорожной разметки или знаков**: Неправильно
нанесенная разметка, противоречивые знаки или их отсутствие.
2. **Неисправность светофора**: Сбои в работе (например, мигающий
желтый сигнал), некорректные временные интервалы.
3. **Сужение полос** из-за ремонтных работ, парковки или временных
ограждений.
4. **Новые препятствия**: Установка рекламных щитов, столбов,
деревьев, ограничивающих обзор.
5. **Плохое состояние дорожного покрытия**: Выбоины, ледяная
корка, отсутствие освещения в темное время суток.
6. **Изменение типа перекрестка**: Например, переход от светофора
к круговому движению без должного информирования.
- Транспортный поток
7. **Рост трафика** из-за открытия новых ТЦ, офисов, жилых
комплексов.
8. **Перенаправление движения** с других улиц из-за ремонта,
аварий или изменений в маршрутах.
9. **Увеличение грузового транспорта**: Новые логистические
маршруты через перекресток.
10. **Активность общественного транспорта**: Новые автобусные
остановки или троллейбусные линии.
- Человеческий фактор
11. **Нарушение ПДД водителями**: Частые проезды на красный свет,
превышение скорости, агрессивное вождение.
12. **Низкая видимость пешеходов**: Отсутствие зебры, освещения
или знаков у пешеходного перехода.
13. **Отвлекающие факторы**: Яркая реклама, использование
телефонов за рулем.
14. **Новички на дороге**: Увеличение числа неопытных водителей
(например, из-за новой автошколы поблизости).
- Внешние условия
15. **Погодные аномалии**: Гололед, туман, дождь, слепящее солнце
в определенные часы.
16. **Сезонные факторы**: Туристы, листопад, снежные заносы.
17. **Животные на дороге**: Бродячие собаки, птицы или дикие
животные, вызывающие резкие торможения.
- Технические причины
18. **Неисправности автомобилей**: Массовые отзывы авто из-за
брака тормозных систем.
19. **Сбои в системах помощи водителю**: Например, ошибки в
навигаторах, предлагающих опасные маневры.
20. **Электромагнитные помехи**, влияющие на работу датчиков или
светофоров.
- Организационные и социальные факторы
21. **Снижение контроля со стороны ГИБДД**: Уменьшение числа
патрулей или камер фиксации нарушений.
22. **Новые правила движения**, которые водители не успели
изучить.
23. **Вандализм**: Повреждение знаков, светофоров или разметки.
24. **Массовые мероприятия**: Концерты, митинги или фестивали,
создающие заторы и невнимательность.
- Статистические аномалии
25. **Случайная кластеризация**: Краткосрочный всплеск аварий без
системной причины.
26. **Изменение методики учета ДТП**: Теперь фиксируются даже
мелкие столкновения, которые раньше игнорировались.
27. **Ошибки в данных**: Технические сбои при сборе статистики.
```
Хочется обратить внимание, что гипотез очень много и часть из низ
можно отмести в зависимости от контекста исследования. Но эту задачу
**должен делать аналитик**.
Ответ на вопрос: "где искать доказательства":
```
- Данные ГИБДД: Статистика нарушений, протоколы ДТП, видео с камер.
- Дорожные службы: Отчеты о ремонтах, изменениях разметки, проверках
светофоров.
- Метеорологические службы: Погодные сводки на даты аварий.
- Соцсети и СМИ: Жалобы водителей, репортажи о проблемах на
перекрестке.
- Технические данные: Логи навигаторов (Яндекс.Пробки, Google Maps),
отчеты автопроизводителей.
```
На основе полученных ответов можно пробовать строить анализ.
## Выводы
В заключении этого небольшого текста, хочу отметить несколько выводов:
1. Данная заметка не является инструкцией в стиле "вы используете
языковые модели неправильно". Здесь я просто хочу высказать мнение
касательно ИИ и отметить, какое применение я вижу у этого
инструмента.
2. В моем понимании, нейросети подойдут в тех случаях, когда нужно
применить **мозговой штурм**: составление гипотез, поиск
доказательств, составление списка действия для решения задачи в
методологии *GTD*.
3. Не стоит отдавать под контроль ИИ принятие решений на _любом
уровне_. Все логические выкладки должен делать аналитик, который
использует языковую модель как инструмент.
4. Думаю, обращаться за помощью к нейросетям, нужно если не в
*последнюю очередь*, то хотя бы не сразу. Во-первых, стоит не
забывать про собственное *критичное отношение* к миру, а во-вторых,
цель **мозгового штурма** -- это сбор сех_ возможных вариантов,
которые могут пройти ниже радаров нейросети, и про которые потом не
станет думать аналитик, будучи отвлеченный анализом результатов.
По итогу, я убежден, что языковые модели -- это *инструмент*, который
можно применить во множестве областей, но это все же *инструмент*. Он
не решит все проблемы за вас, но поможет вам решить ваши проблемы.
## Источники
1. [Psychology of intelligence analysis](https://www.amazon.com/Psychology-Intelligence-Analysis-Richards-Heuer/dp/B0016OST3O)
2. [Китайская комната](https://ru.wikipedia.org/wiki/%D0%9A%D0%B8%D1%82%D0%B0%D0%B9%D1%81%D0%BA%D0%B0%D1%8F_%D0%BA%D0%BE%D0%BC%D0%BD%D0%B0%D1%82%D0%B0)

3
docs/common/index.md Normal file
View File

@@ -0,0 +1,3 @@
# Общие заметки
## 2025-04-23 [Немного про принятие решений и нейросети](ach.md)

View File

@@ -3,15 +3,27 @@
Меня зовут Рустам.
Люблю Linux и все, что связано с ним.
Увлекаюсь автоматизацией, аналитикой и программированием, а также смежными
направлениями.
Предпочитаю командную строку графическим
приложениям.
Ввиду того, что я часто делаю "*Proof of Concept*" и "*Probe*" проекты, было
решено завести для этого блог.
Также увлекаюсь математической статистикой и машинным обучением.
Здесь время от времени выкладываю заметки по различным темам, которые мне
показались интересными.
В свободное время, если есть возможность, занимаюсь спортивным туризмом, в
частности, горным. В 2019 году взошел на Казбек (5033 м, 2Б к.с.) и в 2021 году
— на Эльбрус (5642 м, 2А к.с.).
# Технологический стэк
# TBD
- **Администрирование**: дистрибутивы Linux, права доступа, управление
процессами, **nginx** (веб-сервер), сетевые протоколы, ведение документации
(**mkdocs**);
- **DevOps**: основы **docker** и **ansible**, docker-compose (в т.ч.
Portainer), основы **CI/CD** (GitHub Actions, GitLab CI, Jenkins);
- **Программирование**: **python** (в том числе: numpy, scipy, pandas,
matplotlib), **bash** и zsh, **C/C++**;
- **Математика**: основы теории случайных процессов, машинное обучение,
построение критериев для проверки **гипотез**, численные методы,
моделирование (**метод отбора, MCMC, bootstrap**);
- **Вёрстка**: $\LaTeX$, Markdown, groff, HTML, CSS;
- **Общее**: чтение документации (на русском и английском), **git**,
**терминал** (vim, tmux, различные утилиты командной строки);

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 961 KiB

284
docs/linux/distrant.md Normal file
View File

@@ -0,0 +1,284 @@
# Немного про распределенную компиляцию
## Мотивация / Введение
Мне, как любителю Linux, всегда было интересно изучить Gentoo
Linux. На это есть множество причин, сейчас не о них.
Суть в том, этап установки системы на виртуальную машину пройден и
есть желание попробовать установить на второстепенный маломощный нетбук.
Возникает проблема: Gentoo Linux -- это т.н. "source-based" дистрибутив,
т.е. она распространяется в виде исходного кода. В свою очередь, компиляция
системы на нетбуке занимает чуть больше суток (возможно, это можно поправить
более тщательной конфигурацией перед сборкой, но, на мой взгляд, это
слишком "хардкорный" путь для знакомства с системой). Конечно, компиляция
ядра, строго говоря, необязательна, так как можно поставить предварительно
скомпилированную версию. Но так неинтересно.
Таким образом, возникает вопрос -- можно ли ускорить компиляцию
на слабых ПК? Тут на помощь приходит `distcc`,
своего рода фронтенд для компиляторов C/C++.
Сегодня мы хотим посмотреть на возможность компиляции ядра Linux (минимальной
конфигурации `tinyconfig`) на двух виртуальных машинах с разными
характеристиками. Но для этого нужно рассказать про утилиту `vagrant`,
конфигуратор виртуальных машин.
## Vagrant
Vagrant[^1] (с англ. — «бродяга») — свободное и открытое программное
обеспечение для создания и конфигурирования виртуальной среды разработки.
Является обёрткой для программного обеспечения виртуализации, например
VirtualBox, и средств управления конфигурациями, таких как Chef, Salt и
Puppet.
Данная утилита полезна тем, что позволяет, используя шаблоны виртуальных
машин, запускать их. Для описания стэка требуется один т.н. Vagrantfile.
Она может работать совместно с qemu, VirtualBox, VMWare и пр.
О vagrant стоит знать потому, что в какой момент, эксперементируя с
виртуальными машинами, надоест каждый раз их устанавливать в условном VMWare.
## Distcc
distcc[^2] (от англ. distributed C/C++/ObjC compiler) — инструмент,
позволяющий компилировать исходные коды при помощи
компиляторов C/C++/ObjC на удалённых машинах, что ускоряет процесс компиляции.
Важно понимать, что это своего рода фронтенд для компиляторов,
сам по себе он не компилирует код.
## Компиляция
### Демонстрация стенда
Для начала построчно рассмотрим Vagrantfile.
При его написании используется язык Ruby.
Описание "шаблона" для виртуальных машин. В данном случае это Debian
12 Bookworm.
```ruby
# Default box
box_name = "debian.jessie64.libvirt.box"
```
Файл можно скачать с сайта HashiCorp.
Описание виртуальной машины, на которой будет основная компиляция:
```ruby
# Master
master_node = {
:hostname => "master", :ip => "10.200.1.2", :memory => 1024, :cpu => 1
}
```
Характеристики:
- IP: 10.200.1.2,
- RAM: 1Gb,
- 1 поток.
Они похожи на характеристики моего нетбука, но занижены в целях демонстрации.
Описание второстепенной виртуальной машины:
```ruby
# List of slaves
slaves = [
{ :memory => 4096, :cpu => 4 },
]
```
Характеристики:
- RAM: 4Gb,
- 4 потока.
Скрипт для автоматической установки зависимостей:
```ruby
$distcc_install = <<-SCRIPT
apt update
apt install -y make distcc gcc g++ tmux libz-dev git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison time neofetch
SCRIPT
```
Старт конфигурации виртуальных машин:
```ruby
Vagrant.configure("2") do |config|
```
Конфигурация основной машины:
```ruby
# Master node's config
config.vm.box_check_update = false
config.vm.define master_node[:hostname] do |nodeconfig|
nodeconfig.vm.box = box_name
nodeconfig.vm.hostname = master_node[:hostname]
nodeconfig.vm.network(:private_network, ip: master_node[:ip])
nodeconfig.vm.provision "shell", inline: $distcc_install
nodeconfig.vm.provision "file", source: "./linux-6.13.tar.gz", destination: "~/linux-6.13.tar.gz"
nodeconfig.vm.provider :libvirt do |vb|
vb.memory = master_node[:memory]
vb.cpus = master_node[:cpu]
end
end
```
В нем:
1. Отключаются обновления,
2. Задаются характеристики ВМ,
3. Запускается скрипт установки зависимостей,
4. Копируется
[архив](https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.13.tar.gz)
с исходным кодом ядра (должен лежать в директории с Vagrantfile).
Конфигурация второстепенных машин:
```ruby
# Slaves configs
slaves.each_with_index do |slave, i|
config.vm.box_check_update = false
config.vm.define "slave-#{ i+1 }" do |nodeconfig|
# Default box-name (cause I have only it)
nodeconfig.vm.box = box_name
# Hostname: slave-N
nodeconfig.vm.hostname = "slave-#{ i+1 }"
# IP-address: 10.200.1.{N+2}
nodeconfig.vm.network :private_network, ip: "10.200.1.#{ i+3 }"
nodeconfig.vm.provision "shell", inline: $distcc_install
nodeconfig.vm.provider :libvirt do |vb|
vb.memory = slave[:memory]
vb.cpus = slave[:cpu]
end
end
end
end
```
Стоит обратить внимание, что IP задается автоматически, начиная от
`10.200.1.3` и далее. Сделано это на случай нескольких ВМ.
### Компиляция на одной машине (gcc)
Для начала запустим стенд командой `vagrant up`. На моем ноутбуке это занимает
примерно 127 секунд.
Далее необходимо подключиться к главной машине и распаковать исходники ядра[^3]:
```shell
vagrant ssh master
tar xvf linux-6.13.tar.gz
cd linux-6.13
```
Создаем файл минимальной конфигурации
(с остальными вариантам можно ознакомиться командой `make help | less`):
```shell
make tinyconfig
```
> **Важно**: для чистоты эксперимента все замеры делаются после команды `make
distclean` (см. `make help`).
Запускаем компиляцию с замером времени:
```shell
time -p make CC=gcc
```
### Компиляция на одной машине (distcc)
По смыслу, все тоже самое, только нужно указать distcc, на каких хостах
можно компилировать:
```shell
export DISTCC_HOSTS="localhost"
```
Запускаем компиляцию с замером времени:
```shell
time -p make CC="distcc gcc"
```
### Компиляция на двух машинах (distcc)
Для запуска распределенной компиляции, нужно сначала запустить демон на
второй виртуальной машине. Для этого подключаемся к ней и запускаем его:
```shell
vagrant ssh slave-1
distccd --daemon --allow-private
```
Параметр `--allow-private` разрешает стучаться только с приватных сетей.
Для проверки можно:
1. На второй машине проверить открытые порты: `ss -ntlp | grep 3632`,
2. С основной машины постучаться в этот порт: `telnet 10.200.1.3 3632`
(выход на `C-] C-d`).
Теперь нужно добавить хост, чтобы на нем можно было удаленно компилировать.
Для этого на основной машине:
```shell
export DISTCC_HOSTS="localhost 10.200.1.3"
```
Для проверки можно посмотреть список хостов для компиляции: `distcc --show-hosts`.
Запустим компиляцию на 5 потоках с замером времени:
```shell
time -p make -j5 CC="distcc gcc"
```
Мониторить компиляцию можно с помощью команды (на основной машине):
```shell
watch -n 1 distccmon-text
```
![distccmon-text](assets/distccmon-text.png)
### Таблица сравнения
|Итерация|Одна машина (gcc), с|Одна машина (distcc), с|Две машины (distcc), с|
|:------:|:------------------:|:---------------------:|:--------------------:|
| 1 | 176 | 176 | 111 |
| 2 | 186 | 162 | 109 |
| 3 | 187 | 174 | 127 |
|Среднее | 183 | 170 | 115 |
## Итог
Можно увидеть, что такая параллелизация дает прирост 37%.
Сложно сказать, можно ли разогнать сильнее, так как многое зависит от
правил компиляции (например, их нельзя распараллелить больше чем на 5 потоков).
Очевидно, что распределенная компиляция при прочих равных будет проигрывать
параллельной, так как общение между потоками по определению быстрее.
Но для слабых машин это отлично подходит. К сожалению, у данного метода есть
существенные ограничения:
1. Версии gcc и distcc должны совпадать (хотя, пишут, что достаточно
совпадения только мажорных версий).
2. В некоторых случаях нет возможности общения по TCP и требуется подключение по
SSH. Например, когда есть ограничения безопасности или при сложной организации
сети. Определенно, такое подключение будет медленнее.
Все материалы стенда можно найти в
[репозитории](https://github.com/rustbas/disgrant/) на Github.
[^1]: Википедия [Vagrant](https://ru.wikipedia.org/wiki/Vagrant).
[^2]: Википедия [distcc](https://ru.wikipedia.org/wiki/Distcc).
[^3]: Исходный код ядра можно найти [здесь](https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.13.tar.gz).

View File

@@ -1 +1,6 @@
# Linux
## 2024-11-01 [Немного про мануалы](manpage.md)
## 2025-01-24 [Немного про распределенную компиляцию](distrant.md)

110
docs/linux/manpage.md Normal file
View File

@@ -0,0 +1,110 @@
# Немного про мануалы
## Мотивация
Какое-то время назад возникла задача:
написать мануал к репозиторию с дотфайлами.
Вообще, сложилось впечатление, что сейчас большая часть документации создается
либо автоматически, либо техническими писателями. Причем сама документация
лежит на каком-то сайте, например, **github.io** и нечасто можно получить
к ней доступ офлайн. В таких случаях спасают `man`-ы.
## Способы
Вообще, сам мануал -- это документ для [препроцессора](https://en.wikipedia.org/wiki/Groff_(software)) `groff`, который
умеет читать команда `man`, и который можно перевести в другие форматы,
при желании.
[Пример](https://www.cyberciti.biz/faq/linux-unix-creating-a-manpage/) (`test.1`):
```groff
.\" Manpage for nuseradd.
.\" Contact vivek@nixcraft.net.in to correct errors or typos.
.TH man 8 "06 May 2010" "1.0" "nuseradd man page"
.SH NAME
nuseradd \- create a new LDAP user
.SH SYNOPSIS
nuseradd [USERNAME]
.SH DESCRIPTION
nuseradd is high level shell program for adding users to LDAP server. On Debian, administrators should usually use nuseradd.debian(8) instead.
.SH OPTIONS
The nuseradd does not take any options. However, you can supply username.
.SH SEE ALSO
useradd(8), passwd(5), nuseradd.debian(8)
.SH BUGS
No known bugs.
.SH AUTHOR
Vivek Gite (vivek@nixcraft.net.in)
```
Если выполнить команду `man ./test.1`, то увидите следующее:
![Пример manpage](assets/manpage.jpg)
Красиво, но не слишком удобно для создания. Я использовал другой -- через
конвертацию `markdown`-файлов.
## Процесс
### `pandoc`
Для начала, нужна сама [программа](https://en.wikipedia.org/wiki/Pandoc) `pandoc`. Ставим:
```shell
sudo apt install pandoc
```
### Написание мануала
Само написание мануала, думаю, стоит опустить. Синтаксис `markdown`-а
можно посмотреть на википедии.
Есть только два нюанса при написании:
1. В начале нужно указать что-то вроде
`% dotfiles(1) | dotfiles usage documentation`
2. По умолчанию, `pandoc` распознает каждую строку как отдельный
параграф. Из-за этого между строками в результате получается
разрыв. Чтобы избежать этого, нужно в конце строки добавлять `\`.
Сконвертировать файл можно командой:
```shell
pandoc --standalone --to man manpage.md --output=dotfiles.1
```
Также, стоит отметить принятое оглавление. Есть три обязательные секции:
- **NAME** - название
- **SYNOPSIS** - краткое описание (в одну строку) команды или примеры аргументов
или ключей.
- **DESCRIPTION** - подробное описание команды
Также, можно указать:
- **OPTIONS** - описание опций/аргументов.
- **EXAMPLES** - примеры запуска.
- **FILES** - описание файлов, если есть файлы конфигурации.
- **ENVIRONMENT** - описание переменных окружения.
- **BUGS** - Известные баги/ошибки.
- **AUTHORS** - авторы.
- **SEE ALSO** - референсы к другим мануалам.
- **COPYRIGHT | LICENSE** - текст лицензии.
### Как пользоваться
Для того, чтобы можно было удобно пользоваться написанным мануалом,
нужно:
1. Сжать его -- `gzip dotfiles.1`.
2. Поместить архив в любую папку, из которой читает `man` в директорию `man1`.
Для того, чтобы узнать директории, из которых читает `man`,
можно выполнить команду `manpath`
В моем случае, я поместил все в директорию `$HOME/.local/share/man/man1`,
так как `$HOME/.local/share` это как раз `$XDG_DATA_HOME`
(см. [спецификацию XDG](https://specifications.freedesktop.org/basedir-spec/latest/)).
Результат ([репозиторий](https://github.com/rustbas/dotfilesV2/tree/potatoless-pc)):
![dotfiles manual](assets/result.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View File

@@ -1,4 +1,4 @@
# Приложение производящей функции последовательности к числам Фибоначчи
# Немного про производящие функции
## Мотивация
Идея данной публикации родилась в процессе чтения статьи на [викиконспектах](https://neerc.ifmo.ru/wiki/index.php?title=%D0%9F%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D1%8F%D1%89%D0%B0%D1%8F_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D1%8F#.D0.9F.D1.80.D0.B8.D0.BC.D0.B5.D1.80.D1.8B_.D1.80.D0.B5.D1.88.D0.B5.D0.BD.D0.B8.D0.B9_.D0.B7.D0.B0.D0.B4.D0.B0.D1.87_.D0.BC.D0.B5.D1.82.D0.BE.D0.B4.D0.BE.D0.BC_.D0.BF.D1.80.D0.BE.D0.B8.D0.B7.D0.B2.D0.BE.D0.B4.D1.8F.D1.89.D0.B8.D1.85_.D1.84.D1.83.D0.BD.D0.BA.D1.86.D0.B8.D0.B9) о производящих рядах. Мне показалось очень интересным, что существует способ решения рекуррентных уравнений с помощью бесконечных сумм.
@@ -50,6 +50,7 @@ _**Математическая индукция** — метод математ
([Википедия](https://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D1%82%D0%B5%D0%BC%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F_%D0%B8%D0%BD%D0%B4%D1%83%D0%BA%D1%86%D0%B8%D1%8F))
Нам понадобится этот метод для того, чтобы доказать верность формулы, которую мы получим. Применяя к нашему случаю, можно сформулировать идею доказательства так:
1. Нужно доказать **базу индукции**. То есть, что формула верна для $a_0$ и $a_1$.
2. Нужно доказать **переход индукции**. В нашем случае, это означает, что нужно проверить, что формула удовлетворяет изначальному рекуррентному уравнению.
@@ -97,31 +98,36 @@ $$
Рассмотрим $(I)$ и $(II)$.
$$\Large{
(I) = \sum_{n=2}^\infty a_{n-1} z^{n-1} = \Big<
(I) = \sum_{n=2}^\infty a_{n-1} z^{n-1} = \left<
\begin{split}
k = n-1\\
n = k+1
\end{split}
\Big> = \sum_{k=1}^\infty a_{k} z^{k} =
\right> = \sum_{k=1}^\infty a_{k} z^{k} =
}$$
$$\Large{
= a_0 + \sum_{k=1}^\infty a_{k} z^{k} - a_0
= \underbrace{a_0 + \sum_{k=1}^\infty a_{k} z^{k}}_
{\sum_{k=0}^\infty a_{k} z^{k}}
- a_0
= \sum_{k=0}^\infty a_{k} z^{k} - a_0 = G(z) - a_0
}$$
$$\Large{
(II) = \sum_{n=2}^\infty a_{n-2} z^{n-2} = \Big<
(II) = \sum_{n=2}^\infty a_{n-2} z^{n-2} =
\left<
\begin{split}
k = n-2\\
n = k+2
\end{split}
\Big> = \sum_{k=0}^\infty a_{k} z^{k} = G(z)
\right>
= \sum_{k=0}^\infty a_{k} z^{k} = G(z)
}$$
Здесь мы производим замену и приводим суммы к виду $\sum_{i=0}^\infty a_iz^i$. Очевидно, значение суммы не зависит от названия счетчика $i$.
Здесь мы производим замену и приводим суммы к виду $\sum\limits_{i=0}^\infty a_iz^i$. Очевидно, значение суммы не зависит от названия счетчика $i$.
Таким образом:
$$\Large{
G(z) = a_0 + a_1 z + z \left( G\left(z\right) - a_0 \right) + z^2G(z) =
}$$
@@ -146,7 +152,7 @@ $$\Large{
G(z) = \frac{a_0 +a_1z-a_0z}{1 - z - z^2}
}$$
*Замечание*: получившееся дробь правильная. То есть степень многочлена в знаменателе больше, чем в числителе.
> *Замечание*: получившееся дробь правильная. То есть степень многочлена в знаменателе больше, чем в числителе.
## Разложение дроби на элементарные дроби
@@ -204,8 +210,8 @@ a_0 + z(a_1 - a_0) = -Az + Az_2 - Bz + Bz_1 = (Az_2 + Bz_1) + z(-A -B)
$$\Large{
\begin{cases}
a_0 = Az_2 + B z_1\\
a_1 - a_0 = -A-B
&Az_2 &+ &B z_1 &= a_0\\
&A &+ &B &= a_0 - a_1
\end{cases}
}$$
@@ -222,11 +228,11 @@ $$\Large{
$$\Large{
\begin{cases}
z_{1} = - \frac{1 + \sqrt{5}}{2}\\
z_{2} = - \frac{1 - \sqrt{5}}{2}\\
A = a_0 - a_1 - \frac{a_0 - a_0z_2 + a_1z_2}{z_1-z_2}\\
B = \frac{a_0 - a_0z_2 + a_1z_2}{z_1-z_2}\\
G(z) = \frac{A}{z - z_1} + \frac{B}{z - z_2}
z_{1} &= - \frac{1 + \sqrt{5}}{2}\\
z_{2} &= - \frac{1 - \sqrt{5}}{2}\\
A &= a_0 - a_1 - \frac{a_0 - a_0z_2 + a_1z_2}{z_1-z_2}\\
B &= \frac{a_0 - a_0z_2 + a_1z_2}{z_1-z_2}\\
G(z) &= \frac{A}{z - z_1} + \frac{B}{z - z_2}
\end{cases}
}$$
@@ -260,6 +266,7 @@ $$\Large{
}$$
Проведя аналогичные вычисления для $B$ получим:
$$\Large{
B = \frac{a_0}{z_1-z_2} - z_2 \frac{a_0-a_1}{z_1-z_2}
}$$
@@ -291,8 +298,9 @@ z_1z_2 = \frac{(1+\sqrt{5})(1-\sqrt{5})}{2\cdot2} = \frac{1-5}{4} = -1
}$$
Подставив результат в наше выражение:
$$\Large{
-\frac{a_0}{-1} = a_0, \text{Q.E.D.}
-\frac{a_0}{-1} = a_0, \text{ Q.E.D.}
}$$
#### $n = 1$
@@ -335,6 +343,7 @@ $$\Large{
}$$
Как мы доказали:
$$\Large{
z_1z_2 = -1
}$$
@@ -344,7 +353,9 @@ z_1z_2 = -1
$$\Large{
z_1+z_2 = \frac{-1-
\cancelto{0}{\sqrt{5}+\sqrt{5}}
-1}{2} = -1
-1}{2} =
\frac{-1-1}{2} =
-1
}$$
Подставив значения в выражение, получим:
@@ -360,7 +371,7 @@ $$\Large{
= -\left(
\cancelto{0}{a_0 - a_0}
-a_1
\right) = -(-a_1) = a_1, \text{Q.E.D.}
\right) = -(-a_1) = a_1, \text{ Q.E.D.}
}$$
### Переход индукции
@@ -483,12 +494,13 @@ $$\Large{
$$\Large{
= -A \frac{1}{z_1^{n+3}}
-B \frac{1}{z_2^{n+3}} =
a_{n+2}, \text{Q.E.D.}
a_{n+2}, \text{ Q.E.D.}
}$$
## Выводы
В данной публикации были рассмотрены:
- получение производящей функции из рекуррентного уравнения;
- разложение функции в ряд для нахождения $n$-го члена последовательности;
- доказана верность полученной формулы с помощью математической индукции.

View File

@@ -1,7 +1,9 @@
# Математика
# Статистика
## 2024-10-30 [Немного про производящие функции](gen_fun.md)
## 2024-09-24 [Немного про Байесовскую статистику](baes.md)
## 2024-10-30 [Приложение производящей функции последовательности к числам Фибоначчи](gen_fun.md)
## 2020-09-01 [Немного про проверку гипотез](stat-madness.md)
## 2025-05-30 [Немного про работу с файлами, numpy и предсказаниях](type-pred.md)

199
docs/maths/stat-madness.md Normal file
View File

@@ -0,0 +1,199 @@
# Немного про проверку гипотез
## Введение
Любые статистические испытания зиждятся на проверке гипотез, например:
1. Проверка действия лекарств.
2. Установление зависимости между явлениями.
3. A/B тестирование и пр.
В зависимости от вида данных, целей исследования и других факторов
можно по-разному формулировать гипотезы и по-разному их проверять.
Многое зависит от не только знаний и опыта исследователя, но и в целом
от его подхода. В процессе работы можно все меньше уделять внимание
математической составляющей и все больше полагаться на компьютер и его
вычислительные мощности.
Здесь я хочу рассказать о стадиях, через которые проходит исследователь,
в попытках упростить себе жизнь и ускорить процесс проверки гипотез.
## Небольшой ликбез
В статистике, если упростить, проверку гипотезы можно описать так:
1. По данной выборке считается статистика (т.е. функция от выборки).
2. Из распределения статистики находятся две области, где гипотеза отвергается и где нет. Исходя из этого, принимается решение.
**N.B.** Проверяется гипотеза, модель постулируется.
## Стадия 1. Строгие доказательства
На данной стадии ученый строго выводит распределения статистик, чтобы построить как можно более хорошие критерии.
$$\Large
\sqrt{n}
\frac
{\overline{\mathbb{X}} - \mu}
{S} =
\sqrt{n}
\frac
{\overline{\mathbb{X}} - \mu}
{\sigma} \cdot
\frac{1}
{\frac{S}{\sigma}} =
$$
$$\Large
= \sqrt{n}
\frac
{\overline{\mathbb{X}} - \mu}
{\sigma} \cdot
\frac{1}
{\sqrt{\frac{(n-1)S^2}{\sigma^2}\cdot
\frac{1}{n-1}
}}
$$
Получим:
$$\Large
\begin{matrix}
&\sqrt{n}
\frac{\overline{\mathbb{X}} - \mu}
{\sigma} &\sim &N(0,1) \\
&\frac{(n-1)S^2}{\sigma^2} &\sim &\chi^2(n-1)
\end{matrix}
$$
Таким образом, по [определению](https://ru.wikipedia.org/wiki/Распределение_Стьюдента#Определение):
$$\Large
\sqrt{n}
\frac
{\overline{\mathbb{X}} - \mu}
{S} \sim t(n-1).
$$
## Небольшой пример (критерий Стьюдента)
**Дано**: выборка Х объема 10
$$\Large
\mathbb{X} = \left(
\begin{matrix}
3.175 \\
4.042 \\
2.127 \\
3.841 \\
1.699 \\
2.223 \\
3.211 \\
3.33 \\
2.447 \\
2.904
\end{matrix}
\right)
$$
**Модель**: $N(\mu, \theta_2)$
**Нулевая гипотеза**: $\mu = 3$
**Решение**:
Статистика критерия:
$$\Large
T(\mathbb{X}) =
\sqrt{n}
\frac
{\overline{\mathbb{X}} - \mu}
{S}
\sim
t(n-1)
$$
Статистика равна:
$$\Large
T(\mathbb{X}) = -1.9066
$$
Пусть уровень значимости $\alpha = 0.05$.
Область, где не отвергается нулевая гипотеза: $(g_1, g_2) = (-2.262, 2.262)$, т.е. это область, которую принимает значение статистики при условии верности нулевой гипотезы с вероятностью $1 - \alpha = 0.95$. $g_1$ в данном случае это $0.025$-квантиль, а $g_2$, соотвественно, 0.975-квантиль.
![Доверительный интервал](assets/stat-madness/conf_interval.png)
Красным обозначен интервал $(g_1, g_2)$
Таким образом, нулевая гипотеза не отвергается, так как значение статистики лежит в данном интервале.
> **Примечание**: можно было выбрать доверительный интервал иначе,
> но его стараются выбрать так, чтобы минимизировать его длину.
## Стадия 2. Открытие моделирования
Иногда (вернее, даже как правило) распределение статистики вывести
невозможно. В таком случае пользуются моделированием. Идея в том, что
нам известно распределение выборки в случае нулевой гипотезы. Таким
образом, можно многократно генерировать выборки и считать статистику,
таким образом получив ее распределение.
![Открытие моделирования](assets/stat-madness/modeling.png)
В данном случае, моделирование выборки проводилось
в условиях $X \sim N(\mu, S^2)$.
Можно увидеть некоторое расхождение. В этом, кстати, заключается интересный
момент. Часто критикуются исследования построенные на моделировании, так как
есть ненулевая (хоть и очень маленькая) вероятность, что выборки
сгенерировались так, что полученное распределение статистики плохо отражает
реальность.
## Стадия 3. Бутстрэп
Бывают случаи, когда распределение выборки неизвестно совсем
(или его сложно/нельзя в обычном смысле генерировать,
[пример](https://stepik.org/lesson/40491/step/1?unit=24794)). В таком случае
постулируют, что данная выборка хорошо отражает генеральную совокупность и в
качестве функции распределения берут эмпирическую функцию распределения.
$$\Large
F_n(x) = \frac
{\sum_{i=1}^{n} \mathbb{1}(x)}
{n}
$$
где:
$$\Large
\mathbb{1}(x) =
\begin{cases}
1, x > X_i, \\
0, \text{ иначе.}
\end{cases}
$$
В итоге, получается, что для проверки гипотез не нужно ничего кроме выборки и выдуманной статистики (которая, вообще, может быть любой, от нее зависит только качество получаемого критерия).
Основная идея заключается в том, чтобы генерировать выборки объемом как и данная выборка из следующего распределения:
$$\Large
\mathcal{F} =
\begin{pmatrix}
X_1 &X_2 &\cdots &X_n \\
\frac{1}{n} &\frac{1}{n} &\cdots &\frac{1}{n}
\end{pmatrix}.
$$
![Результат на выборке объема 10](assets/stat-madness/bootstrap.png)
Таким образом, из расхождения графиков можно сделать следующие выводы:
- применение бутстрэпа требует большой объема первоначальной выборки,
- наблюдения в выборке должны быть независимыми.
Несмотря на это, он часто применяется невпопад, так как не требует особых затрат на реализацию.

166
docs/maths/type-pred.md Normal file
View File

@@ -0,0 +1,166 @@
# Немного про работу с файлами, numpy и предсказаниях
## Введение
Известно, что файлы в памяти представлены последовательностью байтов.
Структурно, эта последовательность может быть разной. Она может
содержать только ASCII-текст, текст с любой кодировкой, сжатый архив,
mp3, etc. При взаимодействии с файлом (например, открыть файл
текстовым редактором), операционная система не смотрит на
т.н. **расширение файла**, её интересует *побайтовое* содержание
файла.
В Unix для определения типа файла есть утилита `file`. Как она
определяет тип я точно не знаю, но могу сказать, что частично метод
основан на *"заголовке"* файла (первых байтах).
Пример работы `file` на исполняемом файле:
```
./program: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, ...
```
Шестнадцатеричное представление (первые несколько строк) с помощью
`xxd`:
```console
00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
00000010: 0300 3e00 0100 0000 6010 0000 0000 0000 ..>.....`.......
00000020: 4000 0000 0000 0000 c036 0000 0000 0000 @........6......
00000030: 0000 0000 4000 3800 0d00 4000 1f00 1e00 ....@.8...@.....
```
В начале видно последовательность `ELF` -- формат исполняемых файлов в
Unix[1].
Возникает вопрос: **есть какой-то паттерн для различных типов файлов,
который можно увидеть, не считая специальных симвовол в *заголовке*?**
Можно усложнить вопрос: можно ли по какому-то обобщению (*сигнатуре*)
файла предсказать его тип? Попробуем это выяснить.
Для этого нужно решить следующие задачи:
1. Написать модуль (**на Си**), который по имени файла просчитывает
сигнатуру и возвращает её;
2. Посмотреть, как выглядят эти сигнатуры;
3. Попробовать обучить простую нейросеть.
## Как считать сигнатуру файла
Возьмем нулевую матрицу `M` размера 256х256, так как один байт это
число от 0 до 255. Считаем файл в память в виде последовательности
байтов. Теперь будем двигаться по последовательности с окном
размера 2. В этом окне первый элемент будет отвечать за номер строки,
а второй за номер столбца. И каждый раз с окном `(x, y)` будем
увеличивать элемент матрицы `M[x][y]` на единицу.
![](./assets/type-pred/file_sig.png)
## Причины использования Си
Если **кратко**: python очень медленный. Например, средний `wav`-файл
занимает около 10 мегабайт. Это порядка десяти миллионов байт, по
которым нужно пробежать и заполнить матрицу. А для обучения нейросети,
таких файлов должно быть много.
**Отдельный интерес**, также, представляет возможность написать модуль
для python на C, который умеет взаимодействовать с API библиотеки
NumPy.
## Чтение файлов в память
Для чтения файла в память, был написан модуль на Си, доступный
репозитории[2]. Здесь кратко опишу, как он работает.
В нем реализована функция `signature_from_filepath_by2`, которая
получает на вход два параметра: имя файла и уровень `verbose`. `by_2`
в названии обусловлено тем, что работа не с матрицами, а `n`-мерными
тензорами улучшает качество предсказания.
Функция `read_file` считывает файл в структуру `raw_data`, которая
представляет собой просто последовательность байтов и размер этой
последовательности. После этого функция `build_matrix` считывает по
этой струтуре сигнатуру и записывает в `matrix`.
Далее создается объект `PyObject *result`, представляющий собой
указатель на массив `NumPy` типа `uint32`. На его основе создается
динамический массив `result_data`.
Так как `matrix` лежит в памяти последовательно (ввиду того, что
она аллоцирована на стеке), то её можно просто скопировать в
`result_data`. После всего этого возвращается указатель `*result`.
Помимо этого в коде много второстепенных действий, которые требует API
Python для работы. Эти подробности я опустил, их можно увидеть в коде,
все достаточно предсказуемо.
## Пайплайн обучения нейросети
**Нюанс обучения нейросети**: так как получившиеся матрицы вышли очень
неравномерными, дополнительно они были размыты [*методом
Гаусса*](https://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D0%B7%D0%BC%D1%8B%D1%82%D0%B8%D0%B5_%D0%BF%D0%BE_%D0%93%D0%B0%D1%83%D1%81%D1%81%D1%83).
Для обучения нейросети необходимо создать матрицу меток. Так как
предполагается, что нейросеть будет предсказывать различные типы
файлов, то матрица меток будет иметь размер `M*NxM`, где:
- `M` -- количество типов файлов
- `N` -- количество файлов в одном типе (берется минимальное из всех,
чтобы обучение было равномерным)
Для разбиения на тренировочную и обучающию выборки отлично подходит
функция `train_test_split` из модуля `sklearn.model_selection`.
Сам перцептрон будет иметь следующую архитектуру:
1. На входном слое будет 65536 нейронов (`256х256`). Функцией активации
будет `ReLu`-функция.
2. Скрытый слой будет иметь 512 нейронов и `sigmoid`-функцию активации.
3. На выходе будет столько нейронов, сколько типов файлов нужно будет
предсказать.
Для для задания `loss`-функции и оптимизатора:
```python
loss_fn = nn.CrossEntropyLoss()
optimizer = t.optim.SGD(model.parameters(), lr=1e-3)
```
Цикл обучения в данном случае состоял из 250 эпох.
Пайплайн обучения можно будет найти в репозитории
[проекта](https://github.com/rustbas/filetype-prediction), вместе с
инструкцией по воспроизведению результатов (кроме того факта, что
файлы различных типов нужно будет скачать самому).
## Результаты и картинки
Усреденные сигнатуры различных типов файлов можно увидеть ниже.
![](./assets/type-pred/heatmaps.png)
Также, показатели обучения:
![](./assets/type-pred/stats.png)
## Выводы
По итогу, можно сказать, что в некоторых случаях, *сигнатура* файла
является неплохим предиктором его типа.
Гипотетически, это можно использовать для следующих идей:
1. Восстановление частично поврежденных файлов, так как можно попытаться
угадать его структуру и восстановить её.
2. Определение исполняемых файлов при анализе вредоносного ПО.
3. Обнаружение скрытых данных (когда сигнатура файла и его тип не
соответствуют друг другу).
## Источники
1. [Википедия про ELF-формат](https://ru.wikipedia.org/wiki/Executable_and_Linkable_Format);
2. [Репозиторий проекта](https://github.com/rustbas/filetype-prediction);
3. [Основание идеи заметки](https://youtu.be/AUWxl0WdiNI?si=mklboGVUC-mZ-d1M);
1. [Пояснение про сигнатуру](https://youtu.be/4bM3Gut1hIk?si=zSGWLHKTKW7bStPb);
4. [Модули для Python](https://youtu.be/45TOazYbedI?si=jykTbnbjcyzTsN0r).

View File

@@ -3,23 +3,45 @@ site_url: https://rustbas.github.io/blog
repo_url: https://github.com/rustbas/blog
edit_uri: edit/main/docs/
theme:
name: terminal
palette: dark
name: material
palette:
- scheme: default
toggle:
icon: material/toggle-switch
name: Switch to dark mode
primary: green
- scheme: slate
toggle:
icon: material/toggle-switch-off-outline
name: Switch to light mode
primary: teal
features:
- revision.date
- revision.history
- navigation.side.hide
- navigation.instant # TODO: check troubles with TeX loading
- navigation.instant.progress
- header.autohide
icon:
repo: fontawesome/brands/git
font:
# text: Roboto
code: JetBrains Mono
# - revision.date
# - revision.history
# - navigation.side.hide
nav:
# - "Обо мне": 'index.md'
- "Математика": 'maths/index.md'
- "Linux": 'linux/index.md'
- "Общее": 'common/index.md'
plugins:
- search:
lang: ["ru", "en"]
indexing: 'full'
- git-revision-date
markdown_extensions:
- pymdownx.arithmatex:
generic: true