2017-01-25 12 views
0

私はCaltech101をダウンロードしました。その構造は次のとおりです。HDF5に書き込み、大きいデータ配列をシャッフル

#Caltech101 dir #class1 dir #images of class1 jpgs #class2 dir #images of class2 jpgs ... #class100 dir #images of class100 jpgs

私の問題は、私がメモリに2つのNPアレイxと形状(9144, 240, 180, 3)(9144)yを保つことができないということです。ですから、私の解決策は、h5pyデータセットを全面的に配置し、2つのチャンクにロードし、それらを1つずつファイルに書き込むことです。正確に:

from __future__ import print_function 
import os 
import glob 
from scipy.misc import imread, imresize 
from sklearn.utils import shuffle 
import numpy as np 
import h5py 
from time import time 


def load_chunk(images_dset, labels_dset, chunk_of_classes, counter, type_key, prev_chunk_length): 
    # getting images and processing 
    xtmp = [] 
    ytmp = [] 
    for label in chunk_of_classes: 
     img_list = sorted(glob.glob(os.path.join(dir_name, label, "*.jpg"))) 
     for img in img_list: 
      img = imread(img, mode='RGB') 
      img = imresize(img, (240, 180)) 
      xtmp.append(img) 
      ytmp.append(label) 
     print(label, 'done') 

    x = np.concatenate([arr[np.newaxis] for arr in xtmp]) 
    y = np.array(ytmp, dtype=type_key) 
    print('x: ', type(x), np.shape(x), 'y: ', type(y), np.shape(y)) 

    # writing to dataset 
    a = time() 
    images_dset[prev_chunk_length:prev_chunk_length+x.shape[0], :, :, :] = x 
    print(labels_dset.shape) 
    print(y.shape, y.shape[0]) 
    print(type(y), y.dtype) 
    print(prev_chunk_length) 
    labels_dset[prev_chunk_length:prev_chunk_length+y.shape[0]] = y 
    b = time() 
    print('Chunk', counter, 'written in', b-a, 'seconds') 
    return prev_chunk_length+x.shape[0] 


def write_to_file(remove_DS_Store): 
    if os.path.isfile('caltech101.h5'): 
     print('File exists already') 
     return 
    else: 
     # the name of each dir is the name of a class 
     classes = os.listdir(dir_name) 
     if remove_DS_Store: 
      classes.pop(0) # removes .DS_Store - may not be used on other terminals 

     # need the dtype of y in order to initialize h5 dataset 
     s = '' 
     key_type_y = s.join(['S', str(len(max(classes, key=len)))]) 
     classes = np.array(classes, dtype=key_type_y) 

     # number of chunks in which the dataset must be divided 
     nb_chunks = 2 
     nb_chunks_loaded = 0 
     prev_chunk_length = 0 
     # open file and allocating a dataset 
     f = h5py.File('caltech101.h5', 'a') 
     imgs = f.create_dataset('images', shape=(9144, 240, 180, 3), dtype='uint8') 
     labels = f.create_dataset('labels', shape=(9144,), dtype=key_type_y) 
     for class_sublist in np.array_split(classes, nb_chunks): 
      # loading chunk by chunk in a function to avoid memory overhead 
      prev_chunk_length = load_chunk(imgs, labels, class_sublist, nb_chunks_loaded, key_type_y, prev_chunk_length) 
      nb_chunks_loaded += 1 
     f.close() 
     print('Images and labels saved to \'caltech101.h5\'') 
    return 

dir_name = '../Datasets/Caltech101' 
write_to_file(remove_DS_Store=True) 

これはかなりうまく動作し、実際には読み込み速度も十分です。問題は、データセットをシャッフルする必要があることです。

観察:彼らは、ディスクにしているので、明らかにveeeery遅い:

  • は、データセットオブジェクトをシャッフルします。

  • シャッフルされたインデックスの配列を作成し、高度なnumpyインデックスを使用します。これは、ファイルからの読み込みが遅くなることを意味します。

  • ファイルに書き込む前にシャッフルするといいですね。問題:毎回、メモリの約半分しかメモリに残っていません。私は不適切なシャッフリングをするだろう。

書き込み前にシャッフルする方法はありますか?私は、多くのメモリを使用しない限り、書き込みプロセスを再考するソリューションにもオープンしています。

答えて

2

画像データを読み取る前にファイルパスをシャッフルすることができます。

メモリ内のイメージデータをシャッフルする代わりに、データセットに属するすべてのファイルパスのリストを作成します。次に、ファイルパスのリストをシャッフルします。以前と同様にHDF5データベースを作成することができます。

import os 

for file_path in shuffeled_files: 
    label = os.path.basename(os.path.dirname(file_path)) 
    image_id = os.path.splitext(os.path.basename(file_path))[0] 
+0

この問題:

import glob import random files = glob.glob('../Datasets/Caltech101/*/*.jpg') shuffeled_files = random.shuffle(files) 

あなたは、パスからクラスラベルとイメージ名を取得することができます:あなたは、例えばシャッフル用のファイルのリストを作成するglobを使用することができ

アプローチは、ディレクトリの名前は私のラベルです、私はマップイメージ - >ラベルを作成する必要があります。さて、ちょうど私の後で私に答えました:D – iacolippo

+0

パスからIDとラベルを取得する方法の例を追加しました。ちょうど実現した、あなたはラベルをあまりにも(もちろん)保存したい: – thertweck

+0

それは動作します!ありがとうございました – iacolippo

関連する問題