Как уменьшить количество ядер / фильтров в обученной модели в Tensorflow? - PullRequest
0 голосов
/ 10 октября 2019

Если у меня есть обученная модель, где я хочу переобучить ту же модель, с несколькими фильтрами / ядром, удаленными из существующей модели. например,

conv1 = tf.get_variable('conv1_1', shape=(11, 11, 3, 64), initializer=tf.contrib.layers.xavier_initializer()),

, и я хочу изменить этот тензор так, чтобы он имел форму (11, 11, 3, 20), но с тем же именем и положением, означая точно такую ​​же переменную. Заранее спасибо за помощь.

Я пробовал tf.reshape, но это дает мне ошибку несоответствия количеству элементов в a и b Я также пробовал tf.assign(a,b, validate_shape=false)

self.weights = {
    'conv1_': tf.get_variable('conv1_l1', shape=(11, 11, 3, 64), initializer=tf.contrib.layers.xavier_initializer()),
    'conv2_': tf.get_variable('conv2_l1', shape=(7, 7, 64, 128), initializer=tf.contrib.layers.xavier_initializer())
}

Ответы [ 2 ]

0 голосов
/ 10 октября 2019

По сути, вы меняете количество параметров вашей модели. При переходе от

conv1 = tf.get_variable('conv1_1', shape=(11, 11, 3, 64), initializer=tf.contrib.layers.xavier_initializer())

к

conv2 = tf.get_variable('conv2_l1', shape=(11, 11, 3, 20), initializer=tf.contrib.layers.xavier_initializer())

Ваши изучаемые параметры переходят от {Kernel x 64} к {Kernel x 20}. Это потребует от вас переподготовки сети иузнать его новые веса.

Однако это общая проблема, которая превратилась в область исследований. Для этого было предложено много методов, таких как аппроксимация весов низкого ранга (Denton et al., 2014; Lebedev et al., 2014), квантование веса (Courbariaux et al., 2016; Rastegari et al., 2016), знаниеперегонка (Hinton et al., 2014; Romeroet al., 2015) и сетевое сокращение (Han et al., 2015; Li et al., 2017), среди которых сетевое сокращение приобрело заметное внимание благодаря своей конкурентоспособной производительности и совместимости.

Ссылки на исследование:

  1. Эмили Л. Дентон, Войцех Заремба, Джоан Бруна, Янн ЛеКун и Роб Фергус. Использование линейной структуры в сверточных сетях для эффективной оценки. InNIPS, 2014.
  2. Вадим Лебедев, Ярослав Ганин, Максим Рахуба, Иван Оселедец и Виктор Лемпицкий. Ускорение сверточных нейронных сетей с использованием тонко настроенной cp-декомпозиции. ICLR, 2014.
  3. Матье Курбаро, Итай Хубара, Даниэль Судри, Ран Эль-Янив и Йошуа Бенжио. Бинаризованные нейронные сети: обучение глубоких нейронных сетей с весами и активациями, ограниченными препринтом + 1 или -1. ArXiv. ArXiv: 1602.02830, 2016
  4. Джеффри Хинтон, Ориол Виньялс и Джефф Дин. Перегонка знаний в нейронной сети. NIPSWorkshop, 2014.
0 голосов
/ 10 октября 2019

То, что вы хотите сделать, частично достижимо.

Наличие переменной с точно таким же именем, как у уже определенного, вероятно, невозможно. Потому что TensorFlow создает граф потока данных, и каждый узел должен быть уникально идентифицирован (чтобы избежать неоднозначностей). Если вам нужно одно и то же имя, вы можете сделать это, используя переменную область видимости с разными областями действия.

Но для присвоения части переменной другой, вы можете использовать следующий код:

import tensorflow as tf
import numpy as np

tf.reset_default_graph()

with tf.variable_scope('old'):
  conv1 = tf.get_variable('conv1_1', shape=(11, 11, 3, 64), initializer=tf.contrib.layers.xavier_initializer())
with tf.variable_scope('new'):
  conv_res_1 = tf.get_variable('conv1_1', shape=(11, 11, 3, 20), initializer=tf.contrib.layers.xavier_initializer())

assign_op = tf.assign(conv_res_1,conv1[:,:,:,:20])

with tf.Session() as sess:
  tf.global_variables_initializer().run()
  w_1, w_res_1 = sess.run([conv1, assign_op])
  assert np.all(w_1[:,:,:,:20] == w_res_1)
  print(w_1[0,0,0,0], w_res_1[0,0,0,0])  

Обновление : если вы в порядке с потерей переменной большего размераВы можете сделать следующее. Это возьмет conv_1 и заменит переменную меньшей.

import tensorflow as tf

tf.reset_default_graph()
conv1 = tf.get_variable('conv1_1', shape=(11, 11, 3, 64), initializer=tf.contrib.layers.xavier_initializer())

assign_op = tf.assign(conv1, conv1[:,:,:,:20], validate_shape=False)

with tf.Session() as sess:
  tf.global_variables_initializer().run()
  sess.run(assign_op)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...