【Tensorflow】どのようにしてネットワークの事前加工とトレーニングデータのパッケージ化を行いますか?(一)


さまざまなデータセット、さまざまなデータストレージ形式に直面して、初心者の私たちはこれらの状況を処理するときに困っていますか?どうせ歩いてきて、私の経験は私に教えて、deep learningの実験の段階、データの準備と処理の過程は往々にしてあなたに鼻の灰にぶつかることができます.ネットワークの構築方法を知っているのに、実験ができないのは、データ工学の経験が不足しているからだ.
私はこのシリーズを作るつもりで、主に異なる種類、フォーマットのデータに対する処理案を記録します.データの前処理の第1編、私はみんなのために1種のよくある情況の処理方法を展示します
一.問題の背景
問題の背景はraw imageデータセットに直面するが,画像はlabelでフォルダとして格納される.Office-31データセットを例にとります.
Office-31データセットは、学習アルゴリズムのパフォーマンステストを移行するためのデータセットです.私はすでにネット上にアップロードしました.ダウンロードアドレスは以下の通りです.
domain_adaptation_images.part1.rar
domain_adaptation_images.part2.rar権限が足りず、2つのボリュームがアップロードされました.
解凍後にこのファイルが表示されます
次は3つのファイルです.この3つは異なる環境で撮影された図です.amazonに入るだけでいいです.
最後にこのフォルダの下には様々なクラスがあり、各クラスフォルダはlabelに相当します.
具体的なlabelの下に入ると、いろいろな画像が現れます.
このような問題の背景を説明することは、実際には多くのピクチャデータセットがこのような形式で格納されているため、意味がある.
これを例に、この問題の具体的な解決策を以下に記録する.
二.ソリューション
まず、必要なアシストツールについてお話しします.前編で述べたskimage(【Tensorflow】アシストツール編——scikit-image紹介)、cPickle、matplotlib
ここにdomainのデータが3つあるので、amazonというフォルダの下の画像の処理しかしません.
まずコードをつけます.
def build_dataset(data_dir, out_dir, weight=100,hight=100):
    data_dir = os.path.join(data_dir,"images")
    for _, dirnames, _ in os.walk(data_dir):
        for dirname in dirnames:
            index = dirnames.index(dirname)
            workdir = os.path.join(data_dir, dirname)
            #images = io.imread_collection(workdir + '/*.jpg')
            processed_images = io.ImageCollection(workdir + '/*.jpg', load_func=process_image, weight=weight,hight=hight)
            label = np.full(len(processed_images), fill_value=index, dtype=np.int32)
            images = io.concatenate_images(processed_images)
            if index == 0:
                data = images
                labels = label
            else:
                data = np.vstack((data,images))
                labels = np.append(labels,label)
    if not os.path.exists(out_dir):
        os.makedirs(out_dir)
    print "data shape:",data.shape
    print  "label shape:",labels.shape
    save_pickle(data, out_dir+'/'+'amazon_images.pkl')
    save_pickle(labels, out_dir+'/'+'amazon_labels.pkl')

解決策は伝統的だ.まずフォルダを巡り、各フォルダの下にあるすべての画像をskimageで一括して読みます
読み込みのプロセスはimread_collection関数はすべてのjgpピクチャを読み出し、1つのクラスを返します(このクラスはnp配列ではなくskimageのImageCollectionクラスなので、直接使用することはできません.concatenate_images関数で複数のピクチャを接続してnp配列にします).
しかし、私たちはimreadを使用していません.Collection関数ではなく、ImageCollectionクラスのコンストラクション関数を使用して、ImageCollectionクラスを直接構築します.主に、画像のサイズが画素によって異なると接続時にエラー(次元が異なる)が発生するため、画像の前処理を完了し、すべての図resizeを同じサイズに処理します.ImageCollectionクラスを構築するときにloadに処理関数を入れることができます.ここではprocess_イメージ関数:
def process_image(image, weight, hight):
    img = io.imread(image)
    img = transform.resize(img, (weight,hight), mode='reflect')
    return img

もちろんイメージ関数には他の内容(裁断、塗りつぶしなど)を追加することもできます.
また、元の画像の画素がすべて等しくなることを保証できれば、imread_collectionは読み込んでから統一的に処理します.ここでは主により複雑な状況を対象としています.
最後に、pklファイルを使用して保存します.
def save_pickle(data, path):
    with open(path, 'wb') as f:
        pickle.dump(data, f, pickle.HIGHEST_PROTOCOL)
        print ('Saved %s..' %path)

データ量が少ない場合、pklはよく使われる保存手段であり、gzipを用いて圧縮され、最も一般的なmnistはpklである.gzという接尾辞.同時にcPickleはpickleのアップグレード版で、圧縮率はpickleより優れています.試してみてください.
しかし、データ量が大きい場合、hdf 5を使用するのが一般的で、hdf 5はパフォーマンスの面でcPickleよりずっと優れています.この方法は後で紹介します.
もちろん画像の前処理のpipelineを構築することもできます.この方法はすべてのスキームの究極版であり、例えばCoCoデータセットでstyle transfer訓練を行う際にスレッドで画像を読む方式を用いることは不可能であり、同時にこの方法も最も実現しにくいものであり、同様に後述する.
大功が成し遂げられた!最後に結果を見てみましょう.
同じようにmatplotlibで複数の画像を表示します
import cPickle
from mpl_toolkits.axes_grid1 import ImageGrid
import matplotlib.pyplot as plt


def imshow_grid(images, shape=[2, 8]):
    """Plot images in a grid of a given shape."""
    fig = plt.figure(1)
    grid = ImageGrid(fig, 111, nrows_ncols=shape, axes_pad=0.05)

    size = shape[0] * shape[1]
    for i in range(size):
        grid[i].axis('off')
        grid[i].imshow(images[i])  # The AxesGrid object work as a list of axes.

    plt.show()


def load_amazon():
    data = cPickle.load(open('prosessed_data/amazon_images.pkl'))
    labels = cPickle.load(open('prosessed_data/amazon_labels.pkl'))
    return data,labels

data,labels = load_amazon()
print "show image..."
imshow_grid(data[90:106])
print labels[90:106]

画像とlabelは、上を向いているのを見て、次のステップに進むことができます.
[0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1]

データの正規化を忘れずに!!比較的簡単な方法は、(ピクセル値-127.5)/127.5を計算することであり、この方法は、1〜1の間に帰するか、各チャネルの平均値を計算し、各チャネルをそれぞれ帰することもできる.
正規化はみんなができると信じているので,余計なことは言わない.