[ディープラーニングシリーズ] PaddlePaddle データ前処理

[ディープラーニングシリーズ] PaddlePaddle データ前処理

前回の記事では、畳み込みニューラルネットワークの基礎知識についてお話ししました。本来、この記事では、CNN と手書き CNN の関連知識について引き続き詳しく説明する予定でしたが、多くの学生から、PaddlePaddle がどのようにデータを読み取り、データの前処理を行うのかについて質問するメールやプライベートメッセージが届きました。ネットで読むチュートリアルの多くは、よくある例をいくつか挙げているだけです。データセットを自分で用意する必要はないので、あまり気にする必要はありません。しかし、実際のプロジェクトでデータ前処理を行うときは戸惑うので、PaddlePaddle を使ってデータ前処理をする方法についてまとめ、解説する記事を書きました。


PaddlePaddleの基本データ形式

公式ウェブサイトによると、PaddlePaddle は 4 つのデータ タイプと 3 つのシーケンス形式を含むさまざまなデータ形式をサポートしています。

4 つのデータ タイプ:

  • dense_vector: 密な浮動小数点ベクトル。
  • sparse_binary_vector: スパースバイナリベクトル。つまり、ほとんどの値は 0 ですが、値は 1 である必要があります。
  • sparse_float_vector: スパースベクトル。つまり、ほとんどの値は 0 ですが、値部分は任意の浮動小数点数になります。
  • 整数: 整数形式

API は次のとおりです。

  • paddle.v2.data_type. ( dimseq_type=0 dense_vector
    • 説明:密なベクトル。入力機能は密な浮動小数点ベクトルです。たとえば、手書き数字認識の入力画像は 28 x 28 ピクセルであり、Paddle のニューラル ネットワークの入力は 784 次元の密なベクトルである必要があります。
    • パラメータ:
      • dim(int) ベクトルの次元
      • seq_type (int) 入力シーケンス形式
    • 戻り値の型: InputType
  • paddle.v2.data_type. sparse_binary_vector ( dimseq_type=0 )
    • 説明:スパース バイナリ ベクトル。入力特徴はスパース ベクトルであり、各要素は 0 または 1 です。
    • パラメータ: 上記と同じ
    • 戻り値の型: 上記と同じ
  • paddle.v2.data_type. sparse_vector ( dimseq_type=0 )
    • 注:スパースベクトル、ベクトル内のほとんどの要素は0で、他の値は任意の浮動小数点値になります
    • パラメータ: 上記と同じ
    • 戻り値の型: 上記と同じ
  • paddle.v2.data_type. integer_value (値の範囲seq_type=0 )
    • 説明: 整数形式
    • パラメータ:
      • seq_type (int): 入力シーケンス形式
      • value_range(int): 各要素の範囲
    • 戻り値の型: InputType

3 つのシーケンス形式:

  • SequenceType.NO_SEQUENCE: シーケンスではありません
  • SequenceType.SEQUENCE: 時系列です
  • SequenceType.SUB_SEQUENCE: 時系列であり、シーケンスの各要素も時系列です。

API は次のとおりです。

  • paddle.v2.data_type.dense_vector_sequence ( dimseq_type=0 ) は、
    • 説明: 密なベクトルのシーケンス形式
    • パラメータ: dim (int): 密ベクトルの次元
    • 戻り値の型: InputType
  • paddle.v2.data_type.sparse_binary_vector_sequence ( dimseq_type=0 ) は、
    • 説明: スパースなバイナリ ベクトル シーケンス。シーケンス内の各要素は 0 または 1 のいずれかです。
    • パラメータ: dim (int): スパースベクトルの次元
    • 戻り値の型: InputType
  • paddle.v2.data_type.sparse_non_value_slot ( dimseq_type=0 ) は、
    • 説明: スパースベクトルシーケンス。シーケンス内の各要素は 0 または 1 のいずれかです。
    • パラメータ:
      • dim (int): 疎ベクトルの次元
      • seq_type (int): 入力シーケンス形式
    • 戻り値の型: InputType
  • paddle.v2.data_type.sparse_value_slot ( dimseq_type=0 ) は、
    • 説明: 疎なベクトルシーケンス。ベクトル内のほとんどの要素は0で、他の値は任意の浮動小数点値になります。
    • パラメータ:
      • dim (int): 疎ベクトルの次元
        • seq_type (int): 入力シーケンス形式
    • 戻り値の型: InputType
  • paddle.v2.data_type.integer_value_sequence (値の範囲seq_type=0 )
    • 説明: value_range (int): 各要素の範囲

次の表に示すように、異なるデータ型とシーケンス モードによって返される形式が異なります。

ここで、fは浮動小数点数、iは整数を表す。

注: sparse_binary_vector および sparse_float_vector の場合、PaddlePaddle は値の位置のインデックスを格納します。例えば、

  • sparse_binary_vector型の5次元非連続スパース01ベクトル[0, 1, 1, 0, 0]の場合、返される値は[1, 2]です。 (1桁目と2桁目のみに値があるため)
  • sparse_float_vector型の5次元非連続スパース浮動小数点ベクトル[0, 0.5, 0.7, 0, 0]の場合、返される値は[(1, 0.5), (2, 0.7)]です。 (最初の数字と2番目の数字のみに値があり、それぞれ0.5と0.7であるため)

PaddlePaddleからデータを読み取る方法

上で説明した 4 つの基本的なデータ形式と 3 つのシーケンス モードを理解したので、独自のデータを処理する際には、ニーズに応じて選択することができます。しかし、データを処理した後、そのデータをトレーニング用のモデルにどのように取り込むのでしょうか。一般的に、次の 2 つの基本的な方法があることがわかっています。

  • メモリへの 1 回限りのロード: モデルをトレーニングするときに、データがメモリから直接取得されるため、大量の IO 消費を必要とせず、高速で、少量のデータに適しています。
  • ディスク/HDFS/共有ストレージなどへのロード:メモリスペースを占有せず、一般的に大量のデータを処理する場合に使用されます。ただし、データがロードされるたびに IO オーバーヘッドが発生し、速度に大きく影響するという欠点があります。

PaddlePaddle には、データを読み取るための 3 つのモード (リーダー、リーダー クリエーター、リーダー デコレーター) があります。これら 3 つの違いは何でしょうか?

  • リーダー: ローカル、ネットワーク、または HDFS などの分散ファイル システムからデータを読み取ります。また、データをランダムに生成し、1 つ以上のデータ項目を返すこともできます。

  • リーダークリエーター: リーダーを返す関数。

  • リーダー デコレータ: 1 つ以上のリーダーを組み合わせることができるデコレータ。

リーダー

リーダーを例に、住宅価格データ (スタンフォード大学の Andrew Ng の公開コースの最初のレッスンで例として使用されたデータ) のリーダーを作成しましょう。

  1. リーダーを作成します。これは基本的に、毎回 1 つのデータを返すイテレータです (ここでは住宅価格データを例に挙げます)
リーダー = paddle.dataset.uci_housing.train()

2. shuffle_reader を作成し、前の手順のリーダーをその中に配置して、buf_size を設定して buf_size のデータを読み取って自動的にシャッフルし、データをシャッフルしてランダム化します。

shuffle_reader = paddle.reader.shuffle(リーダー、buf_size=100)

3. batch_reader を作成し、前の手順でシャッフルした shuffle_reader をその中に入れ、batch_size を指定して作成します。

batch_reader = paddle.batch(shuffle_reader、batch_size=2)

これら 3 つの方法を組み合わせることもできます。

リーダー = paddle.batch(
    パドル.リーダー.シャッフル(
        uci_housing.train()、
    バッファサイズ = 100)、
    バッチサイズ=2)

直感的な図で表すと次のようになります。

図からわかるように、元のデータセットからデータを直接取得し、リーダーで読み取り、それを 1 つずつ shuffle_reader に注ぎ、ローカルでランダム化してデータをシャッフルし、シャッフルされたデータをバッチでトレーナーに入れて、反復とトレーニングの各ステップを実行できます。 プロセスはシンプルで、プロセス全体を実装するのに必要なコードは 1 行だけです。

読者クリエイター

単純なランダムデータを生成したい場合は、リーダー クリエーターを例に挙げます。

reader_creator() を定義します:
    デフリーダー():
        真の場合:
            numpy.random.uniform(-1,1,size=784) を生成します。
    読者を返す

ソースコードについてはcreator.pyをご覧ください。np_array、text_file、RecordIO、cloud_readerの4つの形式をサポートしています。

[[223797]]コードを表示

リーダーデコレータ

データの 2 つの部分を同時に読み取りたい場合は、2 つのリーダーを定義し、それらをマージしてからシャッフルすることができます。たとえば、自動車シリーズを比較しているユーザーと自動車シリーズを閲覧しているユーザーに関するすべてのデータを読み取りたい場合は、contrast() と view() の 2 つのリーダーを定義し、定義済みのリーダー デコレータを使用してこれらのデータをキャッシュして結合し、結合されたデータに対してシャッフル操作を実行できます。ソースコードはdecorator.pyを参照してください。

データ = paddle.reader.shuffle(
        パドル.リーダー.作成(
            パドル.リーダー(contradt(contrast_path),buf_size = 100),
            パドル.リーダー(ビュー(view_path)、バッファサイズ = 200)、
            500)

これには、トレーニング用の機能を組み合わせるのが容易になるという大きな利点があります。モデルを実行する従来の方法は、ラベルと特徴を決定し、できるだけ多くの適切な特徴を見つけてモデルに投入してトレーニングすることです。この方法では、大きなテーブルを作成する必要があります。トレーニング後、特定の機能の重要性を分析し、トレーニング用にいくつかの機能を追加または削減できます。この方法では、元のラベル機能テーブルを変更する必要があります。データ量が少ない場合は影響はそれほど大きくありませんが、少し面倒です。ただし、データ量が多い場合は、毎回機能を追加して主キーとラベルを結合するのは時間がかかります。この方法を採用すると、同じカテゴリのいくつかの特徴のテーブルを作成し、データを変数名として保存できます。モデルを実行するたびに、複数のカテゴリの特徴を選択する場合は、複数のリーダーを作成し、それらをリーダーデコレータと組み合わせて、最終的にトレーニング用にモデルにシャッフルすることができます。これ!サンプル!はい!いいえ!はい!とても!四角!便利!

理解できない場合は、例を挙げてみましょう。ユーザーが車を購入するかどうかを予測するとします。ラベルは、車を購入するかどうかです。機能には、車シリーズの閲覧、車シリーズの比較、車シリーズへの注目、およびその他の 20 の機能設定が含まれます。従来の考え方では、次のようなテーブルを作成します。

feature_2 を削減し、feature_2 がモデルの精度に大きな影響を与えるかどうかを確認するには、このテーブルでこの列を削除する必要があります。機能を追加する場合は、機能に列を追加する必要があります。リーダー デコレータを使用する場合は、次の操作を実行してデータセットを作成できます。

同じタイプの機能をまとめると、頻繁に結合する必要がなくなり、時間を節約できます。合計 4 つのテーブルを作成し、4 つのリーダーを作成します。

データ = paddle.reader.shuffle(
            パドル.リーダー.作成(
                パドル.リーダー(テーブル1(テーブル1_パス)、バッファサイズ = 100)、
                パドル.リーダー(table2(table2_path),buf_size = 100),
                パドル.リーダー(table3(table3_path),buf_size = 100),
                パドル.リーダー(table4(table4_path),buf_size = 100),
            500)

新しい特徴を発見し、それがモデルの精度向上に役立つかどうかを確認したい場合は、特徴データを個別に抽出し、リーダーを追加し、リーダー デコレータと組み合わせてシャッフルし、モデル内で実行できます。


PaddlePaddleデータ前処理の例

手書きの数字を例にとると、データを処理してトレーニングとテストに分割した後、必要な手順は次の 4 つだけです。

1. データアドレスを指定する

 1 paddle.v2.dataset.common をインポートする
 2 インポートサブプロセス
 3 numpyをインポートする
 4 インポートプラットフォーム
 5 __all__ = ['train', 'test', 'convert']
 6 
 7 URL_PREFIX = 'http://yann.lecun.com/exdb/mnist/'
 8 TEST_IMAGE_URL = URL_PREFIX + 't10k-images-idx3-ubyte.gz'
 9 テストイメージMD5 = '9fb629c4189551a2d022fa330f9573f3'
10 TEST_LABEL_URL = URL_PREFIX + 't10k-labels-idx1-ubyte.gz'
11 TEST_LABEL_MD5 = 'ec29112dd5afa0611ce80d1b7f02629c'
12 TRAIN_IMAGE_URL = URL_PREFIX + 'train-images-idx3-ubyte.gz'
13 TRAIN_IMAGE_MD5 = 'f68b3c2dcbeaaa9fbdd348bbdeb94873'
14 TRAIN_LABEL_URL = URL_PREFIX + 'train-labels-idx1-ubyte.gz'
15 TRAIN_LABEL_MD5 = 'd53e105ee54ea40749a09fcbcd1e9432'

2. リーダークリエイターを作成する

 1 def reader_creator(イメージファイル名、ラベルファイル名、バッファサイズ):
 2 # リーダーを作成する
 3 定義リーダー():
 4 platform.system() == 'Darwin'の場合:
 5 zcat_cmd = 'gzcat'
 6 プラットフォーム.system() == 'Linux'の場合:
 7 zcat_cmd = 'zcat'
 8 その他:
 9 NotImplementedError() を発生させる
10 
11 m = サブプロセス.Popen([zcat_cmd, イメージファイル名], stdout=サブプロセス.PIPE)
12 m.stdout.read(16)  
13 
14 l = サブプロセス.Popen([zcat_cmd, ラベルファイル名], stdout=サブプロセス.PIPE)
15 l.stdout.read(8)  
16 
17 試行: # リーダーが壊れる可能性があります。
18 真実の場合:
19 ラベル = numpy.fromfile(
20 l.stdout、'ubyte'、count=buffer_size).astype("int")
21 
22 labels.size != buffer_size の場合:
23 break # numpy.fromfile は EOF の後に空のスライスを返します。
24 
25 枚の画像 = numpy.fromfile(
26 m.stdout、'ubyte'、count=buffer_size * 28 * 28).reshape(
27 (バッファサイズ、28 * 28)).astype('float32')
28 
29 枚の画像 = 画像 / 255.0 * 2.0 - 1.0
30 
31 i を xrange(buffer_size) に格納します:
32 イメージ[i, :], int(ラベル[i]) を生成する
33 最後に:
34 m.終了()
35 l.終了()
36 
37 リターンリーダー

3. トレーニングセットとテストセットを作成する

 1 定義train():
 2 """
 3 mnsitトレーニングセットリーダークリエーターを作成する
 4 リーダークリエーターを返します。リーダー内の各サンプルは画像のピクセル値で、範囲は[0,1]、ラベルは0~9です。
 5 リターン: トレーニングリーダー作成者
 6 """
 7 リーダークリエイターを返す(
 8 paddle.v2.dataset.common.download(TRAIN_IMAGE_URL, 'mnist',
 9 TRAIN_IMAGE_MD5)、
10 paddle.v2.dataset.common.download(TRAIN_LABEL_URL, 'mnist',
11 TRAIN_LABEL_MD5)、100)
12 
13 
14 定義テスト():
15 """
16 mnsitテストセットリーダークリエーターを作成する
17 リーダークリエーターを返します。リーダー内の各サンプルは画像のピクセル値で、範囲は[0,1]、ラベルは0~9です。
18 戻り値: テストリーダー作成者
19 """
20 リーダークリエイターを返す(
21 paddle.v2.dataset.common.download(TEST_IMAGE_URL, 'mnist',
22 TEST_IMAGE_MD5)、
23 paddle.v2.dataset.common.download(TEST_LABEL_URL, 'mnist',
24 TEST_LABEL_MD5)、100)

4. データをダウンロードし、対応する形式に変換する

 1 def fetch():
 2 paddle.v2.dataset.common.download(TRAIN_IMAGE_URL、'mnist'、TRAIN_IMAGE_MD5)
 3 paddle.v2.dataset.common.download(TRAIN_LABEL_URL、'mnist'、TRAIN_LABEL_MD5)
 4 paddle.v2.dataset.common.download(TEST_IMAGE_URL、'mnist'、TEST_IMAGE_MD5)
 5 paddle.v2.dataset.common.download(TEST_LABEL_URL、'mnist'、TRAIN_LABEL_MD5)
 6 
 7 
 8 def convert(パス):
 9 """
10 データ形式をrecordio形式に変換する
11 """
12 paddle.v2.dataset.common.convert(path, train(), 1000, "minist_train")
13 paddle.v2.dataset.common.convert(path, test(), 1000, "minist_test")

独自のトレーニング データに変更する場合は、手順に従って独自のデータ アドレスに変更し、対応するリーダー クリエーター (またはリーダー デコレータ) を作成します。

これは画像の例です。テキスト モデルをトレーニングして感情分析を行う場合、データをどのように処理すればよいでしょうか。手順も非常に簡単です。

大量のデータがあり、各行がサンプルで、 \tで区切られ、最初の列がカテゴリ ラベル、2 番目の列が入力テキストの内容、テキスト内容の単語がスペースで区切られているとします。次の 2 つのサンプル データがあります。

良い点 今日、ついに理想の車を試乗しました。外観はとてもクールで、中央コントロールも素晴らしいです。悪い点 この車は高すぎるし、燃料を消費しすぎます。コストパフォーマンスが低すぎます

それではデータの前処理を始めましょう

1. リーダーを作成する

 1 定義train_reader(data_dir、word_dict、label_dict):
 2 定義リーダー():
 3 unk_id = word_dict [""]
 4 単語列 = 0
 5 lbl_col = 1
 6 
 7 os.listdir(data_dir) の file_name の場合:
 8 を open(os.path.join(data_dir, file_name), "r") として f として実行:
 9 行目 f:
10 line_split = line.strip().split("\t")
11 ワードID = [
12 word_dict.get(w, UNK_ID)
13 w を line_split[word_col].split() で分割する
14 ]
15 word_ids、label_dict[line_split[lbl_col]]を生成します。
16 
17 リターンリーダー

戻り値の型は、 paddle.data_type.integer_value_sequence (辞書内の単語の序数)とpaddle.data_type.integer_value (カテゴリラベル)です。

2. 複合読解法

1 トレインリーダー = パドル.バッチ(
2 パドル.リーダー.シャッフル(
3 リーダー.train_reader(train_data_dir、word_dict、lbl_dict)、
4 バッファサイズ=1000)、
5 バッチサイズ=バッチサイズ)

完全なコードは次のとおりです (train 部分と test 部分が追加されています)。

 1 インポート OS
 2 
 3 
 4 定義train_reader(data_dir、word_dict、label_dict):
 5 """
 6 トレーニングデータリーダーを作成する
 7 :param data_dir: データアドレス。
 8 :type data_dir: 文字列
 9 :param word_dict: 辞書アドレス、
10 「UNK」は辞書に含まれている必要があります。
11 :type word_dict:python dict
12 :param label_dict: ラベル辞書アドレス 13 :type label_dict: Python dict
14 """
15 
16 定義リーダー():
17 unk_id = word_dict [""]
18 単語列 = 1
19 lbl_col = 0
20 
21 os.listdir(data_dir) の file_name の場合:
22 open(os.path.join(data_dir, file_name), "r") を f として実行:
23 行目 f:
24 line_split = line.strip().split("\t")
25 ワードID = [
26 word_dict.get(w, UNK_ID)
27 w を line_split[word_col].split() で分割する
28 ]
29 word_ids、label_dict[line_split[lbl_col]]を生成します
30 
31 リターンリーダー
32 
33 
34 定義 test_reader(data_dir, word_dict):
35 """
36 テストデータリーダーを作成する
37 :param data_dir: データアドレス。
38 :type data_dir: str
39 :param word_dict: 辞書アドレス、
40 「UNK」は辞書に含まれている必要があります。
41 :type word_dict:python dict
42 """
43 
44 定義リーダー():
45 unk_id = word_dict [""]]
46 単語列 = 1
47 
48 os.listdir(data_dir) の file_name の場合:
49 open(os.path.join(data_dir, file_name), "r") を f として実行:
50 行目 f:
51 line_split = line.strip().split("\t")
52 len(line_split) < word_colの場合: 続行
53 単語ID = [
54 word_dict.get(w, UNK_ID)
55 w の line_split[word_col].split()
56 ]
57 word_ids、line_split[word_col]を生成します
58 
59 リターンリーダー


要約する

  この記事では主に、PaddlePaddle に独自のデータセットを読み込み、対応する形式に変換し、トレーニングとテストに分割する方法について説明します。フレームワークを使用する場合、通常は最初にいくつかの簡単なデモを実行します。ただし、一般的なデモデータを使用せず、実際のプロジェクトを自分で実行し、モデルを完全に実行すれば、そのフレームワークの基本的なアプリケーション知識を習得したことになります。モデルを実行するための最初のステップは、データの前処理です。PaddlePaddle で提供される方法は非常にシンプルですが、多くの利点があります。

  • シャッフルデータは非常に便利です
  • データはバッチトレーニングに組み合わせることができる
  • リーダー デコレータを使用すると、複数のリーダーを組み合わせて、組み合わせた機能を持つモデルの実行効率を向上させることができます。
  • 複数のスレッドでデータを読み取ることができる

以前、mxnetを使用してナンバープレート認識モデルをトレーニングしたことがあります。一度に50万枚の画像データをトレーニングするのは非常に時間がかかります。この場合、2つの解決策があります。1つはほとんどのフレームワークに備わっているバッチトレーニングです。もう1つは、読み取り効率を向上させるためにmxnet固有のrec形式に変換することです。画像はim2rec.pyを介して変換できますが、これはより面倒です。tesnorflowの場合は、対応する特定の形式tfrecordもあります。これらの方法にはそれぞれ長所と短所があります。使いやすさの点では、paddlepaddleは比較的シンプルです。

この記事は前回の記事とは関係ありません。トレーニング用のデータを自分でロードする方法について尋ねるメールをいくつか見たので、最初にこれを書くセクションを挿入することにしました。次回の記事では、引き続きCNNの高度な知識についてお話します。来週お会いしましょう^_^!

参考記事:

1. 公式ウェブサイトの説明:

http://doc.paddlepaddle.org/develop/doc_cn/getstarted/concepts/use_concepts_cn.html

<<:  自然言語処理技術はビジネス分野でどのようなアプリケーションをサポートできますか?

>>:  中国の顔認識技術が世界を震撼させている! (顔認証調査報告書を添付します)

ブログ    

推薦する

...

ファインマン・ラプソディ:体内に入ることができる「外科医」

1959年、ノーベル物理学賞受賞者のリチャード・ファインマンは、カリフォルニア工科大学での「体の底...

人工知能はビジネスに大きな影響を与えます。AIは中小企業に5つの大きなメリットをもたらします。

市場のトレンドはどのくらいの速さで発展していますか? 特に人工知能に関しては。企業は驚くべき速度で ...

自然言語処理パート1: テキスト分類器

[[194511]]序文テキスト分類は、自動記事分類、自動メール分類、スパム識別、ユーザー感情分類な...

不妊治療の新たな夜明け:AI

世界初の試験管ベビーは1978年に英国で誕生した。それ以来、人工生殖技術は継続的に改良されてきました...

...

...

自律走行の新しい方法がネイチャーの表紙に登場:夜を昼のように明るくする、浙江大学の博士

AI の支援により、機械の夜間視界は昼間と同じくらい鮮明になります。今日、既存の熱画像技術に革命をも...

数日間GitHubのホットリストを独占した後、Colossal-AIが正式にリリースされました

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

2018 年に人工知能があなたの生活、仕事、遊びに革命を起こす 8 つの方法

2017年、人工知能はあらゆる面でブームを巻き起こしました。イーロン・マスクからマーク・ザッカーバー...

マスクを着用していても、AIはあなたが何を言っているか理解できる

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

...