<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: MeanNapat012</title>
    <description>The latest articles on DEV Community by MeanNapat012 (@meannapat).</description>
    <link>https://dev.to/meannapat</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1419523%2Fb5d65492-3db1-49d2-89de-9482dd30fe09.jpeg</url>
      <title>DEV Community: MeanNapat012</title>
      <link>https://dev.to/meannapat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/meannapat"/>
    <language>en</language>
    <item>
      <title>การเเบ่งส่วนภาพ โดยใช้ TensorFlow</title>
      <dc:creator>MeanNapat012</dc:creator>
      <pubDate>Sat, 13 Apr 2024 17:13:24 +0000</pubDate>
      <link>https://dev.to/meannapat/kaareebngswnphaaph-odyaich-tensorflow-21j3</link>
      <guid>https://dev.to/meannapat/kaareebngswnphaaph-odyaich-tensorflow-21j3</guid>
      <description>&lt;p&gt;การจำเเนกรูปภาพ คือการให้เครือได้กำหนดคลาสให้กับรูปภาพที่ Input เข้ามาในเเต่ละรูป ซึ่งการ Output จะเป็นการ mask วาดขอบเขตในรูปภาพทำให้สามารถนำไปใช้ได้อย่างกว้างขวาง มีการใช้อย่างหลากหลาย เช่น การวิเคราะห์ภาพของทางการเเพทย์ รถยนต์ขับเคลื่อนอัตโนมัติ การวิเคราะห์ภาพจากดาวเทียม เเละอีกมากมาย เป้าหมายหลักของการเเบ่งส่วนภาพ คือ เพื่อที่จะจดจำ เเละทำความเข้าใจสิ่งที่อยู่ในรูปภาพในระดับเล็กขนาด pixels&lt;/p&gt;

&lt;p&gt;ข้อมูลรูปภาพที่จะนำมาเเบ่งส่วนรูปภาพ ใช้ข้อมูล "The Oxford-IIIT Pet Dataset" เป็นข้อมูลที่เกี่ยวกับสัตว์ทั้งหมด 377 หมวดหมู่โดยจะมีรูปภาพ 200 รูปเอาไว้สำหรับเเต่ละคลาส รูปภาพเเต่ละภาพมีขนาด ท่าทางการเเสดง เเละเเสงที่เเตกต่างกัน รูปภาพทั้งหมดมีคำอธิบายเกี่ยวข้องกับสายพันธุ์ เเละการเเย่งส่วนการตัดเเต่งในรูปเเบบ pixels &lt;/p&gt;




&lt;h2&gt;
  
  
  ขั้นตอนการทำ
&lt;/h2&gt;

&lt;p&gt;1.นำเข้า library เข้าไปใน google colab&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os
import seaborn as sns
from tensorflow import keras
import tensorflow as tf
import tensorflow_datasets as tfds
import cv2
import PIL
from IPython.display import clear_output

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.Download ชุดข้อมูล Tensorflow โดยจะใช้คำสั่งดังนี้เพื่อ Download  เข้างาน&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dataset, info = tfds.load('oxford_iiit_pet:3.*.*', with_info=True)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.การประมวลผลของข้อมูล&lt;br&gt;
เริ่มจาก ตั้งค่า pixels อยู่ในช่วง [0,1] จากนั้นเราจะเเบ่งค่า pixels 255 ชุด&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def normalize(input_image, input_mask):

    # Normalize the pixel range values between [0:1]
    img = tf.cast(input_image, dtype=tf.float32) / 255.0
    input_mask -= 1
    return img, input_mask

@tf.function
def load_train_ds(dataset):
    img = tf.image.resize(dataset['image'], 
                          size=(width, height))
    mask = tf.image.resize(dataset['segmentation_mask'],
                           size=(width, height))

    if tf.random.uniform(()) &amp;gt; 0.5:
        img = tf.image.flip_left_right(img)
        mask = tf.image.flip_left_right(mask)

    img, mask = normalize(img, mask)
    return img, mask

@tf.function
def load_test_ds(dataset):
    img = tf.image.resize(dataset['image'], 
                          size=(width, height))
    mask = tf.image.resize(dataset['segmentation_mask'], 
                           size=(width, height))

    img, mask = normalize(img, mask)
    return img, mask
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ต่อมาเราจะมากำหนดตัวเเปรให้ป็นค่าคงที่ เช่น ขนาดของbuffer ความกว้าง ความสูงของข้อมูล Input&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TRAIN_LENGTH = info.splits['train'].num_examples

# Batch size is the number of examples used in one training example.
# It is mostly a power of 2
BATCH_SIZE = 64
BUFFER_SIZE = 1000
STEPS_PER_EPOCH = TRAIN_LENGTH // BATCH_SIZE

# For VGG16 this is the input size
width, height = 224, 224
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ในตอนนี้เราจะทำการ เทรนเเละทดสอบข้อมูลในตัวเเปรต่างๆ เเละได้ดำเนินการเพิ่มข้อมูลให้เสร็จสิ้น&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;train = dataset['train'].map(
    load_train_ds, num_parallel_calls=tf.data.AUTOTUNE)
test = dataset['test'].map(load_test_ds)

train_ds = train.cache().shuffle(BUFFER_SIZE).batch(BATCH_SIZE).repeat()
train_ds = train_ds.prefetch(buffer_size=tf.data.AUTOTUNE)
test_ds = test.batch(BATCH_SIZE)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4.เเสดงข้อมูล&lt;br&gt;
เห็นภาพตัวอย่างเเละ mask ที่เกี่ยวข้องจากชุดข้อมูล&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; def display_images(display_list):
    plt.figure(figsize=(15, 15))
    title = ['Input Image', 'True Mask', 
             'Predicted Mask']

    for i in range(len(display_list)):
        plt.subplot(1, len(display_list), i+1)
        plt.title(title[i])
        plt.imshow(keras.preprocessing.image.array_to_img(display_list[i]))
        plt.axis('off')

    plt.show()


for img, mask in train.take(5):
    sample_image, sample_mask = img, mask
    display_list = sample_image, sample_mask

display_images(display_list)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0lysgvtjbd883sqswu4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0lysgvtjbd883sqswu4.png" alt="Image description" width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;จากนั้นจะใช้ encoder จาก VGG16 ที่ได้รับการฝึกฝนด้สน ImageNet เพื่อช่วยลดเวลาในการฝึกโมเดล UNet เเละสามารถให้ผลลัพธ์ที่ดีโดยใช้เวลาที่น้อยลง&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;base_model = keras.applications.vgg16.VGG16(
    include_top=False, input_shape=(width, height, 3))

layer_names = [
    'block1_pool',
    'block2_pool',
    'block3_pool',
    'block4_pool',
    'block5_pool',
]
base_model_outputs = [base_model.get_layer(
    name).output for name in layer_names]
base_model.trainable = False

VGG_16 = tf.keras.models.Model(base_model.input,
                               base_model_outputs)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เเล้วทำการกำหนด decoder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def fcn8_decoder(convs, n_classes):
    f1, f2, f3, f4, p5 = convs

    n = 4096
    c6 = tf.keras.layers.Conv2D(
        n, (7, 7), activation='relu', padding='same', 
    name="conv6")(p5)
    c7 = tf.keras.layers.Conv2D(
        n, (1, 1), activation='relu', padding='same', 
    name="conv7")(c6)

    f5 = c7

    # upsample the output of the encoder
    # then crop extra pixels that were introduced
    o = tf.keras.layers.Conv2DTranspose(n_classes, kernel_size=(
        4, 4), strides=(2, 2), use_bias=False)(f5)
    o = tf.keras.layers.Cropping2D(cropping=(1, 1))(o)

    # load the pool 4 prediction and do a 1x1
    # convolution to reshape it to the same shape of `o` above
    o2 = f4
    o2 = (tf.keras.layers.Conv2D(n_classes, (1, 1),
                                activation='relu', 
                                padding='same'))(o2)

    # add the results of the upsampling and pool 4 prediction
    o = tf.keras.layers.Add()([o, o2])

    # upsample the resulting tensor of the operation you just did
    o = (tf.keras.layers.Conv2DTranspose(
        n_classes, kernel_size=(4, 4), strides=(2, 2), 
    use_bias=False))(o)
    o = tf.keras.layers.Cropping2D(cropping=(1, 1))(o)

    # load the pool 3 prediction and do a 1x1
    # convolution to reshape it to the same shape of `o` above
    o2 = f3
    o2 = (tf.keras.layers.Conv2D(n_classes, (1, 1),
                                activation='relu', 
                                padding='same'))(o2)

    # add the results of the upsampling and pool 3 prediction
    o = tf.keras.layers.Add()([o, o2])

    # upsample up to the size of the original image
    o = tf.keras.layers.Conv2DTranspose(
        n_classes, kernel_size=(8, 8), strides=(8, 8),
    use_bias=False)(o)

    # append a softmax to get the class probabilities
    o = tf.keras.layers.Activation('softmax')(o)
    return o
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;เอาทุกอย่างที่ได้กำหนดเข้ามาด้วยกันเเละสร้างโมเดลขึ้นมา&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def segmentation_model():

    inputs = keras.layers.Input(shape=(width, height, 3))
    convs = VGG_16(inputs)
    outputs = fcn8_decoder(convs, 3)
    model = tf.keras.Model(inputs=inputs, outputs=outputs)

    return model


opt = keras.optimizers.Adam()

model = segmentation_model()
model.compile(optimizer=opt,
            loss=tf.keras.losses.SparseCategoricalCrossentropy(
                from_logits=True),
            metrics=['accuracy'])

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5.ทำการสร้าง prediction mask utility&lt;br&gt;
จะทำการสร้าง function ที่จะเเสดงให้เห็นภาพจริงเเละ mask ที่ถูกต้องเเละ mask ที่ predicted ในเเถวเดียวกัน&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def create_mask(pred_mask):
    pred_mask = tf.argmax(pred_mask, axis=-1)
    pred_mask = pred_mask[..., tf.newaxis]
    return pred_mask[0]


def show_predictions(dataset=None, num=1):
    if dataset:
        for image, mask in dataset.take(num):
            pred_mask = model.predict(image)
            display_images([image[0], mask[0], create_mask(pred_mask)])
    else:
        display_images([sample_image, sample_mask,
                        create_mask(model.predict(sample_image[tf.newaxis, ...]))])


show_predictions()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5ewoyuism0486sss8mt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5ewoyuism0486sss8mt.png" alt="Image description" width="800" height="253"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6.การฝึกฝนโมเดล&lt;br&gt;
โดยเราจะตั้งค่าในการฝึกฝนโมเดลเอาไว้เป็นเวลา 20 รอบเเละทำการตรวจซ้ำ 5 รอบ&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EPOCHS = 20
VAL_SUBSPLITS = 5
VALIDATION_STEPS = info.splits['test'].num_examples//BATCH_SIZE//VAL_SUBSPLITS

model_history = model.fit(train_ds, epochs=EPOCHS,
                        steps_per_epoch=STEPS_PER_EPOCH,
                        validation_steps=VALIDATION_STEPS,
                        validation_data=test_ds)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4rakra6lm47qte6n0yp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4rakra6lm47qte6n0yp.png" alt="Image description" width="651" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;7.จะใช้ Metricsในการคำนวณค่าออกมา&lt;br&gt;
สำหรับงานเเบ่งส่วนภาพนั้นจะมีการใช้เมตริกทั้งหมด 2 ประเภทคือ 1.Intersection over Union(IOU) เเละ 2.Dice score&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def compute_metrics(y_true, y_pred):
    '''
    Computes IOU and Dice Score.

    Args:
    y_true (tensor) - ground truth label map
    y_pred (tensor) - predicted label map
    '''

    class_wise_iou = []
    class_wise_dice_score = []

    smoothening_factor = 0.00001

    for i in range(3):
        intersection = np.sum((y_pred == i) * (y_true == i))
        y_true_area = np.sum((y_true == i))
        y_pred_area = np.sum((y_pred == i))
        combined_area = y_true_area + y_pred_area

        iou = (intersection + smoothening_factor) / \
            (combined_area - intersection + smoothening_factor)
        class_wise_iou.append(iou)

        dice_score = 2 * ((intersection + smoothening_factor) /
                        (combined_area + smoothening_factor))
        class_wise_dice_score.append(dice_score)

    return class_wise_iou, class_wise_dice_score

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;8.จะใช้ Metrics ในการคำนวณค่าออกมา&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def get_test_image_and_annotation_arrays():
    '''
    Unpacks the test dataset and returns
    the input images and segmentation masks
    '''

    ds = test_ds.unbatch()
    ds = ds.batch(info.splits['test'].num_examples)

    images = []
    y_true_segments = []

    for image, annotation in ds.take(1):
        y_true_segments = annotation.numpy()
        images = image.numpy()

    y_true_segments = y_true_segments[:(
        info.splits['test'].num_examples - (info.splits['test']
                                            .num_examples % BATCH_SIZE))]
    images = images[:(info.splits['test'].num_examples -
                    (info.splits['test'].num_examples % BATCH_SIZE))]

    return images, y_true_segments


y_true_images, y_true_segments = get_test_image_and_annotation_arrays()

integer_slider = 2574
img = np.reshape(y_true_images[integer_slider], (1, width, height, 3))
y_pred_mask = model.predict(img)
y_pred_mask = create_mask(y_pred_mask)
y_pred_mask.shape


def display_prediction(display_list, display_string):
    plt.figure(figsize=(15, 15))
    title = ['Input Image', 'True Mask', 'Predicted Mask']

    for i in range(len(display_list)):
        plt.subplot(1, len(display_list), i+1)
        plt.title(title[i])
        plt.xticks([])
        plt.yticks([])
        if i == 1:
            plt.xlabel(display_string, fontsize=12)
        plt.imshow(keras.preprocessing.image.array_to_img(display_list[i]))
    plt.show()


iou, dice_score = compute_metrics(
    y_true_segments[integer_slider], y_pred_mask.numpy())
display_list = [y_true_images[integer_slider],
                y_true_segments[integer_slider], y_pred_mask]


class_names = ['pet', 'background', 'outline']
display_string_list = ["{}: IOU: {} Dice Score: {}".format(class_names[idx],
                                                        i, dc) for idx, (i, dc) in
                    enumerate(zip(np.round(iou, 4), np.round(dice_score, 4)))]
display_string = "\n\n".join(display_string_list)


# showing predictions with metrics
display_prediction(display_list, display_string)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flj7zh622rwu6ib4ekgdh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flj7zh622rwu6ib4ekgdh.png" alt="Image description" width="769" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  สรุปผล
&lt;/h2&gt;

&lt;p&gt;จากผลการทดลองที่ใช้ TensorFlow ในการทำการ Image Segmentation โดยใช้ชุดกลุ่มข้อมูลสัตว์เลี้ยงของ Oxford IIIT ทำให้มีการเเบ่งสัดส่วนภาพได้อย่างมาก สามารถนำโมเดลไปต่อยอดสู่งาน Project อื่นๆหรือเอาใช้สร้างโมเดลใหม่ที่ดีขึ้นในอนาคต&lt;/p&gt;




&lt;p&gt;เเหล่งอ้างอิง&lt;br&gt;
1.&lt;a href="https://www.geeksforgeeks.org/image-segmentation-using-tensorflow/"&gt;https://www.geeksforgeeks.org/image-segmentation-using-tensorflow/&lt;/a&gt;&lt;br&gt;
2.&lt;a href="https://www.tensorflow.org/tutorials/images/segmentation?hl=th"&gt;https://www.tensorflow.org/tutorials/images/segmentation?hl=th&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>python</category>
      <category>tensorflow</category>
    </item>
  </channel>
</rss>
