復元抽出と非復元抽出
ミニバッチの学習には復元抽出と非復元抽出の2種類があります。 復元抽出(with replacement)と非復元抽出(without replacement)は、統計学や機械学習においてデータをサンプリングする方法の違いを表しています。
復元抽出(with replacement)
サンプルを選択した後、元のデータセットに戻すことを許すサンプリング方法です。つまり、同じサンプルが複数回選ばれることがあります。この場合、サンプルの選択は独立であり、選ばれる確率は一定です。復元抽出は、ランダム性と確率の性質を維持しながら大規模なデータセットから比較的少数のサンプルを選ぶのに有用です。
非復元抽出(without replacement)
サンプルを選択した後、元のデータセットから取り除くサンプリング方法です。つまり、同じサンプルは一度しか選ばれません。この場合、選ばれるサンプルは前の選択に依存して変化します。非復元抽出は、データセット全体の特徴や分布を反映させるために使用されます。
コードの例(復元抽出)
np.random.choice(train_size, batch_size)
の部分で、train_size
の範囲からbatch_size
個のサンプルが重複を許してランダムに選ばれています。これにより、同じサンプルが複数回選ばれる可能性があります。コードの例(非復元抽出)
index = np.arange(train_size)
でトレーニングデータのインデックスが生成され、np.random.shuffle(index)
でそのインデックスがシャッフルされます。その後、ミニバッチを作成する際にシャッフルされたインデックスから部分配列を抽出することで、同じサンプルが複数回選ばれることはありません。
復元抽出の場合
コード
np.random.seed(1234) train_size = train_labels.shape[0] batch_size = 32 max_iter = 10 #ループの回数 network = None #ダミー for i in range(max_iter): batch_mask = np.random.choice(train_size, batch_size) # 復元抽出 print("i=%s, "%i, "batch_mask=%s"%batch_mask[:10]) x_batch = train[batch_mask] y_batch = train_labels[batch_mask] trainer(network, x_batch, y_batch)
コード解説
このコードは、ニューラルネットワークのトレーニングループを実行しています。以下にコードの解説を示します。
np.random.seed(1234)
: 乱数のシードを設定しています。これにより、再現性のあるランダムな動作が得られます。train_size = train_labels.shape[0]
:train_labels
のサイズを取得し、train_size
に代入しています。これはトレーニングデータのサンプル数を表します。batch_size = 32
: バッチサイズを定義しています。バッチサイズとは、一度にネットワークに入力するサンプルの数です。max_iter = 10
: ループの回数を定義しています。トレーニングデータ全体を何回繰り返して学習するかを表します。network = None
: ネットワークモデルを表す変数network
を定義しています。このコードではダミーのままであり、実際のネットワークモデルは記述されていません。for i in range(max_iter):
: ループをmax_iter
回繰り返します。batch_mask = np.random.choice(train_size, batch_size)
:train_size
の範囲から、バッチサイズの数だけ復元抽出(重複を許す抽出)を行い、batch_mask
に代入します。これにより、ランダムに選択されたサンプルのインデックスが得られます。print("i=%s, "%i, "batch_mask=%s"%batch_mask[:10])
: 現在のループ回数と選択されたバッチのインデックスを出力します。batch_mask[:10]
は最初の10個のインデックスを表します。x_batch = train[batch_mask]
: 選択されたバッチのインデックスを使って、トレーニングデータtrain
から対応する部分配列を抽出し、x_batch
に代入します。これにより、ネットワークへの入力データが得られます。y_batch = train_labels[batch_mask]
: 選択されたバッチのインデックスを使って、トレーニングデータのラベルtrain_labels
から対応する部分配列を抽出し、y_batch
に代入します。これにより、ネットワークへの正解データが得られます。trainer(network, x_batch, y_batch)
:trainer
関数を呼び出し、ネットワークモデルnetwork
とバッチデータx_batch
、正解データy_batch
を引数として渡しています。trainer
関数は、ネットワークモデルを使用してバッチデータをトレーニングし、パラメータの更新を行う関数です。trainer(network, x_batch, y_batch)
:trainer
関数を呼び出し、ネットワークモデルnetwork
、バッチデータx_batch
、正解データy_batch
を渡しています。この関数は、ネットワークモデルに対してバッチデータを与えてトレーニングを行い、パラメータの更新を行います。
このコードは、与えられたトレーニングデータをバッチサイズごとにランダムに選択してミニバッチを作成し、それぞれのミニバッチを使ってネットワークモデルをトレーニングしています。ループはmax_iter
回繰り返され、トレーニングデータ全体を複数回学習します。このようにランダムなミニバッチを用いることで、トレーニングデータ全体の特徴を反映しつつ、効率的にネットワークのパラメータを更新することができます。
非復元抽出の場合
コード
np.random.seed(1234) train_size = train_labels.shape[0] batch_size = 32 epochs = 10 network = None #ダミー minibatch_num = np.ceil( train_size / batch_size).astype(int) #学習データをバッチ数で割ってミニバッチ数を求める for epoch in range(epochs): index = np.arange(train_size) np.random.shuffle(index) for mn in range(minibatch_num): batch_mask = index[batch_size*mn:batch_size*(mn+1)] print("epoch=%s, "%epoch, "batch_mask=%s"%batch_mask[:10]) x_batch = train[batch_mask] y_batch = train_labels[batch_mask] trainer(network, x_batch, y_batch)
コード解説
このコードは、ミニバッチ学習を行いながらニューラルネットワークのトレーニングを実行しています。以下にコードの解説を示します。
np.random.seed(1234)
: 乱数のシードを設定しています。これにより、再現性のあるランダムな動作が得られます。train_size = train_labels.shape[0]
:train_labels
のサイズを取得し、train_size
に代入しています。これはトレーニングデータのサンプル数を表します。batch_size = 32
: バッチサイズを定義しています。バッチサイズとは、一度にネットワークに入力するサンプルの数です。epochs = 10
: エポック数を定義しています。エポック数は、トレーニングデータ全体を何回繰り返して学習するかを表します。network = None
: ネットワークモデルを表す変数network
を定義しています。このコードではダミーのままであり、実際のネットワークモデルは記述されていません。minibatch_num = np.ceil(train_size / batch_size).astype(int)
: ミニバッチの個数を計算しています。トレーニングデータのサンプル数をバッチサイズで割り、小数点以下を切り上げて整数に変換しています。for epoch in range(epochs):
: エポック数だけループを実行します。print()
: 空行を出力します。index = np.arange(train_size)
: 0からtrain_size-1
までの連番を生成し、index
に代入しています。これはトレーニングデータのインデックスを表します。np.random.shuffle(index)
:index
の要素をランダムにシャッフルします。これにより、トレーニングデータの順序がランダムになります。for mn in range(minibatch_num):
: ミニバッチの個数だけループを実行します。batch_mask = index[batch_size*mn:batch_size*(mn+1)]
: シャッフルされたインデックスから、ミニバッチに対応する部分配列を抽出し、batch_mask
に代入します。これにより、ミニバッチ内のサンプルのインデックスが得られます。print("epoch=%s, "%epoch, "batch_mask=%s"%batch_mask[:10])
: 現在のエポックとミニバッチのインデックスを出力します。batch_mask[:10]
は最初の10個のインデックスを表します。x_batch = train[batch_mask]
: 選択されたミニバッチのインデックスを使って、トレーニングデータtrain
から対応する部分配列を抽出し、x_batch
に代入します。これにより、ネットワークへの入力データが得られます。y_batch = train_labels[batch_mask]
: 選択されたミニバッチのインデックスを使って、トレーニングデータのラベルtrain_labels
から対応する部分配列を抽出し、y_batch
に代入します。これにより、ネットワークへの正解データが得られます。trainer(network, x_batch, y_batch)
:trainer
関数を呼び出し、ネットワークモデルnetwork
、バッチデータx_batch
、正解データy_batch
を渡しています。この関数は、ネットワークモデルに対してバッチデータを与えてトレーニングを行い、パラメータの更新を行います。
このコードは、与えられたトレーニングデータをエポックごとにシャッフルし、ミニバッチ学習を行いながらニューラルネットワークのトレーニングを実行します。各エポックでは、トレーニングデータをバッチサイズごとに非復元抽出(重複のない抽出)し、ミニバッチを作成します。これにより、トレーニングデータ全体を複数回学習し、ネットワークのパラメータを更新します。