深層学習モデルを使用した画像セグメンテーション

この記事では、画像セグメンテーションにディープ ラーニング モデルを使用する方法について説明します。具体的には、U-Net ネットワークを使用して人間の目の網膜画像をセグメント化し、その中の血管構造を抽出します。

1. データセットの紹介

このホワイト ペーパーでは、公開データセットである Messidor-2 データセットを使用します。このデータセットには、人間の目の 874 枚の網膜画像が含まれており、そのうち 615 枚がトレーニングに使用され、259 枚がテストに使用されます。各画像の解像度は 1440x960 で、血管、視神経乳頭、黄斑の 3 つの構造が含まれています。

Python の Pillow ライブラリを使用して、画像ファイルを読み取り、それを numpy 配列に変換できます。

from PIL import Image
import numpy as np

# 读取图像文件
image = Image.open('image.png')

# 将图像转换为 numpy 数组
image = np.array(image)

2. U-Net ネットワークの構築

U-Net ネットワークは、一般的に使用されるディープ ラーニング モデルであり、画像セグメンテーション、医用画像解析などの分野で広く使用されています。収縮パス (エンコーダー) と拡張パス (デコーダー) の 2 つの部分で構成されます。その中で、エンコーダー部分は畳み込みとプーリング操作を使用して画像サイズを徐々に縮小し、画像の特徴を抽出し、デコーダー部分はデコンボリューションとアップサンプリング操作を使用して画像サイズを徐々に復元し、セグメンテーション結果を生成します。

以下は、単純な U-Net ネットワークの実装です。

import tensorflow as tf
from tensorflow.keras import layers

# 定义 U-Net 网络
def build_model():
    inputs = tf.keras.Input(shape=(1440, 960, 3))

    # Encoder 部分
    conv1 = layers.Conv2D(64, 3, activation='relu', padding='same')(inputs)
    conv1 = layers.Conv2D(64, 3, activation='relu', padding='same')(conv1)
    pool1 = layers.MaxPooling2D(pool_size=(2, 2))(conv1)

    conv2 = layers.Conv2D(128, 3, activation='relu', padding='same')(pool1)
    conv2 = layers.Conv2D(128, 3, activation='relu', padding='same')(conv2)
    pool2 = layers.MaxPooling2D(pool_size=(2, 2))(conv2)

    conv3 = layers.Conv2D(256, 3, activation='relu', padding='same')(pool2)
    conv3 = layers.Conv2D(256, 3, activation='relu', padding='same')(conv3)
    pool3 = layers.MaxPooling2D(pool_size=(2, 2))(conv3)

    conv4 = layers.Conv2D(512, 3, activation='relu', padding='same')(pool3)
    conv4 = layers.Conv2D(512, 3, activation='relu', padding='same')(conv4)
    pool
= layers.MaxPooling2D(pool_size=(2, 2))(conv4)

conv5 = layers.Conv2D(1024, 3, activation='relu', padding='same')(pool4)
conv5 = layers.Conv2D(1024, 3, activation='relu', padding='same')(conv5)

# Decoder 部分
up6 = layers.UpSampling2D(size=(2, 2))(conv5)
conv6 = layers.Conv2D(512, 2, activation='relu', padding='same')(up6)
merge6 = layers.concatenate([conv4, conv6], axis=3)
conv6 = layers.Conv2D(512, 3, activation='relu', padding='same')(merge6)
conv6 = layers.Conv2D(512, 3, activation='relu', padding='same')(conv6)

up7 = layers.UpSampling2D(size=(2, 2))(conv6)
conv7 = layers.Conv2D(256, 2, activation='relu', padding='same')(up7)
merge7 = layers.concatenate([conv3, conv7], axis=3)
conv7 = layers.Conv2D(256, 3, activation='relu', padding='same')(merge7)
conv7 = layers.Conv2D(256, 3, activation='relu', padding='same')(conv7)

up8 = layers.UpSampling2D(size=(2, 2))(conv7)
conv8 = layers.Conv2D(128, 2, activation='relu', padding='same')(up8)
merge8 = layers.concatenate([conv2, conv8], axis=3)
conv8 = layers.Conv2D(128, 3, activation='relu', padding='same')(merge8)
conv8 = layers.Conv2D(128, 3, activation='relu', padding='same')(conv8)

up9 = layers.UpSampling2D(size=(2, 2))(conv8)
conv9 = layers.Conv2D(64, 2, activation='relu', padding='same')(up9)
merge9 = layers.concatenate([conv1, conv9], axis=3)
conv9 = layers.Conv2D(64, 3, activation='relu', padding='same')(merge9)
conv9 = layers.Conv2D(64, 3, activation='relu', padding='same')(conv9)

# 输出层
outputs = layers.Conv2D(1, 1, activation='sigmoid')(conv9)

# 创建模型
model = tf.keras.Model(inputs=inputs, outputs=outputs)

return model


上記のコードでは、最初に入力レイヤーを定義します。入力レイヤーの形状は (1440, 960, 3) です。次に、畳み込み演算とプーリング演算を使用してエンコーダー部分とデコーダー部分を構築し、最後に 1x1 畳み込みレイヤーを使用してバイナリ化されたセグメンテーション結果を生成しました。デコーダー部分では、デコンボリューションとアップサンプリング操作を使用して画像サイズを徐々に復元し、スキップ接続を使用してエンコーダー部分の特徴情報を融合し、モデルのパフォーマンスと一般化能力を向上させます。

 3. モデルのトレーニングと評価

モデルを定義した後、トレーニング セットを使用してモデルをトレーニングし、テスト セットを使用してモデルを評価できます。具体的には、クロスエントロピー損失関数と Adam オプティマイザーを使用してモデルをトレーニングできます。

# 定义损失函数和优化器
loss_fn = tf.keras.losses.BinaryCrossentropy()
optimizer = tf.keras.optimizers.Adam()

# 编译模型
model.compile(optimizer=optimizer, loss=loss_fn)

# 训练模型
model.fit(train_dataset, epochs=10, validation_data=val_dataset)

トレーニング プロセス中に、TensorBoard を使用してモデルのトレーニング プロセスを視覚化できます。

 
 
# 启动 TensorBoard
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)

# 训练模型,并使用 TensorBoard 可视化训练过程
model.fit(train_dataset, epochs=10, validation_data=val_dataset, callbacks=[tensorboard_callback])

トレーニングが完了したら、テスト セットを使用してモデルのパフォーマンスを評価できます。

 
 
# 在测试集上评估模型
test_loss, test_acc = model.evaluate(test_dataset)
print('Test loss:', test_loss)
print('Test accuracy:', test_acc)

同時に、混同行列などの指標を使用して、モデルの分類効果を評価することもできます。

 
 
# 获取模型预测结果
y_pred = model.predict(test_dataset)

# 将预测结果转换为二值化图像
y_pred = np.round(y_pred)

# 计算混淆矩阵
confusion_matrix = tf.math.confusion_matrix(test_labels, y_pred)

# 打印混淆矩阵
print('Confusion matrix:', confusion_matrix.numpy())

実際のアプリケーションでは、他の画像セグメンテーション モデルを使用して、FCN、SegNet、Mask R-CNN などのさまざまな画像セグメンテーション タスクを処理することもできます。同時に、画像強調技術を使用して、データセットの多様性を高め、モデルの一般化能力を向上させることもできます。

4. モデルの展開

トレーニングと評価が完了したら、自動化された画像セグメンテーション タスクを実現するために、トレーニング済みのモデルを運用環境にデプロイする必要があります。具体的には、さまざまなシナリオで使用するために、モデルをクラウド サーバーまたはモバイル デバイスに展開できます。

4.1 クラウド展開

クラウド展開では、AWS、Azure、Google Cloud などのクラウド コンピューティング プラットフォームを使用して、トレーニング済みのモデルを展開できます。具体的には、Flask フレームワークと TensorFlow Serving ライブラリを使用して RESTful API を構築し、クライアントが HTTP リクエストを介してモデル サービスを呼び出せるようにします。シンプルな Flask アプリケーションのコード例を次に示します。

from flask import Flask, request, jsonify
import tensorflow as tf

app = Flask(__name__)
model = tf.keras.models.load_model('model.h5')

@app.route('/predict', methods=['POST'])
def predict():
    # 获取请求参数
    data = request.get_json()

    # 将图像转换为 NumPy 数组
    image = tf.image.decode_jpeg(data['image'], channels=3)
    image = tf.image.resize(image, (1440, 960))
    image = image / 255.0
    image = tf.expand_dims(image, axis=0)

    # 预测图像分割结果
    result = model.predict(image)

    # 将预测结果转换为 JSON 格式
    result = result.tolist()
    result = {'result': result}

    # 返回预测结果
    return jsonify(result)

上記のコードでは、最初に Flask アプリケーションを定義し、トレーニング済みのモデルを読み込みます。次に、クライアントが画像をサーバーに送信して予測結果を取得できる RESTful API を定義しました。

4.2 モバイル展開

モバイル展開では、TensorFlow Lite ライブラリを使用して、トレーニング済みモデルを軽量モデルに変換し、Android または iOS デバイスに展開できます。以下は、単純な TensorFlow Lite アプリケーションのコード例です。

import tensorflow as tf
import numpy as np

# 加载 TensorFlow Lite 模型
interpreter = tf.lite.Interpreter(model_path='model.tflite')
interpreter.allocate_tensors()

# 定义输入和输出张量
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

# 加载图像数据
image = tf.image.decode_jpeg(image_bytes, channels=3)
image = tf.image.resize(image, (1440, 960))
image = image / 255.0
image = np.expand_dims(image.numpy(), axis=0)

# 设置输入张量
interpreter.set_tensor(input_details[0]['index'], image)

# 运行模型
interpreter.invoke()

# 获取输出张量
output_data = interpreter.get_tensor(output_details[0]['index'])

上記のコードでは、最初に TensorFlow Lite モデルをロードし、メモリを割り当てました。次に、入力と出力のテンソル情報を取得し、画像データを読み込みました。次に、

画像データをテンソルに変換し、入力テンソルとして設定します。最後に、モデルを実行し、出力テンソルを予測として取得します。

モバイル デバイスの計算能力が弱いため、モデルのサイズと計算を削減するために、モデルに対していくつかの最適化を実行する必要があることに注意してください。具体的には、量子化手法を使用して浮動小数点モデルを固定小数点モデルに変換し、モデルのサイズを縮小できます。さらに、プルーニング手法を使用して冗長な重みを削除し、モデルの計算量を削減することもできます。これらの最適化手法は、TensorFlow Lite ライブラリで実装できます。

5. まとめ

この記事では、Python と TensorFlow ライブラリを使用して画像セグメンテーション タスクを実装する基本的なプロセスを紹介します。最初に、画像セグメンテーションの基本的な概念とタスクの種類を紹介し、一般的に使用されるデータセットと画像セグメンテーション モデルをいくつか紹介します。次に、Python と TensorFlow ライブラリを使用して、データの前処理、モデルの構築、モデルのトレーニング、モデルのデプロイなどの画像セグメンテーション タスクを実装する方法を紹介しました。最後に、自動化された画像セグメンテーション タスクのためにモデルをクラウド サーバーまたはモバイル デバイスにデプロイする方法について説明します。

一般に、画像のセグメンテーションは、医療、自動運転、セキュリティなど、多くの分野で適用できる非常に重要なコンピューター ビジョン タスクです。この記事の導入により、Python と TensorFlow ライブラリを使用して画像セグメンテーション タスクを実現する方法を理解し、実用的なアプリケーションのアイデアとリファレンスを提供できます。

おすすめ

転載: blog.csdn.net/m0_68036862/article/details/130164670