Оценка модели keras с квантованными весами после обучения

У меня есть модель, обученная керасу, и она сохраняется в виде файла.h5. Модель обучается с использованием значений с плавающей запятой одинарной точности и тензорного бэкэнда. Теперь я хочу реализовать аппаратный ускоритель, который выполняет операцию свертки на ПЛИС Xilinx. Однако, прежде чем я определюсь с шириной битов с фиксированной точкой, которая будет использоваться на ПЛИС, мне нужно оценить точность модели, квантовая веса до 8 или 16-битных чисел. Я наткнулся на квантирование тензорного потока, но я не уверен, как я могу брать весовые коэффициенты с каждого слоя, определять его количественно и сохранять в списке массивов. После того, как все слои квантованы, я хочу установить веса модели для вновь сформированных квантованных весов. Может ли кто-нибудь помочь мне сделать это?

Это то, что я пытался уменьшить точность с float32 до float16. Пожалуйста, дайте мне знать, если это правильный подход.

for i in range(len(w_orginal)):
temp_shape = w_orginal[i].shape
print('Shape of index: '+ str(i)+ 'array is :')
print(temp_shape)
temp_array = w_orginal[i]
temp_array_flat = w_orginal[i].flatten()
for j in range(len(temp_array)):
    temp_array_flat[j] = temp_array_flat[j].astype(np.float16)

temp_array_flat = temp_array_flat.reshape(temp_shape)
w_fp_16_test.append(temp_array_flat)

1 ответ

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

Если я вас правильно понимаю, у вас есть модель тензорного потока (float32), которую вы хотите квантовать в int8 и сохранять в numpy.array,

Во-первых, вы должны прочитать все веса для каждого слоя, который может быть список Python или numpy.array или что-то еще, это не имеет значения.

Тогда алгоритм квантования существенно повлияет на точность, вы должны выбрать лучший для вашей модели. Тем не менее, эти алгоритмы имеют одну и ту же базовую шкалу. Все, что вам нужно сделать, это масштабировать все веса до -127 до 127(int8), как scale слой без biasи запишите масштабный коэффициент.

Между тем, если вы хотите реализовать это на ПЛИС, данные тоже должны быть цианированы. Здесь у нас есть новая проблема - результатом int8 * int8 является int16, что является очевидным переполнением.

Чтобы решить эту проблему, мы создаем новый параметр - shift - для сдвига результата int16 обратно в int8. Обратите внимание, что shift параметр не будет константой 8, предположим, что у нас 0 * 0 = 0, нам вообще не нужно сдвигать результат.

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

После того, как вся сеть закончилась на FPGA, если вы хотите деквантовать int8 до float32, просто используйте последний параметр масштаба (конечного результата), чтобы сделать несколько mul/div(зависит от того, как вы определяете scale).

Это основной алгоритм квантования, другие как tf.quantization может иметь более высокую точность. Теперь у нас есть квантованная модель, вы можете сохранить ее во что угодно, это не тяжелая работа.

PS почему нюми? bin-файл лучше всего подходит для FPGA, не так ли?

И есть ли у вас какие-либо идеи о реализации Softmax на FPGA? Я запутался в этом...

Другие вопросы по тегам