ミニバッチ学習
ミニバッチ学習は機械学習で広く使用されるトレーニングアルゴリズムです。大規模データセットを小さなサブセット(バッチ)に分割し、各イテレーションで一つのバッチのみを使用してモデルをトレーニングします。データセットが大きいほどモデルの精度は向上しますが、計算量が増加しトレーニング時間が長くなります。ミニバッチアプローチは、モデルの精度を維持しつつ計算時間とメモリ消費を削減します。各バッチはモデルに入力され、バッチごとの誤差に基づいてパラメータが更新されます。これにより、各バッチが異なる情報を提供し、モデルの汎化能力が向上します。
Pythonの特殊メソッド
特殊メソッド(マジックメソッド)は、Pythonで二重アンダースコアで囲まれた関数です(例: __init__, __str__)。これらのメソッドはPython内部で呼び出され、演算子のオーバーロード、オブジェクトの作成、オブジェクトの印刷などの特殊機能を実装します。
DataLoaderとDataSet
DataLoaderとDataSetはPyTorchのデータ読み込みの中核をなすコンポーネントです。これらを使用して、反復可能なデータローダーを構築し、各ループでバッチサイズ分のサンプルを読み込んでトレーニングを行います。
- DataSet: PyTorchで使用可能なデータセットの作成を担当
- DataLoader: モデルにデータを渡す役割
Transformersライブラリの概要
Transformersライブラリは、テキスト、画像、音声など様々なモダリティのタスクを実行するための数千の事前学習済みモデルを提供します。これらのモデルは以下の用途に使用できます:
- テキスト: テキスト分類、情報抽出、質問応答、要約、翻訳、テキスト生成など、100以上の言語をサポート
- 画像: 画像分類、物体検出、セグメンテーションなど
- 音声: 音声認識、音声分類など
Transformersモデルは、表形式の質問応答、光学文字認識、スキャン文書からの情報抽出、ビデオ分類、視覚的質問応答など、複数のモダリティを組み合わせたタスクも実行できます。TransformersはJax、PyTorch、TensorFlowという3つの主要な深層学習ライブラリをサポートし、それらの間でシームレスに統合されています。
torchvisionの概要
torchvisionはPyTorch深層学習フレームワーク用のグラフィックライブラリで、コンピュータビジョンモデルの構築に主に使用されます。torchvisionの構成要素は以下の通りです:
- torchvision.datasets: データ読み込み関数と一般的なデータセットインターフェース
- torchvision.models: AlexNet、VGG、ResNetなどの一般的なモデル構造(事前学習済みモデルを含む)
- torchvision.transforms: 裁剪、回転などの一般的な画像変換
- torchvision.utils: その他の便利なメソッド
torch.no_grad()
torch.no_grad()はPyTorchのコンテキストマネージャーで、このコンテキスト内では勾配計算を無効にします。これはモデルの評価のみを行い、トレーニングを行わない場合に非常に有用です。メモリ使用量を大幅に削減し、計算を高速化します。torch.no_grad()コンテキストマネージャー内でテンソル操作を実行すると、PyTorchはこれらの操作の勾配を計算しません。つまり、.grad属性に勾配が蓄積されず、操作がより高速に実行されます。
活性化関数
活性化関数は通常、ニューロンの加重入力(活性化前の値)に作用し、非線形の出力値を生成してニューロンの活性化状態として次の層のニューロンに渡すか、出力層の最終出力として使用します。
一般的な非線形関数には以下のようなものがあります:
- Sigmoid関数: 入力を[0, 1]の範囲にマッピングし、二値分類問題や出力層の活性化関数としてよく使用されます
- Tanh関数: 入力を[-1, 1]の範囲にマッピングし、これも二値分類問題や出力層の活性化関数としてよく使用されます
- ReLU関数(Rectified Linear Unit): 負の入力を0にマッピングし、正の入力はそのまま保持します。隠れ層の活性化関数としてよく使用されます
- Softmax関数: 入力を確率分布にマッピングします(出力ベクトルの各値が正で、要素の合計が1になる)。多クラス分類問題の出力層でよく使用されます
Q: なぜ非線形変換が必要なのですか?
A: 活性化関数は非線形操作を導入し、ニューラルネットワークが複雑な非線形関係をより適切にフィッティングできるようにします。ニューラルネットワークが線形活性化関数のみを使用する場合、ネットワーク全体は複数の線形操作の組み合わせとなり、非線形データを処理したり非線形マッピングを学習したりすることができません。
Softmax
Softmaxは活性化関数の一種で、数値ベクトルを確率分布ベクトルに正規化し、各確率の合計が1になるようにします。Softmaxはニューラルネットワークの最終層として使用され、多クラス分類問題の出力に使用されます。Softmax層は交差エントロピー損失関数と組み合わせてよく使用されます。
二値分類問題では、Sigmoid関数(Logistic関数とも呼ばれる)を使用できます。これは(-∞,+∞)の範囲の数値を(0,1)の区間の数値にマッピングし、(0,1)の区間の数値は確率を表すのに適しています。多クラス分類問題では、各クラスの確率を予測するためにSoftmax関数が一般的に使用されます。
ReLU
ReLU(Rectified Linear Unit、日本語では線形整流関数)は、ニューラルネットワークで一般的に使用される活性化関数です。通常、数学におけるランプ関数を指します。
非線形活性化関数を導入する目的は、ニューラルネットワークの非線形フィッティング能力を高め、モデルの表現能力を向上させることです。したがって、特に指定がない場合、活性化関数は非線形活性化関数を指します。厳密な数学的導出から、ネットワークで活性化関数を使用しない場合、各層のノードの入力は上層の出力の線形関数となり、ニューラルネットワークの隠れ層がいくつあっても、最終的な出力結果はネットワーク入力の線形フィッティングとなり、隠れ層がその役割を果たさないことがわかります。このため、非線形関数を活性化関数として導入し、モデルの表現能力を向上させます。
隠れ層
人工ニューラルネットワーク(ANN)において、隠れ層(Hidden Layer)は、入力層と出力層の間にある1つ以上のニューロンの集合です。ニューラルネットワークの中間層として、隠れ層は入力データの特徴抽出と変換を担当し、複雑な非線形マッピング関係を実現します。
ニューラルネットワークのトレーニング
順伝播(Forward Propagation)
順伝播(Forward Propagation)は、ニューラルネットワーク内で情報を伝達するプロセスであり、ニューラルネットワークトレーニングの最初のステップです。順伝播では、入力データがニューラルネットワークの複数の層(入力層、隠れ層、出力層を含む)を通じて、事前に定義された重みとバイアスに基づいて計算され、入力層から出力層へと伝達され、最終的にニューラルネットワークの予測結果を得ます。
勾配降下法
勾配降下法は、極小値を見つけるための手法です。関数上の現在の点に対応する勾配(または近似勾配)の反対方向に、決められたステップサイズだけ移動することを繰り返し、極小点に収束するまで探索を続けます。
確率的勾配降下法(Stochastic Gradient Descent, SGD)
optim.SGDはPyTorchのオプティマイザの一つで、確率的勾配降下法(SGD)を実装しています。深層学習では、通常、オプティマイザを使用してニューラルネットワークのパラメータを更新し、損失関数を可能な限り小さくします。
PyTorchでoptim.SGDオプティマイザを使用する場合、通常以下のパラメータを指定する必要があります:
params: 更新が必要なパラメータ、通常はモデルの重みとバイアス項lr: 学習率、パラメータ更新時のステップサイズmomentum: モメンタム、モデルの収束速度を加速し、局所最適解に陥るのを避けるために使用dampening: モメンタムの減衰、モメンタムの減衰速度を制御weight_decay: 重み減衰、モデルの過学習を防ぐため、重みのL2正則化によってモデルの複雑さを制約nesterov: Nesterovモメンタムを使用するかどうか
損失関数
損失関数(Loss Function)は、目的関数、コスト関数、または目的損失関数とも呼ばれ、教師あり学習でモデルの予測値と真のラベルとの差異を測定する関数です。
torch.nn.CrossEntropyLoss()、交差エントロピー損失関数
- 交差エントロピー損失関数は、入力されたモデルの予測値に対して自動的にsoftmaxを適用します。したがって、多クラス分類問題でnn.CrossEntropyLoss()を使用する場合、予測モデルの出力層にsoftmaxを追加する必要はありません。
- nn.CrossEntropyLoss() = nn.LogSoftmax() + nn.NLLLoss()です。
- 交差エントロピー損失関数は分類タスクに使用され、平均二乗誤差損失関数は回帰タスクに使用されます。
# 損失関数とオプティマイザの構築、PyTorch APIを使用
criterion = torch.nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.5)
# トレーニングサイクル:順伝播、逆伝播、更新
# 順伝播で損失を計算し、逆伝播で損失に関する勾配を計算し、更新では勾配降下法を使用して勾配を利用して更新
def train(epoch):
running_loss = 0.0
for batch_idx, data in enumerate(train_loader, 0):
# バッチデータとラベルを取得
inputs, target = data
optimizer.zero_grad()
# 順伝播 + 逆伝播 + 更新
outputs = model(inputs)
loss = criterion(outputs, target)
loss.backward()
optimizer.step()
running_loss += loss.item()
if batch_idx % 300 == 299:
print('[%d, %5d] loss: %.3f' % (epoch + 1, batch_idx + 1, running_loss / 300))
running_loss = 0.0
逆伝播
逆伝播(Backpropagation)は、ニューラルネットワークの各層の重みとバイアスの勾配を計算するために使用され、モデルパラメータの更新を実現します。これは順伝播の逆プロセスであり、損失関数のニューラルネットワーク出力に対する勾配を計算し、出力層から入力層へと層ごとに逆方向に伝播させ、各層の勾配を計算し、モデルパラメータの更新に使用します。
勾配消失問題(Gradient Vanishing)とは、深層ニューラルネットワークにおいて、逆伝播アルゴリズムで計算された勾配がネットワークの深い層で徐々に非常に小さくなり、ゼロに近づく現象を指します。これにより、これらの層の重み更新が非常に遅くなるか、停止してしまい、これらの層のパラメータが効果的にトレーニングできなくなります。
勾配爆発は、複数の乗算操作を経ることで、各乗算操作が勾配を拡大し、勾配値が非常に大きくなる現象です。これにより勾配爆発(Gradient Explosion)が発生します。
最適化アルゴリズム
最適化アルゴリズムは、パラメータを更新する際にステップサイズや方向などの要素をどのように調整して損失関数の値を最小化するかを決定します。確率的勾配降下法が最も一般的な最適化アルゴリズムです。
Transformerモデル
Transformerの全体構造
元のTransformerには6つのエンコーダと6つのデコーダがあります。
Transformerは本来、変圧器や変換器を意味し、/trænsˈfɔːmə(r)/と発音します。2017年6月、Googleチームが発表した論文「Attention Is All You Need」で、Transformerが初めて人工知能の文脈で紹介されました。当時、これはアテンションに基づくエンコーダ/デコーダモデルとして説明されました。今日、Transformerについて話すとき、それは人工知能の古典的なフレームワークとなり、大きなファミリーを形成しています。
Transformerモデルの設計は、長いシーケンスデータを処理する際の従来のリカレントニューラルネットワーク(RNN)や畳み込みニューラルネットワーク(CNN)の制限を解決します。最も重要な特性は、自己注意機構(Self-Attention)とマルチヘッド注意機構(Multi-Head Attention)です。Transformerモデルは自己注意機構を通じて入力シーケンス内の異なる位置間の依存関係を構築し、シーケンス内の長距離依存関係を効果的に捉えます。
Tensor: テンソル
# PyTorchでは、Tensorは動的計算グラフを構築するための重要なコンポーネントです
weight_val = torch.tensor([1.0]) # weight_valの初期値を1.0に設定
weight_val.requires_grad = True # 勾配を計算する必要がある
# 自動微分メカニズムが必要な場合、Tensorのrequires_grad要素をTrueに設定する必要があります。
# Tensor: テンソルは多次元配列であり、スカラー、ベクトル、行列の高次元への拡張です。
# テンソルはデータ構造であり、ニューラルネットワークモデルの入力、出力、モデルパラメータなどを表現またはエンコードするために使用されます。
Tensor: テンソル(Tensor)は多次元配列であり、スカラー、ベクトル、行列の高次元への拡張です。テンソルはデータ構造であり、ニューラルネットワークモデルの入力、出力、モデルパラメータなどを表現またはエンコードするために使用されます。
F.avg_pool2d()関数
avg_pool2d(input, kernel_size, stride=None, padding=0, ceil_mode=False, count_include_pad=True, divisor_override=None)
2D平均プーリング操作を実行します。パラメータ:
- input: 入力テンソル、[batch_size, channels, height, width]
- kernel_size: プーリング領域のサイズ、数値n(kernel=(n,n))または(kh,kw)の形式
- stride: プーリング操作のストライド、スカラーまたは(sh, sw)。デフォルトはkernelと同じで、これは2次元であるため、heightとwidthの両方でkernelと一致し、境界を越えた場合は破棄されます
- padding: デフォルトでは入力inputの周囲に0をパディングします。スカラーまたは(padh, padw)で指定できます
- ceil_mode: true(ceilを使用)、false(floorを使用)
- count_include_pad: true(平均を計算する際にパディングされた0を含める)
PyTorchのF.avg_pool2d()平均プーリング操作は2次元用で、inputは4次元です。PyTorchのF.avg_pool1d()平均プーリング操作は1次元用で、inputは3次元です。
torch.nn.MaxPool2d
作用: 隣接領域内の特徴点の最大値を取り、畳み込み層のパラメータ誤差による平均値の推定の偏りの誤差を減らし、テクスチャ情報をより多く保持します。
torch.cat
torch.cat(tensors, dim=0, *, out=None)、つまり2つのパラメータがあり、一つは結合するテンソル、もう一つはどの次元で結合するかです。この関数は2つのテンソルを指定された次元で結合します。注意:結合次元dimの数値は異なっていても構いませんが、その他の次元の数値は同じである必要があり、そうでないと整列できません。
dim = 0: 列方向に整列
dim = 1: 行方向に整列
torch.nn.Conv2d
nn.Conv2d: 複数の入力平面からなる入力信号に対して2次元畳み込みを実行します。
GoogLeNetネットワーク
一、GoogLeNetネットワークの背景
より良い予測効果を得るためには、ネットワークの深さと幅の両方の観点からネットワークの複雑さを増やす必要があります。
しかし、このアプローチには2つの明らかな問題があります:
まず、より複雑なネットワークはより多くのパラメータを意味し、過学習しやすくなります。
次に、より複雑なネットワークはより多くの計算リソースを消費し、畳み込みカーネルの数の設計が不合理である場合、畳み込みカーネル内のパラメータが完全に利用されない(多くの重みが0に近づく)と、大量の計算リソースの浪費につながります。したがって、GoogLeNetはネットワーク構造を深めることに集中しつつ、ネットワークの幅を増やすために新しい基本構造であるInceptionモジュールを導入しました。GoogLeNetは合計22層で、全結合層がなく、2014年のImageNet画像認識チャレンジで優勝しました。
二、Inceptionモジュール
GooLeNetのInceptionモジュールの基本構成要素は4つあります:1x1畳み込み、3x3畳み込み、5x5畳み込み、3x3最大プーリングです。
ResNets 残差ネットワーク
ResNetは2015年に何凱明、張翔宇、任少卿、孫剣によって共同で提案されました。ResNetは新しい思想を使用しています。ResNetの思想は、最適化されたネットワーク層が存在すると仮定すると、設計した深層ネットワークには多くの冗長層があるということです。これらの冗長層が恒等写像を完成させ、その恒等層を通過した入力と出力が完全に同じになることを望みます。具体的にどの層が恒等層であるかは、ネットワークのトレーニング中に自己判断されます。
残差ネットワークは、ある程度、モデルの劣化問題(最適化の困難さにより、ネットワークが深くなるにつれてトレーニングセットの精度が逆に低下する問題)を解決します。ブロックの入力と出力の間に直接的な経路(スキップ接続と呼ばれる)を導入します。スキップ接続の導入により、情報の流れがよりスムーズになります:一是順伝播時に入力と出力の情報を融合し、特徴をより効果的に利用できること、二是逆伝播時に一部の勾配が常にスキップ接続を通じて入力に逆伝播し、勾配消失問題を緩和することです。
標準的な最適化アルゴリズム(勾配降下法など)を使用して通常のネットワークをトレーニングする場合、残差やショートカット(スキップ接続)がないと、経験的にネットワークの深さが増すにつれてトレーニング誤差は最初減少し、その後増加することがわかります。理論的には、ネットワークが深くなるほど、より良くトレーニングできるはずです。つまり、理論的にはネットワークは深いほど良いはずです。しかし、実際には、残差ネットワークがない場合、通常のネットワークでは深くなるほど最適化アルゴリズムでトレーニングするのが難しくなります。実際、ネットワークが深くなるにつれて、トレーニング誤差はますます大きくなります。
しかし、ResNetsでは状況が異なり、ネットワークがどれだけ深くても、トレーニングのパフォーマンスは良好です。例えば、100層の深いネットワークをトレーニングする場合でも、トレーニング誤差は減少します。1000層以上のニューラルネットワークで実験した人もいます。これにより、より深いネットワークをトレーニングしながら、良好なパフォーマンスを保証できます。別の観点から見ると、ネットワークが深くなるにつれて接続が肥大化しますが、ResNetは確かに深層ネットワークのトレーニングに非常に効果的です。
手書き数字の特徴抽出
白黒の手書き数字の場合、どのような特徴を機械学習の入力として与えるべきでしょうか?
答えは、その画像を構成する28×28=784個のピクセルのグレースケール値です!各ピクセルに対して、0から1までの値を割り当てます。ピクセルが黒いほど0に近づき、白いほど1に近づきます。