Keras Core 0.1 : 開発者ガイド : Getting started with Keras Core (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 07/13/2023 (0.1.0)
* 本ページは、Keras の以下のドキュメントを翻訳した上で適宜、補足説明したものです:
- Getting started with Keras Core
(Author: fchollet ; Date created: 2023/07/10 ; Last modified: 2023/07/10)
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- 人工知能研究開発支援
- 人工知能研修サービス(経営者層向けオンサイト研修)
- テクニカルコンサルティングサービス
- 実証実験(プロトタイプ構築)
- アプリケーションへの実装
- 人工知能研修サービス
- PoC(概念実証)を失敗させないための支援
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
- 株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション
- sales-info@classcat.com ; Web: www.classcat.com ; ClassCatJP
Keras Core 0.1 : 開発者ガイド : Getting started with Keras Core
イントロダクション
Keras Core は TensorFlow, JAX そして PyTorch と交換可能に動作する Keras API の完全な実装です。このノートブックは主要な Keras Core ワークフローを紹介します。
最初に、Keras Core をインストールしましょう :
!pip install -q keras-core
セットアップ
ここでは JAX バックエンドを使用していきます — しかし下の文字列を “tensorflow” や “torch” に編集して “Restart runtime” と打ち込むことができて、その場合ノートブック全体は同じように動作します!このガイド全体はバックエンド透過 (不可知, agnostic) です。
import numpy as np
import os
os.environ["KERAS_BACKEND"] = "jax"
# Note that keras_core should only be imported after the backend
# has been configured. The backend cannot be changed once the
# package is imported.
import keras_core as keras
Using JAX backend.
最初の例: MNIST convnet
Let’s start with the Hello World of ML: convnet を訓練して MNIST 数字を分類します。
Here’s the data:
# Load the data and split it between train and test sets
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
# Scale images to the [0, 1] range
x_train = x_train.astype("float32") / 255
x_test = x_test.astype("float32") / 255
# Make sure images have shape (28, 28, 1)
x_train = np.expand_dims(x_train, -1)
x_test = np.expand_dims(x_test, -1)
print("x_train shape:", x_train.shape)
print("y_train shape:", y_train.shape)
print(x_train.shape[0], "train samples")
print(x_test.shape[0], "test samples")
x_train shape: (60000, 28, 28, 1) y_train shape: (60000,) 60000 train samples 10000 test samples
Here’s our model.
Keras が提供する様々なモデル構築オプションは以下のようなものです :
- シーケンシャル API (下で使用するものです)
- 関数型 API (最も典型的)
- サブクラス化により貴方自身でモデルを書く (上級ユースケース)
# Model parameters
num_classes = 10
input_shape = (28, 28, 1)
model = keras.Sequential(
[
keras.layers.Input(shape=input_shape),
keras.layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
keras.layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
keras.layers.MaxPooling2D(pool_size=(2, 2)),
keras.layers.Conv2D(128, kernel_size=(3, 3), activation="relu"),
keras.layers.Conv2D(128, kernel_size=(3, 3), activation="relu"),
keras.layers.GlobalAveragePooling2D(),
keras.layers.Dropout(0.5),
keras.layers.Dense(num_classes, activation="softmax"),
]
)
Here’s our model summary:
model.summary()
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┓ ┃ Layer (type) ┃ Output Shape ┃ Param # ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━┩ │ conv2d (Conv2D) │ (None, 26, 26, 64) │ 640 │ ├─────────────────────────────────┼───────────────────────────┼────────────┤ │ conv2d_1 (Conv2D) │ (None, 24, 24, 64) │ 36,928 │ ├─────────────────────────────────┼───────────────────────────┼────────────┤ │ max_pooling2d (MaxPooling2D) │ (None, 12, 12, 64) │ 0 │ ├─────────────────────────────────┼───────────────────────────┼────────────┤ │ conv2d_2 (Conv2D) │ (None, 10, 10, 128) │ 73,856 │ ├─────────────────────────────────┼───────────────────────────┼────────────┤ │ conv2d_3 (Conv2D) │ (None, 8, 8, 128) │ 147,584 │ ├─────────────────────────────────┼───────────────────────────┼────────────┤ │ global_average_pooling2d │ (None, 128) │ 0 │ │ (GlobalAveragePooling2D) │ │ │ ├─────────────────────────────────┼───────────────────────────┼────────────┤ │ dropout (Dropout) │ (None, 128) │ 0 │ ├─────────────────────────────────┼───────────────────────────┼────────────┤ │ dense (Dense) │ (None, 10) │ 1,290 │ └─────────────────────────────────┴───────────────────────────┴────────────┘ Total params: 260,298 (7.94 MB) Trainable params: 260,298 (7.94 MB) Non-trainable params: 0 (0.00 B)
compile() メソッドを使用して optimizer, 損失関数と監視のためのメトリクスを指定します。JAX と TensorFlow バックエンドでは、XLA コンパイルがデフォルトで有効にされていることに注意してください。
model.compile(
loss=keras.losses.SparseCategoricalCrossentropy(),
optimizer=keras.optimizers.Adam(learning_rate=1e-3),
metrics=[
keras.metrics.SparseCategoricalAccuracy(name="acc"),
],
)
モデルを訓練して評価しましょう。未見のデータで汎化を監視するために、訓練中、データの 15% の検証分割を取り置きます。
batch_size = 128
epochs = 20
callbacks = [
keras.callbacks.ModelCheckpoint(filepath="model_at_epoch_{epoch}.keras"),
keras.callbacks.EarlyStopping(monitor="val_loss", patience=2),
]
model.fit(
x_train,
y_train,
batch_size=batch_size,
epochs=epochs,
validation_split=0.15,
callbacks=callbacks,
)
score = model.evaluate(x_test, y_test, verbose=0)
Epoch 1/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 69s 172ms/step - acc: 0.5219 - loss: 1.3333 - val_acc: 0.9581 - val_loss: 0.1400 Epoch 2/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 69s 172ms/step - acc: 0.9260 - loss: 0.2497 - val_acc: 0.9743 - val_loss: 0.0881 Epoch 3/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 69s 171ms/step - acc: 0.9505 - loss: 0.1634 - val_acc: 0.9839 - val_loss: 0.0567 Epoch 4/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 68s 170ms/step - acc: 0.9611 - loss: 0.1314 - val_acc: 0.9798 - val_loss: 0.0673 Epoch 5/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 68s 171ms/step - acc: 0.9696 - loss: 0.1059 - val_acc: 0.9873 - val_loss: 0.0459 Epoch 6/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 69s 174ms/step - acc: 0.9729 - loss: 0.0920 - val_acc: 0.9891 - val_loss: 0.0400 Epoch 7/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 70s 176ms/step - acc: 0.9755 - loss: 0.0828 - val_acc: 0.9890 - val_loss: 0.0360 Epoch 8/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 68s 171ms/step - acc: 0.9775 - loss: 0.0761 - val_acc: 0.9904 - val_loss: 0.0359 Epoch 9/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 70s 174ms/step - acc: 0.9795 - loss: 0.0663 - val_acc: 0.9903 - val_loss: 0.0342 Epoch 10/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 68s 170ms/step - acc: 0.9813 - loss: 0.0621 - val_acc: 0.9904 - val_loss: 0.0360 Epoch 11/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 68s 170ms/step - acc: 0.9817 - loss: 0.0575 - val_acc: 0.9910 - val_loss: 0.0285 Epoch 12/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 67s 169ms/step - acc: 0.9845 - loss: 0.0525 - val_acc: 0.9908 - val_loss: 0.0346 Epoch 13/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 67s 168ms/step - acc: 0.9843 - loss: 0.0514 - val_acc: 0.9917 - val_loss: 0.0283 Epoch 14/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 67s 168ms/step - acc: 0.9859 - loss: 0.0481 - val_acc: 0.9924 - val_loss: 0.0242 Epoch 15/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 68s 169ms/step - acc: 0.9863 - loss: 0.0466 - val_acc: 0.9920 - val_loss: 0.0269 Epoch 16/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 68s 170ms/step - acc: 0.9867 - loss: 0.0445 - val_acc: 0.9936 - val_loss: 0.0228 Epoch 17/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 69s 174ms/step - acc: 0.9875 - loss: 0.0423 - val_acc: 0.9926 - val_loss: 0.0261 Epoch 18/20 399/399 ━━━━━━━━━━━━━━━━━━━━ 69s 174ms/step - acc: 0.9875 - loss: 0.0408 - val_acc: 0.9934 - val_loss: 0.0231
訓練中、各エポックの最後にモデルをセーブしています。このように最新の状態でモデルをセーブすることもできます :
model.save("final_model.keras")
そしてそれをこのように再ロードします :
model = keras.saving.load_model("final_model.keras")
次に、predict() でクラス確率の予測を問い合わせることができます :
predictions = model.predict(x_test)
313/313 ━━━━━━━━━━━━━━━━━━━━ 3s 10ms/step
That’s it for the basics!
クロスフレームワークのカスタムコンポーネントの作成
Keras Core は、同じコードベースで TensorFlow, JAX と PyTorch に渡り動作する、カスタム層, モデル, メトリクス, 損失と Optimizers を作成することを可能にします。最初にカスタム層をみましょう。
もし貴方が tf.keras でカスタム層を作成するのに既に馴染みがあるならば — well, 何も変わりません。一点を除いて: tf 名前空間の関数を使用する代わりに、keras.ops.* の関数を使用するべきです。
keras.ops 名前空間は以下を含みます :
- NumPy API の実装、e.g. keras.ops.stack や keras.ops.matmul.
- keras.ops.conv や keras.ops.binary_crossentropy のような、NumPy には欠落しているニューラルネットワーク固有の ops のセット。
すべてのバックエンドで動作するカスタム Dense 層を作成しましょう :
class MyDense(keras.layers.Layer):
def __init__(self, units, activation=None, name=None):
super().__init__(name=name)
self.units = units
self.activation = keras.activations.get(activation)
def build(self, input_shape):
input_dim = input_shape[-1]
self.w = self.add_weight(
shape=(input_dim, self.units),
initializer=keras.initializers.GlorotNormal(),
name="kernel",
trainable=True,
)
self.b = self.add_weight(
shape=(self.units,),
initializer=keras.initializers.Zeros(),
name="bias",
trainable=True,
)
def call(self, inputs):
# Use Keras ops to create backend-agnostic layers/metrics/etc.
x = keras.ops.matmul(inputs, self.w) + self.b
return self.activation(x)
次に、keras.random 名前空間に依存するカスタム Dropout 層を作成しましょう :
class MyDropout(keras.layers.Layer):
def __init__(self, rate, name=None):
super().__init__(name=name)
self.rate = rate
# Use seed_generator for managing RNG state.
# It is a state element and its seed variable is
# tracked as part of `layer.variables`.
self.seed_generator = keras.random.SeedGenerator(1337)
def call(self, inputs):
# Use `keras_core.random` for random ops.
return keras.random.dropout(inputs, self.rate, seed=self.seed_generator)
次に、2 つのカスタム層を使用する、カスタムのサブクラス化されたモデルを作成しましょう :
class MyModel(keras.Model):
def __init__(self, num_classes):
super().__init__()
self.conv_base = keras.Sequential(
[
keras.layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
keras.layers.Conv2D(64, kernel_size=(3, 3), activation="relu"),
keras.layers.MaxPooling2D(pool_size=(2, 2)),
keras.layers.Conv2D(128, kernel_size=(3, 3), activation="relu"),
keras.layers.Conv2D(128, kernel_size=(3, 3), activation="relu"),
keras.layers.GlobalAveragePooling2D(),
]
)
self.dp = MyDropout(0.5)
self.dense = MyDense(num_classes, activation="softmax")
def call(self, x):
x = self.conv_base(x)
x = self.dp(x)
return self.dense(x)
Let’s compile it and fit it:
model = MyModel(num_classes=10)
model.compile(
loss=keras.losses.SparseCategoricalCrossentropy(),
optimizer=keras.optimizers.Adam(learning_rate=1e-3),
metrics=[
keras.metrics.SparseCategoricalAccuracy(name="acc"),
],
)
model.fit(
x_train,
y_train,
batch_size=batch_size,
epochs=1, # For speed
validation_split=0.15,
)
399/399 ━━━━━━━━━━━━━━━━━━━━ 71s 176ms/step - acc: 0.5410 - loss: 1.2896 - val_acc: 0.9216 - val_loss: 0.2615 <keras_core.src.callbacks.history.History at 0x28a8047c0>
任意のデータソースでモデルを訓練する
すべての Keras モデルは、使用しているバックエンドとは独立に、広範囲なデータソースで訓練して評価することができます。これは以下を含みます :
- NumPy 配列
- Pandas dataframes
- TensorFlowtf.data.Dataset オブジェクト
- PyTorch DataLoader オブジェクト
- Keras PyDataset オブジェクト
Keras バックエンドとして TensorFlow, JAX あるいは PyTorch のいずれを利用していても、それらはすべて動作します。
PyTorch DataLoaders で試しましょう :
import torch
# Create a TensorDataset
train_torch_dataset = torch.utils.data.TensorDataset(
torch.from_numpy(x_train), torch.from_numpy(y_train)
)
val_torch_dataset = torch.utils.data.TensorDataset(
torch.from_numpy(x_test), torch.from_numpy(y_test)
)
# Create a DataLoader
train_dataloader = torch.utils.data.DataLoader(
train_torch_dataset, batch_size=batch_size, shuffle=True
)
val_dataloader = torch.utils.data.DataLoader(
val_torch_dataset, batch_size=batch_size, shuffle=False
)
model = MyModel(num_classes=10)
model.compile(
loss=keras.losses.SparseCategoricalCrossentropy(),
optimizer=keras.optimizers.Adam(learning_rate=1e-3),
metrics=[
keras.metrics.SparseCategoricalAccuracy(name="acc"),
],
)
model.fit(train_dataloader, epochs=1, validation_data=val_dataloader)
469/469 ━━━━━━━━━━━━━━━━━━━━ 82s 173ms/step - acc: 0.5713 - loss: 1.2036 - val_acc: 0.9319 - val_loss: 0.2262 <keras_core.src.callbacks.history.History at 0x2e41dac20>
Now let’s try this out with tf.data:
import tensorflow as tf
train_dataset = (
tf.data.Dataset.from_tensor_slices((x_train, y_train))
.batch(batch_size)
.prefetch(tf.data.AUTOTUNE)
)
test_dataset = (
tf.data.Dataset.from_tensor_slices((x_test, y_test))
.batch(batch_size)
.prefetch(tf.data.AUTOTUNE)
)
model = MyModel(num_classes=10)
model.compile(
loss=keras.losses.SparseCategoricalCrossentropy(),
optimizer=keras.optimizers.Adam(learning_rate=1e-3),
metrics=[
keras.metrics.SparseCategoricalAccuracy(name="acc"),
],
)
model.fit(train_dataset, epochs=1, validation_data=test_dataset)
469/469 ━━━━━━━━━━━━━━━━━━━━ 80s 170ms/step - acc: 0.5450 - loss: 1.2778 - val_acc: 0.8986 - val_loss: 0.3166 <keras_core.src.callbacks.history.History at 0x2e467fdc0>
以上