Sigmoid
シグモイド関数は、任意の実数を0から1の間の値に変換します。数式、勾配、確率出力、ゲート、PyTorchコードについて解説します。
シグモイド関数σ(x) = 1 / (1 + e^(−x))は、S字型の曲線に沿って任意の実数を0から1の値に変換します。大きな負の入力では出力が0に近く、大きな正の入力では1に近くなり、入力が0の場合は正確に0.5になります。機械学習 (ML)で「シグモイド」といえば、ほぼ常にこのロジスティック関数を指します。ロジスティック回帰で線形スコアを確率に変換するのと同じ曲線です。ニューラルネットワーク (NN)では、シグモイドは3つの役割を担います。初期には隠れ層の活性化関数として使われ、最終スコアを二値およびマルチラベル出力の確率に変換し、再帰セルなどのゲート付き層では柔らかなオン・オフスイッチとして機能します。その後、隠れ層ではReLUなどの関数が使われるようになったため、現在のモデルにおけるシグモイドの大半は出力とゲートに使われています。
数式と特性#
シグモイドは中点を中心に対称で、σ(−x) = 1 − σ(x)となります。逆関数はlogit関数log(p / (1 − p))で、確率を対数オッズに戻します。そのため、シグモイドを適用する前のネットワークの生の出力はlogitと呼ばれます。導関数は簡潔な形σ′(x) = σ(x)(1 − σ(x))で表され、x = 0で最大値0.25となります。曲線が両端で平坦になるにつれてゼロに近づくこの挙動は、飽和と呼ばれます。以下のPyTorchのコードは、5つの点で出力と勾配を計算します。
import torch
x = torch.tensor([-6.0, -2.0, 0.0, 2.0, 6.0], requires_grad=True)
y = torch.sigmoid(x)
# Backpropagate to get the derivative sigmoid(x) * (1 - sigmoid(x)) at each input
y.sum().backward()
print(f"Sigmoid: {[round(v, 4) for v in y.tolist()]}")
print(f"Gradient: {[round(v, 4) for v in x.grad.tolist()]}")出力にはシグモイドの値[0.0025, 0.1192, 0.5, 0.8808, 0.9975]と勾配[0.0025, 0.105, 0.25, 0.105, 0.0025]が表示されます。±6では出力が極限値から0.0025以内に収まり、勾配はゼロの場合の100分の1です。そのため、この範囲の入力では、その入力を生成した重みはほとんど変化しません。
隠れ層におけるシグモイド#
初期の多層ネットワークでは、すべての隠れ層にシグモイドを使用していたため、2つの問題が発生しました。誤差逆伝播では層ごとに1つの活性化導関数を乗算します。シグモイドの導関数は0.25を超えないため、シグモイド層が10層あると、これらの導関数だけで勾配は最大でも0.25¹⁰、つまり100万分の1未満になります。これが勾配消失の問題です。また、シグモイドの出力は常に正であるため、それを受け取るニューロンの重み勾配は各更新で同じ符号になり、重みは最適値に向かってジグザグにしか進めません。tanhは出力をゼロ中心にし、Xavier GlorotとYoshua Bengioは2010年に、シグモイドの正の平均値によって、ランダムに初期化されたディープネットワークの最上位隠れ層が飽和状態になることを示しました。ReLUは両方の問題を解消し、隠れ層のデフォルトとなりました。SiLUのような滑らかな後継関数も、x · σ(x)のようにゲートとして内部でシグモイドを使用します。
出力層としてのシグモイド#
二値分類では、1つの出力zをp = σ(z)に変換し、正例クラスの予測確率とします。pに対するしきい値0.5は、zに対するしきい値0と同じです。学習ではシグモイドと二値クロスエントロピーを組み合わせます。このときlogitに対する勾配は、予測確率とラベルの差であるp − yとなります。数値安定性を確保するため、フレームワークでは両者を融合します。PyTorchのBCEWithLogitsLossは生のlogitを受け取り、内部でlog-sum-expトリックを使います。これにより、0または1に丸められた確率の対数を取ることを避けられます。
ラベルが同時に存在する場合、モデルはラベルごとに1つのシグモイドを使います。この構成はマルチラベル分類と呼ばれます。一方、softmaxはクラス間で確率の合計が1になるようにし、互いに排他的なラベルに適しています。
import torch
# Logits from a classifier for the labels "person", "backpack", and "car"
logits = torch.tensor([2.0, 1.5, -3.0])
# Sigmoid scores each label on its own; softmax makes the labels compete for one total
sigmoid_probs = torch.sigmoid(logits)
softmax_probs = torch.softmax(logits, dim=0)
print(f"Sigmoid: {[round(p, 3) for p in sigmoid_probs.tolist()]}, sum {sigmoid_probs.sum():.3f}")
print(f"Softmax: {[round(p, 3) for p in softmax_probs.tolist()]}, sum {softmax_probs.sum():.3f}")シグモイドのスコア[0.881, 0.818, 0.047]の合計は1.746です。そのため、「person」と「backpack」はどちらも0.5を超えます。一方、softmaxは同じlogitを[0.62, 0.376, 0.004]に分配し、「person」だけが0.5を超えます。YOLO26の検出モデルは、BCEWithLogitsLossで学習した独立したシグモイドで各クラスを評価するため、ボックスのクラススコアの合計は1になるとは限りません。また、YOLO26の姿勢推定モデルは、各キーポイントの可視性logitにシグモイドを適用し、そのキーポイントが見えている確率を出力します。
ゲートとしてのシグモイド#
出力が0から1の範囲にあるため、シグモイドは別の信号を要素ごとにスケーリングできます。完全に遮断した状態から完全に通過させる状態まで調整でき、微分可能性も保たれます。
- LSTMとGRUセル: シグモイドゲートは、各時刻で古いメモリをどれだけ保持するか、新しい情報をどれだけ書き込むか、状態をどれだけ出力するかを決めます。tanhは情報自体の形状を調整します。
- SwiGLU: 多くの大規模言語モデル (LLM)のフィードフォワード層では、学習可能な射影の1つに、SiLUで活性化した2つ目の射影を乗算します。これはシグモイドに基づくゲートです。
- SigLIP: この画像・テキストモデルは、バッチ内の画像とキャプションのすべてのペアを、それぞれ独立したシグモイドで評価して一致確率を出します。そのため、損失の計算でバッチ全体の正規化は必要ありません。
シグモイドと関連関数の比較#
- ロジスティック関数: 機械学習ではシグモイドの同義語です。数学では、「シグモイド」はtanhや誤差関数など、ほかのS字型曲線も指します。
- softmax: ベクトル全体を、合計が1になる確率に正規化します。2クラスの場合、logit (z₁, z₂)に対するsoftmaxは第1クラスについてσ(z₁ − z₂)を与えるため、2出力のsoftmaxと1出力のシグモイドは同じモデルを表します。
- tanh: スケーリングされたシグモイドで、tanh(x) = 2σ(2x) − 1です。出力は−1から1まででゼロ中心となり、導関数の最大値は1です。
- Hard sigmoid: モバイルハードウェアで指数関数を使わずに済む、区分線形近似です。MobileNetV3ではReLU6(x + 3) / 6を使います。x = −3未満では0、x = 3より大きい場合は1となり、その間は直線です。










