оценка модели keras с квантованными весами после тренировки

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

Это то, что я до сих пор пытался снизить точность с 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)

person frisco_1989    schedule 15.10.2018    source источник


Ответы (1)


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

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

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

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

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

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

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

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

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

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

А есть ли у вас идеи о реализации softmax на ПЛИС? Я сбит с толку ...

person ID.W    schedule 17.10.2018
comment
Да ... Это то, что я пытаюсь ... Но извините, я не понимаю, как я могу взять число float32 и масштабировать до int8, которое находится в диапазоне от -127 до 127 ... Это несколько сбивает с толку мне. Далее идет обработка переполнения ... Если результат больше 127 или меньше -127 ... Я просто устанавливаю максимально возможное значение ... Это то, что я пытаюсь ... Но keras внутренне принимает эти только значения с плавающей запятой 32 - person frisco_1989; 17.10.2018
comment
Квантование похоже на обратный процесс, вы можете попытаться масштабировать результат до int8, тогда вы будете знать диапазон масштабированных входных данных, а входные данные являются результатом предыдущего слоя ... - person ID.W; 18.10.2018
comment
Извините, я понятия не имею, как получить число float32 из keras ... Но я думаю, что это основная функция, которую должны иметь keras. Попробуйте найти его в руководстве пользователя? - person ID.W; 18.10.2018