В моем эксперименте MxNet мог забыть сохранить некоторые параметры моей сети.
Я изучаю пакет mxnet gluoncv (https://gluon-cv.mxnet.io/index.html). Чтобы научиться у инженеров навыкам программирования, я вручную генерирую SSD с помощью «gluoncv.model_zoo.ssd.SSD». Параметры, которые я использую для инициализации этого класса, такие же, как у официальной сети 'ssd_512_resnet50_v1_voc', кроме 'classes=('car', 'pedestrian', ' грузовик', 'светофор', 'байкер')'.
from gluoncv.model_zoo.ssd import SSD
import mxnet as mx
name = 'resnet50_v1'
base_size = 512
features=['stage3_activation5', 'stage4_activation2']
filters=[512, 512, 256, 256]
sizes=[51.2, 102.4, 189.4, 276.4, 363.52, 450.6, 492]
ratios=[[1, 2, 0.5]] + [[1, 2, 0.5, 3, 1.0/3]] * 3 + [[1, 2, 0.5]] * 2
steps=[16, 32, 64, 128, 256, 512]
classes=('car', 'pedestrian', 'truck', 'trafficLight', 'biker')
pretrained=True
net = SSD(network = name, base_size = base_size, features = features,
num_filters = filters, sizes = sizes, ratios = ratios, steps = steps,
pretrained=pretrained, classes=classes)
Я пытаюсь передать в эту сеть искусственные данные x, и это дает следующие ошибки.
x = mx.nd.zeros(shape=(batch_size,3,base_size,base_size))
cls_preds, box_preds, anchors = net(x)
RuntimeError: Parameter 'ssd0_expand_trans_conv0_weight' has not been initialized. Note that you should initialize parameters and create Trainer with Block.collect_params() instead of Block.params because the later does not include Parameters of nested child Blocks
Это разумно. SSD использует функцию 'gluoncv.nn.feature.FeatureExpander' для добавления новых слоев в '_resnet50_v1_', и я забыл инициализировать их. Итак, я использую следующие коды.
net.initialize()
Ого, это дает мне много предупреждений.
v.initialize(None, ctx, init, force_reinit=force_reinit)
C:\Users\Bird\AppData\Local\conda\conda\envs\ssd\lib\site-packages\mxnet\gluon\parameter.py:687: UserWarning: Parameter 'ssd0_resnetv10_stage4_batchnorm9_running_mean' is already initialized, ignoring. Set force_reinit=True to re-initialize.
v.initialize(None, ctx, init, force_reinit=force_reinit)
C:\Users\Bird\AppData\Local\conda\conda\envs\ssd\lib\site-packages\mxnet\gluon\parameter.py:687: UserWarning: Parameter 'ssd0_resnetv10_stage4_batchnorm9_running_var' is already initialized, ignoring. Set force_reinit=True to re-initialize.
v.initialize(None, ctx, init, force_reinit=force_reinit)
'_resnet50_v1_', являющийся основой SSD, предварительно обучен, поэтому эти параметры не могут быть установлены. Однако эти предупреждения раздражают.
Как их отключить?
Однако здесь возникает первая проблема. Я хотел бы сохранить параметры сети.
net.save_params('F:/Temps/Models_tmp/' +'myssd.params')
Файл параметров _'resnet50_v1_' ('resnet50_v1-c940b1a0.params') составляет 97,7 МБ; однако размер моего файла параметров составляет всего 9,96 МБ. Есть ли какие-то волшебные технологии для сжатия этих параметров?
Чтобы протестировать эту новую технологию, я открываю новую консоль и перестраиваю ту же сеть. Затем я загружаю сохраненные параметры и передаю им данные.
net.load_params('F:/Temps/Models_tmp/' +'myssd.params')
x = mx.nd.zeros(shape=(batch_size,3,base_size,base_size))
Ошибка инициализации появляется снова.
Ошибка выполнения: параметр «ssd0_expand_trans_conv0_weight» не был инициализирован. Обратите внимание, что вы должны инициализировать параметры и создать Trainer с помощью Block.collect_params() вместо Block.params, потому что последний не включает параметры вложенных дочерних блоков.
Этого не может быть, потому что сохраненный файл myssd.params должен содержать все установленные параметры моей сети.
Чтобы найти блок «_ssd0_expand_trans_conv0», я провел более глубокое исследование в «gluoncv.nn.feature. FeatureExpander_’. Я использую ‘mxnet.gluon. nn.Conv2D' для замены 'mx.sym.Convolution' в 'FeatureExpander< /strong>'.
''' y = mx.sym.Convolution( y, num_filter=num_trans, kernel=(1, 1), no_bias=use_bn, name='expand_trans_conv{}'.format(i), attr={'__init__': weight_init}) ''' Conv1 = nn.Conv2D(channels = num_trans,kernel_size = (1, 1),use_bias = use_bn,weight_initializer = weight_init) y = Conv1(y) Conv1.initialize(verbose = True) ''' y = mx.sym.Convolution( y, num_filter=f, kernel=(3, 3), pad=(1, 1), stride=(2, 2), no_bias=use_bn, name='expand_conv{}'.format(i), attr={'__init__': weight_init}) ''' Conv2 = nn.Conv2D(channels = f,kernel_size = (3, 3),padding = (1, 1),strides = (2, 2),use_bias = use_bn, weight_initializer = weight_init) y = Conv2(y) Conv2.initialize(verbose = True)
Эти новые блоки можно инициализировать вручную. Однако MxNet по-прежнему сообщает об тех же ошибках. Кажется, что ручная инициализация не дает никакого эффекта.
Как мне сохранить все параметры моей сети и восстановить их?