サイトアイコン アマチュア無線局JS2IIU

Panel応用編 第9回: Panelと機械学習モデルの連携 (後半)

こんにちは、JS2IIUです。機械学習の結果を表示するためにPanelを使う事例紹介その2です。よろしくお願いします。

TensorFlowを使った機械学習モデルの統合

前回の前半に続いて今回はTensorFlowを使ってディープラーニングモデルを訓練し、Panelアプリに統合する方法を紹介します。ここでは、手書き数字の画像を分類するMNISTデータセットを使用して、画像分類モデルを作成し、それをPanelアプリケーションで使います。

TensorFlowでのモデル訓練

まず、TensorFlowを使ってMNISTデータセットを読み込み、シンプルなニューラルネットワークモデルを訓練します。最初にTensorFlowとKerasをインストールします。これは少し時間がかかります。

pip install tensorflow
pip install keras

こちらのプログラムの実行も少し時間がかかります。

import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten

# MNISTデータセットの読み込み
(X_train, y_train), (X_test, y_test) = mnist.load_data()

# データの正規化
X_train, X_test = X_train / 255.0, X_test / 255.0

# シンプルなニューラルネットワークモデルの構築
model = Sequential([
    Flatten(input_shape=(28, 28)),
    Dense(128, activation='relu'),
    Dense(10, activation='softmax')
])

# モデルのコンパイルと訓練
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(X_train, y_train, epochs=5)

TensorFlowモデルのPanel統合

次に、手書き数字の画像を入力として予測を行うPanelアプリを作成します。ユーザーがアップロードした画像を使い、モデルがその画像を分類します。

import numpy as np
import panel as pn
from PIL import Image

pn.extension()

# 画像の入力フィールド
image_input = pn.widgets.FileInput(name='Upload an Image')

# 予測結果の表示
result_pane = pn.pane.Markdown("## Prediction: ")

# 画像を処理して予測を行う関数
def predict_image(event):
    if image_input.value is not None:
        image = Image.open(image_input.file).convert('L').resize((28, 28))
        image_data = np.array(image) / 255.0
        image_data = image_data.reshape(1, 28, 28)
        prediction = np.argmax(model.predict(image_data), axis=1)[0]
        result_pane.object = f"## Prediction: {prediction}"

# ボタンクリックで予測実行
predict_button = pn.widgets.Button(name='Predict')
predict_button.on_click(predict_image)

# レイアウトの作成
layout = pn.Column(
    "## MNIST Image Classification",
    image_input,
    predict_button,
    result_pane
)

layout.servable()
pn.serve(layout)

このアプリケーションでは、ユーザーがアップロードした手書き数字の画像に対してリアルタイムで分類を行うことができます。

あれ、ちょっと変ですね・・・

https://js2iiu.com/wp-content/uploads/2024/09/pn_09_02.mov

PyTorchを使った機械学習モデルの統合

最後に、PyTorchを使って機械学習モデルをPanelアプリに統合する方法を紹介します。ここでは、PyTorchを使った線形回帰モデルの訓練と、そのモデルを使って予測を行うPanelアプリを作成します。

PyTorchでのモデル訓練

まず、PyTorchでシンプルな線形回帰モデルを作成し、訓練します。

import torch
import torch.nn as nn
import torch.optim as optim

# ダミーデータの作成
X_train = torch.tensor([[1.0], [2.0], [3.0], [4.0]])
y_train = torch.tensor([[2.0], [4.0], [6.0], [8.0]])

# シンプルな線形モデルの定義
class LinearRegressionModel(nn.Module):
    def __init__(self):
        super(LinearRegressionModel, self).__init__()
        self.linear = nn.Linear(1, 1)

    def forward(self, x):
        return self.linear(x)

model = LinearRegressionModel()

# 損失関数とオプティマイザの定義
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

# モデルの訓練
for epoch in range(100):
    optimizer.zero_grad()
    outputs = model(X_train)
    loss = criterion(outputs, y_train)
    loss.backward()
    optimizer.step()

PyTorchモデルのPanel統合

次に、訓練済みの線形回帰モデルを使って予測を行うPanelアプリを作成します。

import panel as pn

pn.extension()

# 入力ウィジェットの作成
x_input = pn.widgets.FloatSlider(name='Input Value', start=0.0, end=5.0, step=0.1, value=1.0)

# 予測結果を表示するためのパネル
prediction_result = pn.pane.Markdown("## Prediction: ")

# 予測を実行する関数
def update_prediction(event):
    input_value = torch.tensor([[x_input.value]])
    prediction = model(input_value).item()
    prediction_result.object = f"## Prediction: {prediction:.2f}"

# 予測ボタンの作成
predict_button = pn.widgets.Button(name='Predict')

# ボタンクリック時に予測を実行
predict_button.on_click(update_prediction)

# レイアウトの作成
layout = pn.Column(
    "## PyTorch Linear Regression",
    x_input,
    predict_button,
    prediction_result
)

layout.servable()
pn.serve(layout)

このアプリでは、PyTorchの線形回帰モデルを使って、リアルタイムで予測を行うことができます。

まとめ

後半では、TensorFlowとPyTorchを使った機械学習モデルをPanelアプリケーションに統合する方法を学びました。TensorFlowでは手書き数字の画像を分類し、PyTorchでは線形回帰モデルを使ってリアルタイムで予測を行うインターフェースを構築しました。これにより、Panelアプリケーションでの機械学習モデルの応用範囲が大幅に広がります。

次回は、Panelを活用したデータサイエンスパイプラインの構築について解説します。お楽しみに!

補足(1) TensorFlowのサンプルプログラム解説

# import os
# os.environ["KERAS_BACKEND"] = "jax"

import tensorflow as tf

from keras._tf_keras.keras.datasets import mnist
from keras._tf_keras.keras.models import Sequential
from keras._tf_keras.keras.layers import Dense, Flatten

# from tensorflow.keras.datasets import mnist
# from keras.models import Sequential
# from keras.layers import Dense, Flatten
from io import BytesIO


# MNISTデータセットの読み込み
(X_train, y_train), (X_test, y_test) = mnist.load_data()

# データの正規化
X_train, X_test = X_train / 255.0, X_test / 255.0

# シンプルなニューラルネットワークモデルの構築
model = Sequential([
    Flatten(input_shape=(28, 28)),
    Dense(128, activation='relu'),
    Dense(10, activation='softmax')
])

# モデルのコンパイルと訓練
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(X_train, y_train, epochs=5)


import numpy as np
import panel as pn
from PIL import Image

pn.extension()

# 画像の入力フィールド
image_input = pn.widgets.FileInput(name='Upload an Image')

# 予測結果の表示
result_pane = pn.pane.Markdown("## Prediction: ")

# 画像を処理して予測を行う関数
def predict_image(event):
    if image_input.value is not None:
        # 修正部分: バイナリデータをBytesIOで処理
        image = Image.open(BytesIO(image_input.value)).convert('L').resize((28, 28))
        image_data = np.array(image) / 255.0
        image_data = image_data.reshape(1, 28, 28)
        prediction = np.argmax(model.predict(image_data), axis=1)[0]
        result_pane.object = f"## Prediction: {prediction}"

# ボタンクリックで予測実行
predict_button = pn.widgets.Button(name='Predict')
predict_button.on_click(predict_image)

# レイアウトの作成
layout = pn.Column(
    "## MNIST Image Classification",
    image_input,
    predict_button,
    result_pane
)

layout.servable()
pn.serve(layout)

このプログラムは、Keras(TensorFlowバックエンドを使用)で構築されたシンプルなニューラルネットワークモデルを利用し、MNISTデータセットの手書き数字認識を行います。また、Panelを使ってWebアプリケーションを作成し、ユーザーがアップロードした画像に対して手書き数字の分類予測を行う仕組みになっています。以下に各部分の詳細を説明します。

1. Kerasバックエンドの設定

os.environ["KERAS_BACKEND"] = "jax"

2. 必要なライブラリのインポート

import tensorflow as tf
from keras._tf_keras.keras.datasets import mnist
from keras._tf_keras.keras.models import Sequential
from keras._tf_keras.keras.layers import Dense, Flatten

3. MNISTデータセットの読み込みと前処理

(X_train, y_train), (X_test, y_test) = mnist.load_data()

X_train, X_test = X_train / 255.0, X_test / 255.0

4. ニューラルネットワークの構築

model = Sequential([
    Flatten(input_shape=(28, 28)),
    Dense(128, activation='relu'),
    Dense(10, activation='softmax')
])

5. モデルのコンパイルと訓練

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(X_train, y_train, epochs=5)

6. PanelによるWebインターフェースの構築

import panel as pn
from PIL import Image
pn.extension()

7. 画像のアップロードと予測

image_input = pn.widgets.FileInput(name='Upload an Image')
result_pane = pn.pane.Markdown("## Prediction: ")

8. 予測関数

def predict_image(event):
    if image_input.value is not None:
        image = Image.open(BytesIO(image_input.value)).convert('L').resize((28, 28))
        image_data = np.array(image) / 255.0
        image_data = image_data.reshape(1, 28, 28)
        prediction = np.argmax(model.predict(image_data), axis=1)[0]
        result_pane.object = f"## Prediction: {prediction}"

9. 予測ボタンの設定

predict_button = pn.widgets.Button(name='Predict')
predict_button.on_click(predict_image)

10. レイアウトの構築とアプリの起動

layout = pn.Column(
    "## MNIST Image Classification",
    image_input,
    predict_button,
    result_pane
)

layout.servable()
pn.serve(layout)

全体の流れ

  1. モデルがMNISTデータセットで訓練されます。
  2. ユーザーが手書き数字の画像をアップロードします。
  3. 画像は前処理され、訓練済みモデルで予測が行われます。
  4. 結果がWebインターフェースに表示されます。
モバイルバージョンを終了