Arm CMSIS-NN предоставил пример входных данных и ожидаемые выходные данные здесь (https://github.com/ARM-software/CMSIS-N ... oftmax_s16) в их тестовом примере.
Изначально мой первое впечатление было, что я не смогу это использовать коробки, потому что когда я смотрю на данные конфигурации тестовых случаев (https://github.com/ARM-software/CMSIS-N ... fig_data.h), Я вижу два параметра конфигурации softmax_s16_input_mult и softmax_s16_input_left_shift, которые я не совсем понял.
Кроме того, в тестовом примере кажется, что они обращаются к экспоненте посмотреть таблицу (https://github.com/ARM-software/CMSIS-N ... lut_data.h) и поочередную таблицу поиска (https://github.com/ARM-software/CMSIS-N ... lut_data.h). Я также изучил это (например, таблицу экспоненциального поиска), которая, по-видимому, получается путем равномерного создания значений от -10 до 0, а затем для каждой точки они вычисляют e^x и масштабируют его от [2^1 до (2^15)-1].
Я покопался еще немного и нашел здесь (https://github.com/ARM-software/CMSIS-N ... ettings.py), что input_scale, который используется для генерации параметров конфигурации softmax_s16_input_mult и softmax_s16_input_left_shift — параметр по умолчанию. Итак, один вопрос, который меня интересует: для моего варианта использования мне нужно будет использовать разные softmax_s16_input_mult и softmax_s16_input_left_shift или я могу просто получить отказаться от использования этого множителя «по умолчанию» и предоставленного сдвига.
Например, для моего варианта использования у меня есть 16-битный входной сигнал,
Код: Выделить всё
#include
static const int16_t logits[15] = {2019, 4958, 1855, -230, -7992, 1396, -1919, 2611, 658, 3588, 885, -4759, 3426, 1348, 5906};
Код: Выделить всё
def get_s16_exp_lut(input_range : list[int, int], num_vals : int, num_bits: int) -> np.array:
"""
Takes in the specificed input range and the specified number of entries from CMSIS,
and computes the exponential of each point and scales it to num_bits range.
Example
--------
exp_lut = get_s16_exp_lut([-10, 0], 513, 16)
"""
in_arr = np.linspace(input_range[0], input_range[1], num_vals)
exp_in_arr = np.exp(in_arr)
min_val = -2**(num_bits-1)
max_val = 2**(num_bits - 1) - 1
normalised_exp = (exp_in_arr - np.min(exp_in_arr)) / (np.max(exp_in_arr) - np.min(exp_in_arr))
scaled_exp = normalised_exp * (max_val - min_val) + min_val
exp_lut_arr = np.round(scaled_exp).astype(np.int16)
return exp_lut_arr
Мой главный вопрос: могу ли я обойтись без используя предоставленные softmax_s16_input_mult и softmax_s16_input_left_shift, или мне нужно выяснить входной сдвиг влево и множитель для моего случая, и если да, то что бы вы предложили Я так и делаю (если это поможет, пример битового ввода S16, которым я поделился выше, был получен с использованием этой библиотеки). При этом после ручного выполнения всех операций на каждом слое моей модели конечный результат (т. е. логиты) представляет собой дробный объект с фиксированной запятой, который имеет в общей сложности 16 бит, причем 9 бит выделены для дробной части моих данных, 6 бит. выделено для целого числа и 1 бит для знака.
В общем, я прав, для моего варианта использования мне понадобится
< ul>
[*]А [-2^15, 2^15-1] таблица экспоненциального поиска
[*]A [-2^15, 2^15-1] таблица поиска one_by_one
[*]Входной множитель
[*]Введите сдвиг влево
или можно обойтись без использования доступного входного множителя и ввести левый сдвиг?
Подробнее здесь: https://stackoverflow.com/questions/792 ... mbedded-ml
Мобильная версия