Computer368106 views
高校倫理1440106 views
高校物理160203 views
数学講師2886227 views
小学算数1200427 views
教育149510 views
高校日本史190571 views
いろは3010814 views
中学英語811710 views
高校化学2924392 views
Help
Tools
NewsSpreadsheetCalendarSlidesTier ListPen ToolIllustrationCrayonPixel ArtASCII ArtPerspectiveEndless StairsGraphMind MapER DiagramFamily TreeMemeCurved TextImage EditorMosaicRetro FilterPencil SketchOCR/HighlighterMakeup EditorFaviconVideo TrimmerScrolling VideoVideo TitleColor PickerColor ExtractorBonfireFireworksWater RippleWater SplashBreaking GlassWood GrainMarble TextureCSS ButtonIcon MakerBar ChartGrouped Bar ChartStacked Bar ChartPie ChartLine ChartArea ChartStacked Area ChartScatter Plot3D Bar Chart3D Pie ChartBar Chart RaceBubble ChartPopulation PyramidPictogramEarningsCandlestick ChartInvestment RiskMortgage SimulatorCalculatorMatrix CalculatorFunction GraphPolynomial ExpansionVenn DiagramField VisualizerRubik's Cube Group TheoryTraveling SalesmanVoronoi and DelaunayFractalColumn ArithmeticDraw Math FiguresArithmetic AnimationArithmetic Word ProblemsCounting with Tree DiagramsCube NetsCross SectionsMotion PathMechanicsWavesLight and LensesThermodynamicsHow Semiconductors WorkMolecular StructuresAtomic OrbitalsElectrochemical CellsChemical EquilibriumCrystal LatticesBuffer pHComplex IonsDNA Double HelixCell DivisionMembrane ChannelsNerve ImpulseRock ClassificationWeatherConstellationsSolar and Lunar Eclipses3D ModelingFloor PlanSeismic StructuresIntersection TurnMaglevCooking AnimationOrigamiLive Viewer CountGeoJSON MapRailway MapPopulation MapCrime MapLand Price MapSchool MapShrine and Castle MapHouse of Representatives MapWord MapSolitaireReversiHakoiri MusumeChessHamburgerRippleSlide Puzzle MakerNeon PinballNovel MakerJapanese Typing PracticePiano Score EditorMusic Theory

English

TensorFlow の損失関数とオプティマイザ

モデルの訓練とは、損失関数が返す値を小さくするようにパラメータを調整する作業にほかならない。損失関数が「どれだけ間違っているか」を測り、オプティマイザが「どう直すか」を決める。この 2 つはモデルの学習能力を左右する重要な要素であり、タスクに合った組み合わせを選ぶことが精度向上の第一歩になる。

損失関数の役割

損失関数はモデルの予測値と正解ラベルの「ズレ」を 1 つの数値にまとめる関数だ。この数値が小さいほど予測が正解に近いことを意味する。訓練ではこの値を最小化する方向にパラメータが更新されていく。

モデルが予測を出力

損失関数が予測と正解のズレを計算

オプティマイザがズレを小さくする方向に重みを更新

損失関数の選択を誤ると、モデルがまったく学習しなかったり、見当違いの方向に最適化されたりする。タスクの種類に応じた正しい選択が不可欠だ。

分類タスクの損失関数

分類タスクでは交差エントロピー(cross entropy)系の損失関数を使う。正解クラスに割り当てられた確率が高いほど損失は小さくなり、低いほど大きくなるという仕組みだ。

binary_crossentropy

2 クラス分類用。出力層のユニット数は 1、活性化関数は sigmoid を使う。メールのスパム判定や病気の陽性 / 陰性判定など、答えが 2 択の場合に選ぶ。

sparse_categorical_crossentropy

多クラス分類用で、ラベルが整数(0, 1, 2, …)の場合に使う。MNIST の手書き数字(0〜9)のように、ラベルがそのまま整数で与えられる場面で便利だ。

categorical_crossentropy

多クラス分類用で、ラベルが one-hot ベクトル([0, 0, 1, 0] など)の場合に使う。sparse 版と数学的には等価だが、ラベルの形式だけが異なる。

sparse と通常版のどちらを使うかは、ラベルの形式で機械的に決まる。整数ラベルなら sparse、one-hot ラベルなら通常版を選べばよい。

2 クラス分類の例

スパム判定のような 2 クラス分類では、出力層に sigmoid を置き、損失関数に binary_crossentropy を指定する。

model = keras.Sequential([
    layers.Dense(64, activation="relu", input_shape=(100,)),
    layers.Dense(32, activation="relu"),
    layers.Dense(1, activation="sigmoid"),
])

model.compile(
    optimizer="adam",
    loss="binary_crossentropy",
    metrics=["accuracy"],
)

sigmoid は出力を 0〜1 の範囲に押し込む関数で、「クラス 1 に属する確率」と解釈できる。0.5 を閾値にして 0 か 1 に分類するのが一般的な使い方だ。

多クラス分類の例

出力層に softmax を置くと、各クラスの確率分布が得られる。すべての出力の合計は 1 になる。

model = keras.Sequential([
    layers.Dense(128, activation="relu", input_shape=(784,)),
    layers.Dense(64, activation="relu"),
    layers.Dense(10, activation="softmax"),
])

model.compile(
    optimizer="adam",
    loss="sparse_categorical_crossentropy",
    metrics=["accuracy"],
)
binary_crossentropy + sigmoid

出力は 1 つの確率値(0〜1)。2 クラス分類専用。

sparse_categorical_crossentropy + softmax

出力はクラス数ぶんの確率分布。多クラス分類に対応。

回帰タスクの損失関数

回帰タスクでは、予測値と正解値の数値的な距離を損失として計算する。

損失関数計算方法特徴
mse誤差の 2 乗の平均外れ値に敏感
mae誤差の絶対値の平均外れ値に頑健
huber小さい誤差は mse、大きい誤差は mae両者の中間的な性質

住宅価格の予測を例にとると、次のようになる。

model = keras.Sequential([
    layers.Dense(64, activation="relu", input_shape=(13,)),
    layers.Dense(32, activation="relu"),
    layers.Dense(1),
])

model.compile(
    optimizer="adam",
    loss="mse",
    metrics=["mae"],
)

回帰の出力層には活性化関数を指定しない。値の範囲に制約を設けず、任意の実数を出力させるためだ。

オプティマイザの役割

損失関数が「現在の誤差」を教えてくれるのに対し、オプティマイザは「パラメータをどの方向にどれだけ動かすか」を決定する。すべてのオプティマイザは勾配降下法を基盤としており、損失関数の勾配(傾き)を手がかりに重みを更新していく。

勾配降下法の基本的な更新式は で表される。 は重み、学習率 は損失の勾配だ。

1 回の更新でパラメータをどれだけ動かすかを制御するハイパーパラメータ。大きすぎると発散し、小さすぎると収束が遅い。

主要なオプティマイザ

SGD(確率的勾配降下法)

もっとも基本的なオプティマイザ。勾配の方向にそのまま重みを更新する。momentum を加えると過去の勾配を考慮し、振動を抑えながら収束を速められる。シンプルなぶん挙動が予測しやすく、学習率のスケジューリングと組み合わせると高い最終精度を出すことがある。

Adam(Adaptive Moment Estimation)

勾配の平均(1 次モーメント)と勾配の 2 乗の平均(2 次モーメント)を使い、パラメータごとに学習率を自動調整する。デフォルト設定のまま幅広いタスクで安定した結果を出すため、最初に試すオプティマイザとして定番になっている。

RMSprop

勾配の 2 乗の移動平均で学習率を調整する。Adam から 1 次モーメントの補正を除いたような構造をしており、RNN 系のタスクで特に有効とされている。

オプティマイザの使い分け

文字列で指定するとデフォルト設定が適用される。ハイパーパラメータを細かく調整したい場合はオブジェクトで渡す。

# 文字列で指定(デフォルト設定)
model.compile(optimizer="adam", loss="mse")

# オブジェクトで指定(学習率を変更)
model.compile(
    optimizer=keras.optimizers.Adam(learning_rate=0.0001),
    loss="mse",
)

# SGD + momentum
model.compile(
    optimizer=keras.optimizers.SGD(learning_rate=0.01, momentum=0.9),
    loss="mse",
)

Adam のデフォルト学習率は 0.001 で、多くのケースではこの値で十分に機能する。精度が伸び悩んだときに 0.0001 や 0.0005 に下げてみるのは有効なアプローチだ。

学習率の影響

学習率はオプティマイザの中でもっとも重要なハイパーパラメータだ。値によって訓練の挙動は大きく変わる。

学習率が大きすぎる場合

損失が振動したり発散したりして、モデルが収束しない。最適解の周囲を飛び越えてしまう。

学習率が小さすぎる場合

損失は安定して下がるが、収束に非常に時間がかかる。局所最適解に捕まりやすくもなる。

学習率を訓練の途中で動的に変化させるスケジューリングという手法もある。たとえば最初は大きめの学習率で素早く収束に近づき、後半で小さくして精密に調整するやり方だ。

lr_schedule = keras.optimizers.schedules.ExponentialDecay(
    initial_learning_rate=0.01,
    decay_steps=1000,
    decay_rate=0.9,
)

model.compile(
    optimizer=keras.optimizers.Adam(learning_rate=lr_schedule),
    loss="sparse_categorical_crossentropy",
    metrics=["accuracy"],
)

ExponentialDecay は指定したステップごとに学習率を指数的に減衰させる。1000 ステップごとに学習率が 0.9 倍になるため、訓練の後半では自動的に細かい調整に切り替わる。

タスク別の推奨設定

最後に、タスクの種類と損失関数・出力層・オプティマイザの典型的な組み合わせをまとめておく。

タスク損失関数出力層
2 クラス分類binary_crossentropysigmoid(1 ユニット)
多クラス分類sparse_categorical_crossentropysoftmax(クラス数)
回帰mse または mae活性化なし(1 ユニット)

オプティマイザは迷ったら Adam から始め、精度が頭打ちになったら学習率の調整や SGD + momentum への切り替えを検討する。損失関数とオプティマイザの正しい選択は、モデルの構造設計と同じくらい訓練の成否を左右する要素だ。

ラベルが整数(0〜9)で与えられる 10 クラス分類で、適切な損失関数はどれか?

  • binary_crossentropy
  • mse
  • sparse_categorical_crossentropy
  • huber
__RESULT__

整数ラベルの多クラス分類には sparse_categorical_crossentropy を使う。one-hot ベクトルに変換してあるなら categorical_crossentropy を選ぶ。binary_crossentropy は 2 クラス専用、mse と huber は回帰タスク向けだ。