Назад
1015

ONNX с секретом

1015

Задача:

Эта «модель» хранит в себе секрет: если в неё подать что-то очень определённое — она ответит строчкой, которую ни с чем не перепутаешь.

model.onnx

Решение

ONNX-модели удобно визуализировать при помощи Netron. Посмотрим в нём на нашу модель:

Во-первых, можно заметить, что у модели 3 входа.

А ещё пройдя через пару cast-ов и relu, эти входы перемножатся и сравнятся с числом 1547.

Если мы провалимся в ветку else (равенство с 1547 не выполняется), то увидим следующее:

Из этой ветки выходит 3 константы, каждая из которых — вектор из ноликов. Вряд ли нас ждёт что-то интересное, если мы будем переходить по этой ветке.

Теперь исследуем then-ветку (выполняется равенство с 1547):

В этой ветке всё схоже с else, но вектора уже не нулевые, а более интересные 🙂

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

Теперь разберёмся, как нам попасть в ветку then:

Наши входы проходят через relu, а затем кастуются в int. После этого их произведение сравнивается с числом 1547.

1547 = 7 × 13 × 17

И поскольку наши входы проходили через relu, не стоит подавать во вход, например (-7, -13, 17).

Подадим нашей модели на вход числа 7, 13, 17:

import numpy as np
import onnxruntime as ort

sess = ort.InferenceSession("model.onnx")

inputs = {
    "x": np.array(7, dtype=np.int64),
    "y": np.array(13, dtype=np.int64),
    "z": np.array(17, dtype=np.int64),
}
out = sess.run(None, inputs)[0]
print(out)

# prints
#[112 118 107 113 133  99  89  95 105  97  83  72  89  73  72  72  82  89
#  78  59  77  69  91  63  75  74  67  78  61  80  79  29  29  29 121]

В задании нам обещали строку, а здесь — массив чисел 🤔
Переведём его в строку при помощи chr:

print("".join(chr(c) for c in out))
#pvkq
#cY_iaSHYIHHRYN;ME[?KJCN=POy

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

Попробуем перебрать порядок, в котором числа 7, 13, 17 будут подаваться в модель:

import itertools

import numpy as np
import onnxruntime as ort

sess = ort.InferenceSession("model.onnx")
inputs = (7, 13, 17)
for x, y, z in itertools.permutations(inputs):
    inputs = {
        "x": np.array(x, dtype=np.int64),
        "y": np.array(y, dtype=np.int64),
        "z": np.array(z, dtype=np.int64),
    }
    out = sess.run(None, inputs)[0]
    print("".join(chr(c) for c in out))
    
# prints:
#pvkq
#cY_iaSHYIHHRYN;ME[?KJCN=POy
#pvkq
#cY_iaSDUEDDNUJ7IA_CONGRATS!!!}
#jpek]SYc[MN_ONNX_TASK[?KJCN=POy
#jpek]SYc[MDUEDDNUJ7IAeIUTMXGZY'''
#flag{YOU_WIN_ONNX_TASK_CONGRATS!!!}
#flag{YOU_WIHYIHHRYN;MEeIUTMXGZY'''

Несложно заметить строчку flag{YOU_WIN_ONNX_TASK_CONGRATS!!!}, которая и является решением.

Телеграм-канал

DeepSchool

Короткие посты по теории ML/DL, полезные
библиотеки и фреймворки, вопросы с собеседований
и советы, которые помогут в работе

Открыть Телеграм

Увидели ошибку?

Напишите нам в Telegram!