خانه دسته بندی نشده طبقه بندی تصاویر با کمک یادگیری عمیق ماشین (هوش مصنوعی) با استفاده از الگوریتم CNN – پایتون

طبقه بندی تصاویر با کمک یادگیری عمیق ماشین (هوش مصنوعی) با استفاده از الگوریتم CNN – پایتون

11 دقیقه برای خواندن کافیست
0
0
91

در این مقاله قصد داریم تا طبقه بندی ساده­ ی تصاویر را با کمک مدل یادگیری عمیق، به نام شبکه­ی عصبی پیچشی یا کانولوشن (CNN) بررسی کنیم. لذا در ابتدا به معرفی معماری CNN خواهیم پرداخت و پس از آن کد CNN را مورد بررسی قرار می­دهیم. همچنین می­توانید جهت اطلاع از یادگیری عمیق، مقاله­ی قبلی همین مجموعه را مطالعه نمایید.

طبقه بندی ساده¬ی تصاویر با کمک یادگیری عمیق
طبقه بندی سادهی تصاویر با کمک یادگیری عمیق
  • مقدمه

در این مقاله قصد داریم تا در مورد طبقه بندی تصاویر با کمک یادگیری عمیق صحبت کنیم. اگر مایل هستیم تا مقدمه­ی کوتاهی در مورد یادگیری عمیق داشته باشیم، لطفا مقاله­ی قبلی من در این مجموعه را مشاهده کنید. این مقاله قصد دارد تا در مورد طبقه بندی تصاویر با کمک مدل یادگیری عمیق به نام شبکه­ی عصبی پیچشی یا همگشتی (CNN) صحبت کند. قبل از اینکه به کد CNN بپردازیم، مایل هستم تا زمانی را صرف توضیح معماری CNN کنم. این پروژه به عنوان بخشی از دوره­ی یادگیری عمیق شرکت Udacity می­باشد. یک دوره­ی فوق العاده است و شما را تشویق می­کنم تا در این دوره شرکت کنید.

  • معماری

شبکه¬های عصبی معمولی (NN) توانایی پرداختن به تصاویر را ندارد. تنها تصور کنید که هر پیکسل به یک عصب وصل شده و هزاران عصب وجود خواهند داشت که از لحاظ محاسباتی پر هزینه (از لحاظ زمانی، قدرت پردازنده و…) خواهند شد. با اینکه CNN هنوز از مفهوم کلیِ NN تبعیت می کند، اما به روش های مختلفی با تصاویر کار می کند.

آنها از عصب­هایی (نورون­هایی) تشکیل شده­اند که مقادیر وزن و بایاس قابل یادگیری دارند. هر نورون ورودی­ها را می­پذیرد، عمل ضرب داخلی را انجام داده و از غیر خطی بودن تابع، پیروی می­کند. و هنوز آنها روی لایه­ی کاملا متصل، تابع زیان را دارند (مانند SVM/Softmax) و تمامی نکات و ترفندهایی که ما برای یادگیری NN معمولی ایجاد کردیم، هنوز هم بکار می­روند.

CNN به عنوان مدل پیش فرض برای هر موردی جهت پرداختن به تصاویر به کار می­رود.

امروزه مقالاتی وجود دارند که به استفاده از شبکه­ی عصبی بازگشتی (RNN) جهت تشخیص تصویر اشاره کرده اند. معمولا RNNها برای تشخیص متن و گفتار استفاده می­گردند.

استفاده از CNN نسبت به NN معمولی در یادگیری عمیق، کمک به کاهش تعداد پارامترهای مورد نیاز برای تصاویر می­نماید. همچنین، در به اشتراک گذاری پارامترها کمک می­کند تا بتواند ثبات تفسیر داشته باشد.

مثال وجود یک گربه را در یک عکس در نظر بگیرید. وقتی تلاش می­کنیم تا عکسی از یک گربه را طبقه بندی کنیم، اهمیتی نمی­دهیم که گربه در چه موقعیتی از عکس قرار دارد. اگر در قسمت بالا سمت چپ یا پایین سمت راست باشد، هنوز در نگاه­ ما یک گربه است. به این کار ثبات تفسیر می­گویند.

پیچش (کانولوشن)

اجازه بدهید تا به طور دقیق نحوه­ی عملکرد لایه­ی کانولوشن را در یادگیری عمیق بررسی کنیم. کانولوشن دارای مجموعه­ای از فیلترهای قابل یادگیری است که به شکل ماتریس خواهند شد (پهنا، ارتفاع و عمق). ما تصویر را به عنوان بک ماتریس در نظر می­گیریم و فیلتر از وسط ماتریس تصویر، همانند زیر، عبور داده خواهد شد تا یک تصویر در هم پیچیده ایجاد کند که تصویر فیلتر شده­ی تصویر واقعی است.

بسته به نوع کار، بیش از یک فیلتر در این مدل موجود هست تا ویژگی­های متفاوتی ایجاد شوند. ویژگی ممکن است جستجو کردن یک گربه، جستجو کردن رنگ و غیره باشد. مقدار فیلتر ماتریس از طریق مرحله­ی آموزشی این مدل یاد گرفته می­شود.

در مبحث یادگیری عمیق، فاکتور مهم دیگر در کانولوشن، لایه گذاری است. اگر فیلتر را روی ورودی تصویر اِعمال کنید، ما ماتریس خروجی را با اندازه­ی کوچکتری نسبت به تصویر اصلی دریافت خواهیم کرد. اگر نیاز داشته باشیم تا اندازه­ای مشابه ورودی را در خروجی دریافت کنیم، لایه گذاری وارد عمل می­گردد.

توده­ی ورودی (input volume) با اندازه­ی 3x32x32 می­باشد. اگر ما دو لایه­ای از صفر در اطراف این توده تصور کنیم، به ما توده­­ای با اندازه­ی 3x36x36 می­دهد. بنابراین، وقتی ما لایه­ی کانولوشن خود را با سه فیلتر با اندازه­ی 3x5x5 و یک استراید (گام) 1 پیکسلی، اِعمال می­کنیم، پس ما نیز توده­ی خروجی با اندازه­ی 3x32x32 را دریافت خواهیم کرد.

منبع: https://adeshpande3.github.io/A-Beginner%27s-Guide-To-Understanding-Convolutional-Neural-Networks-Part-2

اجازه بدهید مثال بالا را در نظر بگیریم. لایه گذاری با صفر با اندازه­ی 2 را به آن لایه اِعمال کنید. لایه گذاری با صفر، توده­ی ورودی را با اعداد صفر در دورتادور آن، می­پوشاند. اگر ما به فکر لایه گذاری با صفر با اندازه­ی 2 هستیم، این کار سبب ایجاد توده­ای با اندازه­ی 3x36x36 از یک توده­ی ورودی با اندازه­ی 3x32x32 می­شود.

تابع فعال سازی

توابع فعال سازی، توابعی هستند که تعیین می­کنند، با توجه به ورودی­ها در گره، خروجی گره چه چیزی باید باشد؟ به دلیل اینکه تابع فعال سازی است که خروجی واقعی را تعیین می­کند، اغلب به خروجی­های یک لایه به عنوان فعال سازی­های آن، اشاره می­کنیم. یکی از توابع فعال سازی محبوب در CNN، ReLu می­باشد.

منابع:

حداکثر ادغام

در مبحث یادگیری عمیق، مفهوم مهم دیگرِ CNN، ادغام می­باشد، که فرمی از کاهش نرخ نمونه گیری به صورت غیر خطی است. چندین تابع غیر خطی وجود دارند که می­توانند ادغام را انجام دهند، که در بین آنها، حداکثر ادغام، رایج­ترین آنها می­باشد.

منبع: http://cs231n.github.io/convolutional-networks

طبق ویکی پدیا، تصویر ورودی را به مجموعه­ای از مستطیل­های نامتقاطع تقسیم بندی می­کند و، برای هر کدام از چنین زیر ناحیه­هایی، خروجی­ها را به حداکثر می­رساند. حدس این است که مکان دقیق یک ویژگی نسبت به مکان تقریبی آن نسبت به دیگر ویژگی­ها، کم­تر اهمیت دارد.

منبع: ویکی پدیا

 

در یادگیری عمیق، لایه­ی ادغام کمک به کاهش اندازه­ی فضایی تصویر می­کند، تا تعداد پارامترها و مقدار محاسبات را در شبکه کاهش دهد. این کار، بیش برازش (over-fitting) را نیز کنترل می­کند.

کاملا متصل

نهایتا، بعد از چندین لایه­ی کانولوشن و حداکثر ادغام، استدلال سطح بالا در شبکه­ی نورونی از طریق لایه­های کاملا متصل انجام می­گیرد. نورون­ها در یک لایه­ی کاملا متصل ارتباطاتی با تمامی توابع فعال ساز در لایه­ی قبلی دارند، همانطور که در شبکه­های نورونی معمولی دیده شد. بنابراین فعال سازی آنها را نیز می­توان پس از متعادل سازی بایاس، با ضرب ماتریس محاسبه نمود (ویکی پدیا).

Softmax

در مبحث یادگیری عمیق، تابع Softmax (بیشینه­ی هموار)، توزیع احتمالات رخداد را در بیش از n رویداد مختلف محاسبه می­کند. به بیان کلی، این تابع احتمالات هر کلاس هدف را در تمامی کلاس­های هدف احتمالی محاسبه می­کند. پس از آن، احتمالات محاسبه شده برای تعیین کلاس هدف برای ورودهای معین، مفید واقع خواهد شد.

منبع: دوره­ی یادگیری عمیق در Udacity

از لحاظ ریاضی، تابع بیشینه­ی هموار در زیر نشان داده شده است، که در آن z برداری از ورودی­ها به سمت لایه­ی خروجی است (اگر شما 10 واحد خروجی داشته باشید، پس 10 مؤلفه در z وجود دارند). و باز هم، j واحدهای خروجی را نشان می­دهد.

  • طبقه بندی ساده­ی تصویر

بنده این موضوع را از طریق پایه کد این پروژه که به کمک دوره­ی یادگیری عمیقِ Udacity انجام داده­ام، توضیح خواهم داد.

کار ما طبقه بندی نمودن تصاویر بر اساس مجموعه داده­ی CIFAR-10 می­باشد. این مجموعه داده شامل هواپیماها، سگ­ها، گربه­ها و اشیای دیگر می­باشد. هدف ما ساخت مدل CNN، آموزش دادن آنان با کمک مجموعه داده و طبقه بندی تصاویر ورودی می­باشد.

دانلود مجموعه داده

قبل از هر کاری، مجموعه داده را از CIFAR یا در قالب اسکریپت یا دانلود مستقیم تهیه کنید.

این مجموعه داده به چندین دسته تقسیم می­شود تا مانع از تمام شدن حافظه­ی دستگاه شما گردد. مجموعه داده­ی CIFAR-10 شامل 5 دسته می­باشد به نام data_batch_1، data_batch_2 و غیره.

توابع پیش پردازشی

نرمال سازی

در یادگیری عمیق، داده­­ ها در دامنه­ ی از پیش تعیین شده (یعنی به طور معمول [0,1] یا [-1,1]) قرار داده می­شود. این کار هنگامی که داده ­هایی از فرمت­های (یا مجموعه داده­ی) مختلف  دارید و مایل هستید تا تمامی آنها را نرمال سازی کنید مفید واقع می­شود، لذا می­توانید همان الگوریتم­ها را برای آنان بکار ببندید.

def normalize(x):
    """
    Normalize a list of sample image data in the range of 0 to 1
    : x: List of image data.  The image shape is (32, 32, 3)
    : return: Numpy array of normalize data
    """
    # TODO: Implement Function
    #Normalization equation
    #zi=xi−min(x)/max(x)−min(x)
    normalized = (x-np.min(x))/(np.max(x)-np.min(x))
    return normalized

 

 

رمزگذاری one-hot

ورودی، x، لیستی از برچسب­ها می­باشند. این تابع را به منظور بازگشت لیستی از برچسب­ها تحت عنوان آرایه­ی Numpy کدگذاری شده به صورت one-hot پیاده کنید. مقادیر احتمالی برای برچسب­ها از 0 تا 9 هستند. تابع رمزگذاریِ one-hot باید همان رمزگذاری را برای هر مقدار بین هر دستور call تا رمزگذاری one-hot بازگرداند.

def one_hot_encode(x):
    """
    One hot encode a list of sample labels. Return a one-hot encoded vector for each label.
    : x: List of sample Labels
    : return: Numpy array of one-hot encoded labels
    """
    # TODO: Implement Function
    return np.eye(10)[x]

 

 

شما می­توانید به دو روش پیش پردازش را انجام دهید. یک روش هنگامی است که مدل در حال اجرا شدن (run شدن) باشد و روش دیگر، پیش پردازش تمامی داده­ها از قبل می­باشد. برای ذخیره کردن حافظه، روش خوبی برای پیش پردازش مجموعه داده، از قبل، می­باشد.

در این مثال، ما از قبل، این مجموعه داده را با کمک توابع فوق پیش پردازش می­کنیم.

ساخت شبکه

در این بخش، ما این مدل را بر اساس کتابخانه­ی تِنسور فلو (TensorFlow) می­سازیم.

ورودی

در اینجا ما متغیرهای ورودی را در تنسورفلو تعریف می­کنیم.

import tensorflow as tf
def neural_net_image_input(image_shape):
    """
    Return a Tensor for a bach of image input
    : image_shape: Shape of the images
    : return: Tensor for image input.
    """
    # TODO: Implement Function
    return tf.placeholder(tf.float32, shape=(None, *image_shape), name='x')

def neural_net_label_input(n_classes):
    """
    Return a Tensor for a batch of label input
    : n_classes: Number of classes
    : return: Tensor for label input.
    """
    # TODO: Implement Function
    return tf.placeholder(tf.float32, shape=(None, n_classes), name='y')

def neural_net_keep_prob_input():
    """
    Return a Tensor for keep probability
    : return: Tensor for keep probability.
    """
    # TODO: Implement Function
    return tf.placeholder(tf.float32, name='keep_prob')

 

 

لایه­ ی کانولوشن و حداکثر ادغام

این قسمت لایه­ی کانولوشن و حداکثر ادغام را تعریف می­کند. این قسمت شبه کد برای لایه­ها می­باشد:

  • وزن و بایاس را با کمک conv_ksize، conv_num_outputs و شکلِ x_tensor ایجاد کنید.
  • یک کانولوشن را با کمک وزن و conv_strides به x_tensor اِعمال کنید.
  • لایه گذاری
  • بایاس اضافه کنید
  • یک فعال سازی غیرخطی به کانولوشن اضافه کنید.
  • با کمک pool_ksize و pool_strides حداکثر ادغام را اِعمال کنید.

 

 

لایه­ی Flatten (مسطح سازی)

تابع flatten را برای تغییر ابعاد x_tensor از یک تنسور 4 بُعدی به یک تنسور 2 بُعدی، اِعمال کنید. خروجی باید شکل (shape) باشد (اندازه­ی دسته، اندازه­ی تصویر مسطح شده). این مورد، یکی از اجزای معماری CNN در یادگیری عمیق می­باشد که ما آن را در بخش بالایی توضیح ندادیم.

def conv2d_maxpool(x_tensor, conv_num_outputs, conv_ksize, conv_strides, pool_ksize, pool_strides):
    """
    Apply convolution then max pooling to x_tensor
    :param x_tensor: TensorFlow Tensor
    :param conv_num_outputs: Number of outputs for the convolutional layer
    :param conv_ksize: kernal size 2-D Tuple for the convolutional layer
    :param conv_strides: Stride 2-D Tuple for convolution
    :param pool_ksize: kernal size 2-D Tuple for pool
    :param pool_strides: Stride 2-D Tuple for pool
    : return: A tensor that represents convolution and max pooling of x_tensor
    """
    
    
    #Define weight
    weight_shape = [*conv_ksize, int(x_tensor.shape[3]), conv_num_outputs]
    w = tf.Variable(tf.random_normal(weight_shape, stddev=0.1))
    
    #Define bias
    b = tf.Variable(tf.zeros(conv_num_outputs))
    
    #Apply convolution
    x = tf.nn.conv2d(x_tensor, w, strides=[1, *conv_strides, 1], padding='SAME')
    
    #Apply bias
    x = tf.nn.bias_add(x, b)
    
    #Apply RELU
    x = tf.nn.relu(x)
    
    #Apply Max pool
    x = tf.nn.max_pool(x, [1, *pool_ksize, 1], [1, *pool_strides, 1], padding='SAME')
    return x

لایه ی Flatten (مسطح سازی)

تابع flatten را برای تغییر ابعاد x_tensor از یک تنسور 4 بُعدی به یک تنسور 2 بُعدی، اِعمال کنید. خروجی باید شکل (shape) باشد (اندازه¬ی دسته، اندازه¬ی تصویر مسطح شده). این مورد، یکی از اجزای معماری CNN در یادگیری عمیق می¬باشد که ما آن را در بخش بالایی توضیح ندادیم.

def flatten(x_tensor):
    """
    Flatten x_tensor to (Batch Size, Flattened Image Size)
    : x_tensor: A tensor of size (Batch Size, ...), where ... are the image dimensions.
    : return: A tensor of size (Batch Size, Flattened Image Size).
    """
    # TODO: Implement Function
    batch_size, *fltn_img_size = x_tensor.get_shape().as_list()
    img_size = fltn_img_size[0] * fltn_img_size[1] * fltn_img_size[2]
    tensor = tf.reshape(x_tensor, [-1, img_size])
    return tensor

لایه ی کاملا متصل

def fully_conn(x_tensor, num_outputs):
    """
    Apply a fully connected layer to x_tensor using weight and bias
    : x_tensor: A 2-D tensor where the first dimension is batch size.
    : num_outputs: The number of output that the new tensor should be.
    : return: A 2-D tensor where the second dimension is num_outputs.
    """
    # TODO: Implement Function
    #weights
    w_shape = (int(x_tensor.get_shape().as_list()[1]), num_outputs)
    weights = tf.Variable(tf.random_normal(w_shape, stddev=0.1))
    
    #bias
    bias = tf.Variable(tf.zeros(num_outputs))
    x = tf.add(tf.matmul(x_tensor, weights), bias)
    output = tf.nn.relu(x)
    return output

مدل کامل

این تابع تمامی بخش­های منفردی که در بالا به آنها اشاره شد را برای ساخت یک مدل کامل فرا می­خواند. این تابع حاویِ دسته­ای از تصاویر، x، و خروجی­های لاجیت می­باشد. از لایه­هایی که در قسمت بالایی ایجاد کردید برای ساخت این مدل استفاده کنید. ما از drop_out (منظم سازی) برای جلوگیری از بیش برازش استفاده می­کنیم.

def conv_net(x, keep_prob):
    """
    Create a convolutional neural network model
    : x: Placeholder tensor that holds image data.
    : keep_prob: Placeholder tensor that hold dropout keep probability.
    : return: Tensor that represents logits
    """
    # TODO: Apply 1, 2, or 3 Convolution and Max Pool layers
    x = conv2d_maxpool(x, 32, (3, 3), (1, 1), (2, 2), (2, 2))
    x = conv2d_maxpool(x, 32, (3, 3), (2, 2), (2, 2), (2, 2))
    x = conv2d_maxpool(x, 64, (3, 3), (1, 1), (2, 2), (2, 2))
    
    # TODO: Apply a Flatten Layer
    # Function Definition from Above:
    x = flatten(x)
    
    # TODO: Apply 1, 2, or 3 Fully Connected Layers
    #    Play around with different number of outputs
    # Function Definition from Above:
    #   fully_conn(x_tensor, num_outputs)
    x = fully_conn(x, 128)
    x = tf.nn.dropout(x, keep_prob)
    
    
    # TODO: Apply an Output Layer
    #    Set this to the number of classes
    # Function Definition from Above:
    #   output(x_tensor, num_outputs)
    result = output(x, 10)
    
    
    # TODO: return output
    return result

"""
DON'T MODIFY ANYTHING IN THIS CELL THAT IS BELOW THIS LINE
"""
##############################
## Build the Neural Network ##
##############################
# Remove previous weights, bias, inputs, etc..
tf.reset_default_graph()
# Inputs
x = neural_net_image_input((32, 32, 3))
y = neural_net_label_input(10)
keep_prob = neural_net_keep_prob_input()
# Model
logits = conv_net(x, keep_prob)
# Name logits Tensor, so that is can be loaded from disk after training
logits = tf.identity(logits, name='logits')
# Loss and Optimizer
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y))
optimizer = tf.train.AdamOptimizer().minimize(cost)
# Accuracy
correct_pred = tf.equal(tf.argmax(logits, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32), name='accuracy')

در کد بالا، ما از زیان (تابع زیان) و بهینه ساز استفاده می­کنیم که در قسمت بالایی، در مبحث یادگیری عمیق، توضیح داده نشد. هر دو این موارد برای CNN جهت انجام آموزش نیاز می­باشد. زیان، تابع زیانِ تکنیکِ حرکت رو به جلو (forward pass) را در هر بار اجرا (run) تعریف می­کند و بهینه ساز، عمل پس انتشار را به منظور هدف یادگیری بر اساس تابع زیان انجام می­دهد.

تمرین

تمرین را می­توان با کمک متغیر جلسه­ی تنسورفلو انجام داد.

def train_neural_network(session, optimizer, keep_probability, feature_batch, label_batch):
    """
    Optimize the session on a batch of images and labels
    : session: Current TensorFlow session
    : optimizer: TensorFlow optimizer function
    : keep_probability: keep probability
    : feature_batch: Batch of Numpy image data
    : label_batch: Batch of Numpy label data
    """
    # TODO: Implement Function
    session.run(optimizer, feed_dict={
        x: feature_batch,
        y: label_batch,
        keep_prob: keep_probability
    })

و خروجی در طی فاز ارزیابی به شرح زیر می­باشد:

این مورد، مثال ساده­ای از شناخت تصویر می­باشد. مدل یادگیری عمیق به نام، CNN بطور گسترده در انواع مختلف کاربردها، بخصوص در بینایی کامپیوتر (computer vision) استفاده می­گردد.

مجموعه­ی یادگیری عمیق

  • Deep learning series 1- Intro to deep learning
  • Deep learning series 3 — traffic sign detection self-driving car

 

اگر مایل هستید تا کد کامل را به صورت عملی مشاهده کنید، لطفا به گیت هابِ repo بنده مراجعه نمایید.

 

مشاهده محتوا بیشتر
ادامه مطلب شمشاد امیری خراسانی
بارگذاری بیشتر در دسته بندی نشده

دیدگاه بگذارید

avatar
  اشتراک  
به من اطلاع بده

همچنین ببینید

تست ارتباط ‍پایگاه داده mysql با لاراول

برای اینکه تست کنید ارتباط برنامه لاراول شما با پایگاه داده برقرار است در فایل : routes/we…