Как изменить модель Imagenet Caffe?

Я хотел бы изменить модель кафе ImageNet, как описано ниже:

Поскольку номер входного канала для временных сетей отличается от номера для пространственных сетей (20 против 3), мы усредняем фильтры модели ImageNet первого уровня по каналу, а затем копируем средние результаты 20 раз в качестве инициализации временных сетей.

Мой вопрос в том, как я могу достичь вышеуказанных результатов? Как я могу открыть модель кафе, чтобы внести в нее эти изменения?

Я прочитал учебник по сетевой хирургии, но он не описывает необходимую процедуру.

Спасибо вам за вашу помощь!

АМайер


person AMayer    schedule 08.12.2016    source источник


Ответы (1)


руководство по Net Surgery должно дать вам необходимые основы это. Но позвольте мне объяснить шаги, которые вам нужно сделать более подробно:

  1. Подготовьте сетевые архитектуры .prototxt: вам потребуются два файла: существующий файл ImageNet .prototxt и ваша новая временная сетевая архитектура. Вы должны сделать все слои, кроме первых сверточных слоев, идентичными в обеих сетях, включая имена слоев. Таким образом, вы можете использовать файл ImageNet .caffemodel для автоматической инициализации весов.

    Поскольку первый свёрнутый слой имеет другой размер, вы должны дать ему другое имя в файле .prototxt, чем в файле ImageNet. В противном случае Caffe попытается инициализировать этот слой также с существующими весами, что не удастся, поскольку они имеют разные формы. (Это то, что происходит при редактировании вашего вопроса.) Просто назовите его, например. conv1b и соответствующим образом измените все ссылки на этот слой.

  2. Загрузите сеть ImageNet для тестирования, чтобы вы могли извлечь параметры из файла модели:

    net = caffe.Net('imagenet.prototxt', 'imagenet.caffemodel', caffe.TEST)
    
  3. Извлеките веса из этой нагруженной модели.

    conv_1_weights = old_net.params['conv1'][0].data
    conv_1_biases = old_net.params['conv1'][1].data
    
  4. Усредняем веса по каналам:

    conv_av_weights = np.mean(conv_1_weights, axis=1, keepdims=True)
    
  5. Загрузите новую сеть вместе со старым файлом .caffemodel, так как все слои, кроме первого, напрямую используют веса из ImageNet:

    new_net = caffe.Net('new_network.prototxt', 'imagenet.caffemodel', caffe.TEST)
    
  6. Назначьте расчетные средние веса новой сети.

    new_net.params['conv1b'][0].data[...] = conv_av_weights
    new_net.params['conv1b'][1].data[...] = conv_1_biases
    
  7. Сохраните свои веса в новый файл .caffemodel:

    new_net.save('new_weights.caffemodel')
    
person hbaderts    schedule 08.12.2016
comment
Спасибо, что поделились своими знаниями. Я тестирую это прямо сейчас. Я сообщу вам в ближайшее время о том, как это прошло. Я ценю помощь. - person AMayer; 08.12.2016
comment
Я обнаружил ошибку. Я обновил основной пост кодом, который я использовал на основе вашего предложения для лучшего понимания проблемы. Позже я удалю код, чтобы не смущать новых читателей. Что я там сделал не так? Благодарю вас! - person AMayer; 08.12.2016
comment
Мне удалось пройти эту ошибку, но столкнулся с другой. Я обновил основной пост. Благодарю вас! - person AMayer; 08.12.2016
comment
@AMayer Я отредактировал свой ответ (шаг 1 и код на шаге 6), чтобы описать, как исправить ошибку. Пожалуйста, дайте мне знать, если это решит вашу проблему. - person hbaderts; 08.12.2016
comment
Он исправил предыдущую ошибку, но теперь я получаю следующую ошибку: new_net.params['conv1b'][0].data[...] = conv_av_weights ValueError: не удалось передать входной массив из формы (96,11,11) в форму (96,20,11,11) - person AMayer; 09.12.2016
comment
Упс, кажется, мы потеряли ось по пути ;) См. отредактированный шаг 4. - person hbaderts; 09.12.2016
comment
Это исправлено, но есть еще одно. Вот ошибка: new_net.params['conv1b'][1].data = conv_1_biases AttributeError: невозможно установить атрибут. Благодарю вас! Я искренне ценю ваше время и усилия. - person AMayer; 09.12.2016
comment
Можете попробовать добавить [...] после data, как показано на шаге 6? Я забыл это раньше и добавил это в последнем редактировании. Надеюсь, теперь это работает :) - person hbaderts; 09.12.2016
comment
что означает [...]? - person ng0323; 06.12.2018
comment
С помощью [...] вы изменяете data на месте, то есть копируете данные в то место, где сейчас указывает data. Без [...] это изменило бы ссылку, чтобы указать на conv_av_weights вместо копирования данных. Подробнее см. этот ответ. - person hbaderts; 06.12.2018