Keras Functional APIを使ってPythonで残差接続(Residual Connection)を扱う方法
KerasはTensorFlowパッケージに標準で含まれており、以下のコードでインポートしてすぐに利用できます。
import tensorflow from tensorflow import keras
KerasのFunctional API(関数型API)は、Sequential APIで作成できるモデルよりも柔軟性の高いモデル構築を可能にします。具体的には、非線形トポロジーを持つモデル、レイヤーを共有するモデル、複数の入力と出力を持つモデルなどに対応できます。深層学習モデルは通常、複数のレイヤーからなる有向非巡回グラフ(DAG:Directed Acyclic Graph)として表現され、Functional APIを使うことでこのレイヤーグラフを自由かつ直感的に構築できます。
本記事のコードはGoogle Colaboratory上で実行しています。Google Colab(Colaboratory)はブラウザ上でPythonコードを実行できる無料サービスで、面倒な環境設定は一切不要です。さらにGPU(Graphics Processing Unit)へも無料でアクセスでき、Jupyter Notebookをベースに構築されています。
それでは、CIFAR10データセット向けの簡易ResNetモデルを例に、残差接続(Residual Connection)を含むモデルの実装方法を見ていきましょう。
サンプルコード
print("Toy ResNet model for CIFAR10")
print("Layers generated for model")
from tensorflow.keras import layers
inputs = keras.Input(shape=(32, 32, 3), name="img")
x = layers.Conv2D(32, 3, activation="relu")(inputs)
x = layers.Conv2D(64, 3, activation="relu")(x)
block_1_output = layers.MaxPooling2D(3)(x)
x = layers.Conv2D(64, 3, activation="relu", padding="same")(block_1_output)
x = layers.Conv2D(64, 3, activation="relu", padding="same")(x)
block_2_output = layers.add([x, block_1_output])
x = layers.Conv2D(64, 3, activation="relu", padding="same")(block_2_output)
x = layers.Conv2D(64, 3, activation="relu", padding="same")(x)
block_3_output = layers.add([x, block_2_output])
x = layers.Conv2D(64, 3, activation="relu")(block_3_output)
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dense(256, activation="relu")(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(10)(x)
model = keras.Model(inputs, outputs, name="toy_resnet")
print("More information about the model")
model.summary()
コード出典:https://www.tensorflow.org/guide/keras/functional
実行結果
Toy ResNet model for CIFAR10
Layers generated for model
More information about the model
Model: "toy_resnet"
________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
=================================================================================
img (InputLayer) [(None, 32, 32, 3)] 0
________________________________________________________________________________
conv2d_32 (Conv2D) (None, 30, 30, 32) 896 img[0][0]
________________________________________________________________________________
conv2d_33 (Conv2D) (None, 28, 28, 64) 18496 conv2d_32[0][0]
________________________________________________________________________________
max_pooling2d_8 (MaxPooling2D) (None, 9, 9, 64) 0 conv2d_33[0][0]
________________________________________________________________________________
conv2d_34 (Conv2D) (None, 9, 9, 64) 36928 max_pooling2d_8[0][0]
________________________________________________________________________________
conv2d_35 (Conv2D) (None, 9, 9, 64) 36928 conv2d_34[0][0]
________________________________________________________________________________
add_12 (Add) (None, 9, 9, 64) 0 conv2d_35[0][0]
max_pooling2d_8[0][0]
________________________________________________________________________________
conv2d_36 (Conv2D) (None, 9, 9, 64) 36928 add_12[0][0]
________________________________________________________________________________
conv2d_37 (Conv2D) (None, 9, 9, 64) 36928 conv2d_36[0][0]
________________________________________________________________________________
add_13 (Add) (None, 9, 9, 64) 0 conv2d_37[0][0]
add_12[0][0]
________________________________________________________________________________
conv2d_38 (Conv2D) (None, 7, 7, 64) 36928 add_13[0][0]
________________________________________________________________________________
global_average_pooling2d_1 (Glo (None, 64) 0 conv2d_38[0][0]
________________________________________________________________________________
dense_40 (Dense) (None, 256) 16640 global_average_pooling2d_1[0][0]
________________________________________________________________________________
dropout_2 (Dropout) (None, 256) 0 dense_40[0][0]
________________________________________________________________________________
dense_41 (Dense) (None, 10) 2570 dropout_2[0][0]
=================================================================================
Total params: 223,242
Trainable params: 223,242
Non-trainable params: 0
________________________________________________________________________________
解説
このモデルは複数の入力と出力を持つことができます。
Functional APIを利用すると、非線形の接続トポロジーも容易に扱えます。
このモデルのレイヤーは順番に直列接続されているわけではないため、「Sequential」APIでは構築できません。
こうしたケースで活躍するのが残差接続(Residual Connection)です。ブロックの出力を次のブロックの入力に加算することで、勾配消失を抑えながら深いネットワークを安定して学習できます。
ここでは、CIFAR10を対象とした簡易的なResNetモデルを構築し、その仕組みを実際のコードで示しました。
-
PythonとKerasのFunctional APIを使ってレイヤーを作成する方法を徹底解説
はじめに TensorFlowはGoogleが提供する機械学習フレームワークです。オープンソースとして公開されており、Pythonと組み合わせてアルゴリズムやディープラーニングアプリケーションの実装など、幅広い用途に活用されています。研究用途から本番環境まで対応しており、複雑な数学的演算を高速に実行するための最適化技術を備えているのが特徴です。 「tensorflow」パッケージは、Windows環境であれば以下のコマンドでインストールできます。 pip install tensorflow Kerasはギリシャ語で「角(つの)」を意味します。Kerasは、ONEIROS(Open-ended
-
PythonでAPIの結果を可視化する方法|GitHub APIとPlotlyを使った実践チュートリアル
はじめにAPIを活用する最大のメリットの一つは、常に最新のライブデータを取得できる点です。データが頻繁に更新される場合でも、API経由なら最新の状態を確実に取得できます。APIプログラムは、特定の情報をリクエストするために専用のURLを使用します。たとえば「SpotifyやYouTube Musicで2020年に最も再生された楽曲トップ100」といった具合です。リクエストされたデータは、JSONやCSVなど、プログラムで扱いやすい形式で返却されます。Pythonを使えば、ほぼあらゆるURLに対してAPI呼び出しを記述できます。本記事では、GitHubのAPIからデータを抽出し、その結果をグラフ