2015-11-12 2 views
1

Я точно настраиваю сеть GoogleNet с помощью Caffe в свой собственный набор данных. Если я использую слои IMAGE_DATA, когда происходит входное обучение. Однако мне нужно переключиться на уровень HDF5 для дальнейших расширений, которые мне нужны. Когда я использую слои HDF5, обучение не происходит.Caffe HDF5 не изучает

Я использую точные входные изображения, а также метки. Я также проверил, чтобы данные в файлах .h5 могли быть загружены правильно. Это так, и Caffe также может найти количество примеров, которые я кормлю, а также правильное количество классов (2).

Это заставляет меня думать, что проблема заключается в преобразованиях, которые я выполняю вручную (поскольку слои HDF5 не выполняют встроенных преобразований). Код для них ниже. Я делаю следующее:

  • Преобразование изображения из RGB в BGR
  • Изменение размера его 256х256, так что я могу вычесть средний файл из ImageNet (included in the Caffe library)
  • Поскольку исходный GoogleNet prototxt не делится на 255, Я также не (see here)
  • изменить размер изображения вплоть до 224x224, что является размер урожая требуется GoogleNet
  • Я транспонировать изображение, необходимое для удовлетворения CxHxW, в соответствии с требованиями Caffe
  • На данный момент я не выполняю аудит данных, который можно включить, если я допустил перевыполнение = True.

Может ли кто-нибудь увидеть что-то не так с этим подходом? Является ли увеличение данных настолько критичным, что никакое обучение не будет проходить без него?

Код преобразования HDF5

IMG_RESHAPE = 224 
IMG_UNCROPPED = 256 

def resize_convert(img_names, path=None, oversample=False): 
    ''' 
    Load images, set to BGR mode and transpose to CxHxW 
    and subtract the Imagenet mean. If oversample is True, 
    perform data augmentation. 

    Parameters: 
    --------- 
    img_names (list): list of image names to be processed. 
    path (string): path to images. 
    oversample (bool): if True then data augmentation is performed 
     on each image, and 10 crops of size 224x224 are produced 
     from each image. If False, then a single 224x224 is produced. 
    ''' 

    path = path if path is not None else '' 
    if oversample == False: 
     all_imgs = np.empty((len(img_names), 3, IMG_RESHAPE, IMG_RESHAPE), dtype='float32') 
    else: 
     all_imgs = np.empty((len(img_names), 3, IMG_UNCROPPED, IMG_UNCROPPED), dtype='float32') 

    #load the imagenet mean 
    mean_val = np.load('/path/to/imagenet/ilsvrc_2012_mean.npy') 

    for i, img_name in enumerate(img_names): 
     img = ndimage.imread(path+img_name, mode='RGB') # Read as HxWxC 

     #subtract the mean of Imagenet 
     #First, resize to 256 so we can subtract the mean of dims 256x256 
     img = img[...,::-1] #Convert RGB TO BGR 
     img = caffe.io.resize_image(img, (IMG_UNCROPPED, IMG_UNCROPPED), interp_order=1) 
     img = np.transpose(img, (2, 0, 1)) #HxWxC => CxHxW 
     #Since mean is given in Caffe channel order: 3xWxH 
     #Assume it also is given in BGR order 
     img = img - mean_val 

     #set to 0-1 range => I don't think googleNet requires this 
     #I tried both and it didn't make a difference 
     #img = img/255 

     #resize images down since GoogleNet accepts 224x224 crops 
     if oversample == False: 
      img = np.transpose(img, (1,2,0)) # CxHxW => HxWxC 
      img = caffe.io.resize_image(img, (IMG_RESHAPE, IMG_RESHAPE), interp_order=1) 
      img = np.transpose(img, (2,0,1)) #convert to CxHxW for Caffe 
     all_imgs[i, :, :, :] = img 

    #oversampling requires HxWxC order 
    if oversample: 
     all_imgs = np.transpose(all_imgs, (0, 3, 1, 2)) 
     all_imgs = caffe.io.oversample(all_imgs, (IMG_RESHAPE, IMG_RESHAPE)) 
     all_imgs = np.transpose(all_imgs, (0,2,3,1)) #convert to CxHxW for Caffe 

    return all_imgs 

Соответствующие различия между image_data и hdf5 prototxt файлы

name: "GoogleNet" 
layers { 
    name: "data" 
    type: HDF5_DATA 
    top: "data" 
    top: "label" 
    hdf5_data_param { 
    source: "/path/to/train_list.txt" 
    batch_size: 32 
    } 
    include: { phase: TRAIN } 
} 
layers { 
    name: "data" 
    type: HDF5_DATA 
    top: "data" 
    top: "label" 
    hdf5_data_param { 
    source: "/path/to/valid_list.txt" 
    batch_size:10 
    } 
    include: { phase: TEST } 
} 

Update

Когда я говорю, нет обучения не происходит, я имею в виду, что моя потеря тренировки не снижаясь последовательно при использовании данных HDF5 по сравнению с IMG_Data. На приведенных ниже изображениях первый график отображает изменение потерь на тренировку для сети IMG_DATA, а другой - сеть передачи данных HDF5.

Одна из возможностей, которую я рассматриваю, заключается в том, что сеть перерабатывает каждый из .h5, который я кормлю. В настоящий момент я использую расширение данных, но все расширенные примеры хранятся в одном файле .h5 вместе с другими примерами. Однако, поскольку все расширенные версии одного входного изображения все содержатся в одном файле .h5, я думаю, это может привести к переналадке сети на этот конкретный файл .h5. Тем не менее, я не уверен, что это то, что предлагает второй сюжет.

Training loss with IMG_DATA input Training loss with HDF5 input

+0

1. Почему вы не читали изображения используя caffe.io.load_image? – Shai

+0

2. Почему вы изменяете размер с помощью заказа = 1? попробуйте более высокий порядок. – Shai

+1

3. изменение размера изображения с 256 до 224 должно ** не ** выполняться с использованием изменения размера, а путем обрезки – Shai

ответ

0

я столкнулся с той же проблемой и выяснили, что по какой-то причине делать преобразование вручную, как вы делаете в вашем коде вызывает образы, чтобы быть во все черное (все нули). попробуйте отладить свой код и посмотреть, что происходит. решение заключается в использовании той же методики описаны в учебнике Caffe здесь http://nbviewer.jupyter.org/github/BVLC/caffe/blob/master/examples/00-classification.ipynb та часть, где вы видите

# create transformer for the input called 'data' 
transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape}) 
transformer.set_transpose('data', (2,0,1)) # move image channels to outermost dimension 
transformer.set_mean('data', mu)   # subtract the dataset-mean value in each channel 
transformer.set_raw_scale('data', 255)  # rescale from [0, 1] to [0, 255] 
transformer.set_channel_swap('data', (2,1,0)) # swap channels from RGB to BGR 

затем несколько строк вниз

image = caffe.io.load_image(caffe_root + 'examples/images/cat.jpg') 
transformed_image = transformer.preprocess('data', image) 
+0

Как инициализировать трансформатор во время обучения? Здесь он использует transformer = caffe.io.Transformer ({'data': net.blobs ['data']. Data.shape}), но как я могу развернуть размер чистых данных обучения? – dusa

Смежные вопросы