أساسيات Keras في التعلم العميق

Keras في التعلم العميق

الهيكل الرئيسي في Keras هو النموذج الذي يحدد الرسم البياني الكامل للشبكة. يمكنك إضافة المزيد من الطبقات إلى نموذج حالي لبناء نموذج مخصص تحتاجه لمشروعك. إليك كيفية إنشاء نموذج تسلسلي وبعض الطبقات شائعة الاستخدام لـ Keras في التعلم العميق.

النموذج المتسلسل:

from keras.models import Sequential
from keras.layers import Dense, Activation,Conv2D,MaxPooling2D,Flatten,Dropout

model = Sequential()

Keras في التعلم العميق

الطبقة التلافيفية (Convolutional Layer)

هذا مثال Keras Python للطبقة التلافيفية كطبقة إدخال مع شكل إدخال 320x320x3 بـ 48 مرشحًا بحجم 3 × 3 واستخدام ReLU كوظيفة تنشيط (activation funcction).

input_shape=(320,320,3) #this is the input shape of an image 320x320x3
model.add(Conv2D(48, (3, 3), activation='relu', input_shape= input_shape))

النوع الآخر هو:

model.add(Conv2D(48, (3, 3), activation='relu'))

طبقة MaxPooling

لاختزال تمثيل المدخلات استخدم MaxPool2d وحدد حجم kernel.

model.add(MaxPooling2D(pool_size=(2, 2)))

الطبقة Dense

إضافة طبقة متصلة بالكامل مع تحديد حجم الناتج فقط.

model.add(Dense(256, activation='relu'))

طبقة Dropout

إضافة طبقة Dropout باحتمال 50٪.

model.add(Dropout(0.5))

بعد أن نحدد نموذجنا فلنبدأ بتدريبهم. من المفترض تجميع الشبكة أولاً باستخدام دالة loss ودالة optimizer. سيسمح ذلك للشبكة بتغيير الأوزان وتقليل الخسائر.

model.compile(loss='mean_squared_error', optimizer='adam')

للبدء بالتدريب استخدم fit لتغذية بيانات التدريب والتحقق من صحة النموذج.

model.fit(X_train, X_train, batch_size=32, epochs=10, validation_data=(x_val, y_val))

خطوتنا الأخيرة هي تقييم النموذج باستخدام بيانات الاختبار.

score = model.evaluate(x_test, y_test, batch_size=32)

لنحاول استخدام الانحدار الخطي البسيط:

import keras
from keras.models import Sequential
from keras.layers import Dense, Activation
import numpy as np
import matplotlib.pyplot as plt 
 
x = data = np.linspace(1,2,200)
y = x*4 + np.random.randn(*x.shape) * 0.3


model = Sequential()
model.add(Dense(1, input_dim=1, activation='linear'))

model.compile(optimizer='sgd', loss='mse', metrics=['mse'])

weights = model.layers[0].get_weights()
w_init = weights[0][0][0]
b_init = weights[1][0]
print('Linear regression model is initialized with weights w: %.2f, b: %.2f' % (w_init, b_init)) 


model.fit(x,y, batch_size=1, epochs=30, shuffle=False)

weights = model.layers[0].get_weights()
w_final = weights[0][0][0]
b_final = weights[1][0]
print('Linear regression model is trained to have weight w: %.2f, b: %.2f' % (w_final, b_final))

predict = model.predict(data)

plt.plot(data, predict, 'b', data , y, 'k.')
plt.show()

بعد تدريب البيانات يجب أن تبدو المخرجات هكذا:

Keras في التعلم العميق

مع الوزن المبدئي (initial weight):

Linear regression model is initialized with weights w: 0.37, b: 0.00

والوزن النهائي:

Linear regression model is trained to have weight w: 3.70, b: 0.61

تحميل البیانات إلى AWS S3 Bucket

سنستخدم في عملية التدريب الخاصة بنا صورة لصور طبيعية من 8 فئات مختلفة مثل الطائرات والسيارة والقط والكلب والزهور والفواكه والدراجة النارية والإنسان. نحتاج أولاً تحميل بياناتنا إلى Amazon S3 Bucket.

الخطوة 1) بعد تسجيل الدخول إلى حساب S3 ، ننشئ bucket بالنقر علی Create Bucket.

الخطوة 2) اختر الآن اسم Bucket ومنطقتك وفق حسابك. تأكد من أن اسم Bucket متاح. بعد ذلك انقر علی Create.

Keras في التعلم العميق

الخطوة 3) كما ترى فإن Bucket جاهز للاستخدام. ولكن إن Access ليس عامًا، فإنه مفيد لك إذا أردت الاحتفاظ به خاصًا بك. يمكنك تغيير هذا Bucket للوصول العام في خصائص الـ Bucket.

الخطوة 5) انقر الآن على ملفك وانسخ الرابط حتى تتمكن من تنزيله.

Keras في التعلم العميق

تحضير البيانات (Data Preparation)

نحتاج لإنشاء بيانات التدريب الخاصة بنا باستخدام Keras ImageDataGenerator.

يجب عليك أولاً التنزيل باستخدام wget مع رابط الملف الخاص بك من S3 Bucket.

!wget https://s3.us-east-2.amazonaws.com/naturalimages02/images.tar.gz		
!tar -xzf images.tar.gz

فلنبدأ بعملية التدريب بعد تنزيل البيانات.

from keras.preprocessing.image import ImageDataGenerator
import numpy as np
import matplotlib.pyplot as plt

train_path = 'images/train/'
test_path = 'images/test/'
batch_size = 16
image_size = 224
num_class = 8


train_datagen = ImageDataGenerator(validation_split=0.3,
                                   shear_range=0.2,
                                   zoom_range=0.2,
                                   horizontal_flip=True)

train_generator = train_datagen.flow_from_directory(
                        directory=train_path,
                        target_size=(image_size,image_size),
                        batch_size=batch_size,
                        class_mode='categorical',
                        color_mode='rgb',
                        shuffle=True)

سيقوم ImageDataGenerator بعمل بيانات X_training من الدليل. سيتم استخدام الدليل الفرعي الموجود في هذا الدليل كفئة لكل كائن. وسيتم تحميل الصورة بصيغة ألوان RGB بوضع الفئة الفئوية لبيانات Y_training مع batch size من 16. أخيرًا قم بخلط البيانات عشوائيًا.

لنرى صورنا بشكل عشوائي من خلال رسمها باستخدام matplotlib.

x_batch, y_batch = train_generator.next()

fig=plt.figure()
columns = 4
rows = 4
for i in range(1, columns*rows):
    num = np.random.randint(batch_size)
    image = x_batch[num].astype(np.int)
    fig.add_subplot(rows, columns, i)
    plt.imshow(image)
plt.show()
Keras في التعلم العميق

بعد ذلك فلننشئ نموذج شبكتنا من VGG16 بوزن imageNet المدرب مسبقًا. سنقوم بتجميد هذه الطبقات بحيث تكون الطبقات غير قابلة للتدريب لمساعدتنا في تقليل وقت الحساب.

إنشاء النموذج من VGG16

import keras
from keras.models import Model, load_model
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.preprocessing.image import ImageDataGenerator
from keras.applications.vgg16 import VGG16


#Load the VGG model
base_model = VGG16(weights='imagenet', include_top=False, input_shape=(image_size, image_size, 3))

print(base_model.summary())

    # Freeze the layers 
for layer in base_model.layers:
    layer.trainable = False
 
# # Create the model
model = keras.models.Sequential()

# # Add the vgg convolutional base model
model.add(base_model)
 
# # Add new layers
model.add(Flatten())
model.add(Dense(1024, activation='relu'))
model.add(Dense(1024, activation='relu'))
model.add(Dense(num_class, activation='softmax'))
 
# # Show a summary of the model. Check the number of trainable parameters    
print(model.summary())

كما ترى أدناه ملخص نموذج شبكتنا. من إدخال من طبقات VGG16 نضيف طبقتان متصلتين بالكامل والتي ستستخرج 1024 ميزة وطبقة إخراج ستحسب الفئات الثمانية مع تنشيط softmax.

Layer (type)                 Output Shape              Param #   
=================================================================
vgg16 (Model)                (None, 7, 7, 512)         14714688  
_________________________________________________________________
flatten_1 (Flatten)          (None, 25088)             0         
_________________________________________________________________
dense_1 (Dense)              (None, 1024)              25691136  
_________________________________________________________________
dense_2 (Dense)              (None, 1024)              1049600   
_________________________________________________________________
dense_3 (Dense)              (None, 8)                 8200      
=================================================================
Total params: 41,463,624
Trainable params: 26,748,936
Non-trainable params: 14,714,688

تدريب (Training)

# # Compile the model
from keras.optimizers import SGD

model.compile(loss='categorical_crossentropy',
          optimizer=SGD(lr=1e-3),
          metrics=['accuracy'])

# # Start the training process
# model.fit(x_train, y_train, validation_split=0.30, batch_size=32, epochs=50, verbose=2)

# # #save the model
# model.save('catdog.h5')

history = model.fit_generator(
        train_generator,
        steps_per_epoch=train_generator.n/batch_size,
        epochs=10)
        
model.save('fine_tune.h5')

# summarize history for accuracy
import matplotlib.pyplot as plt

plt.plot(history.history['loss'])
plt.title('loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['loss'], loc='upper left')
plt.show()

الإخراج:

Epoch 1/10
432/431 [==============================] - 53s 123ms/step - loss: 0.5524 - acc: 0.9474 
Epoch 2/10
432/431 [==============================] - 52s 119ms/step - loss: 0.1571 - acc: 0.9831
Epoch 3/10
432/431 [==============================] - 51s 119ms/step - loss: 0.1087 - acc: 0.9871
Epoch 4/10
432/431 [==============================] - 51s 119ms/step - loss: 0.0624 - acc: 0.9926
Epoch 5/10
432/431 [==============================] - 51s 119ms/step - loss: 0.0591 - acc: 0.9938
Epoch 6/10
432/431 [==============================] - 51s 119ms/step - loss: 0.0498 - acc: 0.9936
Epoch 7/10
432/431 [==============================] - 51s 119ms/step - loss: 0.0403 - acc: 0.9958
Epoch 8/10
432/431 [==============================] - 51s 119ms/step - loss: 0.0248 - acc: 0.9959
Epoch 9/10
432/431 [==============================] - 51s 119ms/step - loss: 0.0466 - acc: 0.9942
Epoch 10/10
432/431 [==============================] - 52s 120ms/step - loss: 0.0338 - acc: 0.9947
Keras في التعلم العميق

كما تلاحظ فقد انخفضت خسائرنا بشكل كبير وكانت الدقة تقارب 100٪. لاختبار نموذجنا اخترنا الصور بشكل عشوائي عبر الإنترنت ووضعناها في مجلد الاختبار مع فئة مختلفة لاختبارها.

اختبار النموذج

model = load_model('fine_tune.h5')

test_datagen = ImageDataGenerator()
train_generator = train_datagen.flow_from_directory(
                        directory=train_path,
                        target_size=(image_size,image_size),
                        batch_size=batch_size,
                        class_mode='categorical',
                        color_mode='rgb',
                        shuffle=True)

test_generator = test_datagen.flow_from_directory(
                        directory=test_path, 
                        target_size=(image_size, image_size),
                        color_mode='rgb',
                        shuffle=False,
                        class_mode='categorical',
                        batch_size=1)

filenames = test_generator.filenames
nb_samples = len(filenames)

fig=plt.figure()
columns = 4
rows = 4
for i in range(1, columns*rows -1):
    x_batch, y_batch = test_generator.next()

    name = model.predict(x_batch)
    name = np.argmax(name, axis=-1)
    true_name = y_batch
    true_name = np.argmax(true_name, axis=-1)

    label_map = (test_generator.class_indices)
    label_map = dict((v,k) for k,v in label_map.items()) #flip k,v
    predictions = [label_map[k] for k in name]
    true_value = [label_map[k] for k in true_name]

    image = x_batch[0].astype(np.int)
    fig.add_subplot(rows, columns, i)
    plt.title(str(predictions[0]) + ':' + str(true_value[0]))
    plt.imshow(image)
plt.show()

واختبارنا على النحو المبين أدناه! تم توقع صورة واحدة خاطئة فقط من خلال اختبار 14 صورة!

Keras في التعلم العميق

الشبكة العصبية للتعرف على الوجوه (Face Recognition Neural Network) بـ Keras

إننا بحاجة إلى التعرف لتسهيل التعرف على وجه الشخص أو التعرف عليه أو نوع الأشياء أو العمر التقديري للشخص من وجهه أو حتى معرفة تعابير وجه هذا الشخص.

ربما تدرك أن في كل مرة تحاول فيها وضع علامة على وجه صديقك في صورة ما، فإن الميزة الموجودة في Facebook فعلت ذلك نيابةً عنك وهي تحديد وجه صديقك دون الحاجة إلى وضع علامة عليه أولاً. هذا هو التعرف على الوجوه الذي يطبقه Facebook لتسهيل تمييز الأصدقاء.

إذا كيف يعمل؟ في كل مرة نضع علامة على وجه صديقنا، سيعرفه الذكاء الاصطناعي في Facebook وسيحاول التنبؤ به حتى يحصل على النتيجة الصحيحة. نفس النظام الذي سنستخدمه في التعرف على الوجوه الخاصة بنا. دعونا نبدأ في صنع التعرف على الوجوه الخاصة بنا باستخدام التعلم العميق.

نموذج الشبكة (Network Model)

سنستخدم طراز شبكة VGG16 ولكن بوزن VGGFace.

هندسة نموذج VGG16:

ما هو VGGFace؟ إنه تطبيق Keras للتعرف العميق على الوجوه.

from keras.applications.vgg16 import VGG16
from keras_vggface.vggface import VGGFace

face_model = VGGFace(model='vgg16', 
                weights='vggface',
                input_shape=(224,224,3)) 
face_model.summary()

كما تلاحظ ملخص الشبكة:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 224, 224, 3)       0         
_________________________________________________________________
conv1_1 (Conv2D)             (None, 224, 224, 64)      1792      
_________________________________________________________________
conv1_2 (Conv2D)             (None, 224, 224, 64)      36928     
_________________________________________________________________
pool1 (MaxPooling2D)         (None, 112, 112, 64)      0         
_________________________________________________________________
conv2_1 (Conv2D)             (None, 112, 112, 128)     73856     
_________________________________________________________________
conv2_2 (Conv2D)             (None, 112, 112, 128)     147584    
_________________________________________________________________
pool2 (MaxPooling2D)         (None, 56, 56, 128)       0         
_________________________________________________________________
conv3_1 (Conv2D)             (None, 56, 56, 256)       295168    
_________________________________________________________________
conv3_2 (Conv2D)             (None, 56, 56, 256)       590080    
_________________________________________________________________
conv3_3 (Conv2D)             (None, 56, 56, 256)       590080    
_________________________________________________________________
pool3 (MaxPooling2D)         (None, 28, 28, 256)       0         
_________________________________________________________________
conv4_1 (Conv2D)             (None, 28, 28, 512)       1180160   
_________________________________________________________________
conv4_2 (Conv2D)             (None, 28, 28, 512)       2359808   
_________________________________________________________________
conv4_3 (Conv2D)             (None, 28, 28, 512)       2359808   
_________________________________________________________________
pool4 (MaxPooling2D)         (None, 14, 14, 512)       0         
_________________________________________________________________
conv5_1 (Conv2D)             (None, 14, 14, 512)       2359808   
_________________________________________________________________
conv5_2 (Conv2D)             (None, 14, 14, 512)       2359808   
_________________________________________________________________
conv5_3 (Conv2D)             (None, 14, 14, 512)       2359808   
_________________________________________________________________
pool5 (MaxPooling2D)         (None, 7, 7, 512)         0         
_________________________________________________________________
flatten (Flatten)            (None, 25088)             0         
_________________________________________________________________
fc6 (Dense)                  (None, 4096)              102764544 
_________________________________________________________________
fc6/relu (Activation)        (None, 4096)              0         
_________________________________________________________________
fc7 (Dense)                  (None, 4096)              16781312  
_________________________________________________________________
fc7/relu (Activation)        (None, 4096)              0         
_________________________________________________________________
fc8 (Dense)                  (None, 2622)              10742334  
_________________________________________________________________
fc8/softmax (Activation)     (None, 2622)              0         
=================================================================
Total params: 145,002,878
Trainable params: 145,002,878
Non-trainable params: 0
_________________________________________________________________
Traceback (most recent call last):

سنقوم بإجراء Transfer Learning + Fine Tuning لتسريع عملية التدريب باستخدام مجموعات البيانات الصغيرة. سنقوم أولاً بتجميد الطبقات الأساسية بحيث لا يمكن تدريب الطبقات.

for layer in face_model.layers:
    layer.trainable = False

ثم نضيف طبقتنا الخاصة للتعرف على وجوه الاختبار. سنضيف طبقتان متصلتين بالكامل وطبقة إخراج بـ 5 أشخاص للكشف.

from keras.models import Model, Sequential
from keras.layers import Input, Convolution2D, ZeroPadding2D, MaxPooling2D, Flatten, Dense, Dropout, Activation

person_count = 5

last_layer = face_model.get_layer('pool5').output

x = Flatten(name='flatten')(last_layer)
x = Dense(1024, activation='relu', name='fc6')(x)
x = Dense(1024, activation='relu', name='fc7')(x)
out = Dense(person_count, activation='softmax', name='fc8')(x)

custom_face = Model(face_model.input, out)

هنا نلاحظ ملخص شبكتنا:

Layer (type)                 Output Shape              Param #
=================================================================
input_1 (InputLayer)         (None, 224, 224, 3)       0
_________________________________________________________________
conv1_1 (Conv2D)             (None, 224, 224, 64)      1792
_________________________________________________________________
conv1_2 (Conv2D)             (None, 224, 224, 64)      36928
_________________________________________________________________
pool1 (MaxPooling2D)         (None, 112, 112, 64)      0
_________________________________________________________________
conv2_1 (Conv2D)             (None, 112, 112, 128)     73856
_________________________________________________________________
conv2_2 (Conv2D)             (None, 112, 112, 128)     147584
_________________________________________________________________
pool2 (MaxPooling2D)         (None, 56, 56, 128)       0
_________________________________________________________________
conv3_1 (Conv2D)             (None, 56, 56, 256)       295168
_________________________________________________________________
conv3_2 (Conv2D)             (None, 56, 56, 256)       590080
_________________________________________________________________
conv3_3 (Conv2D)             (None, 56, 56, 256)       590080
_________________________________________________________________
pool3 (MaxPooling2D)         (None, 28, 28, 256)       0
_________________________________________________________________
conv4_1 (Conv2D)             (None, 28, 28, 512)       1180160
_________________________________________________________________
conv4_2 (Conv2D)             (None, 28, 28, 512)       2359808
_________________________________________________________________
conv4_3 (Conv2D)             (None, 28, 28, 512)       2359808
_________________________________________________________________
pool4 (MaxPooling2D)         (None, 14, 14, 512)       0
_________________________________________________________________
conv5_1 (Conv2D)             (None, 14, 14, 512)       2359808
_________________________________________________________________
conv5_2 (Conv2D)             (None, 14, 14, 512)       2359808
_________________________________________________________________
conv5_3 (Conv2D)             (None, 14, 14, 512)       2359808
_________________________________________________________________
pool5 (MaxPooling2D)         (None, 7, 7, 512)         0
_________________________________________________________________
flatten (Flatten)            (None, 25088)             0
_________________________________________________________________
fc6 (Dense)                  (None, 1024)              25691136
_________________________________________________________________
fc7 (Dense)                  (None, 1024)              1049600
_________________________________________________________________
fc8 (Dense)                  (None, 5)                 5125
=================================================================
Total params: 41,460,549
Trainable params: 26,745,861
Non-trainable params: 14,714,688

كما ترى أعلاه، سيتم بعد طبقة pool5 تسويتها في متجه ميزة واحد سيتم استخدامه بواسطة الطبقة الكثيفة للتعرف النهائي.

تحضير الوجوه (Preparing Faces)

نجهز وجوهنا الآن. لقد قمنا بإنشاء دليل يتكون من 5 مشاهير:

  • جاك ما
  • جايسون ستاثام
  • جوني ديب
  • روبرت داوني جونيور
  • روان أتكينسون

يحتوي كل مجلد على 10 صور لكل عملية تدريب وتقييم. إنها كمية صغيرة جدًا من البيانات ولكن هذا هو التحدي. أليس كذلك؟

سنستخدم مساعدة أداة Keras في التعلم العميق لمساعدتنا في إعداد البيانات. ستتكرر هذه الدالة في مجلد مجموعة البيانات ثم تعدها إذ يمكن استخدامها في التدريب.

from keras.preprocessing.image import ImageDataGenerator
batch_size = 5
train_path = 'data/'
eval_path = 'eval/'

train_datagen = ImageDataGenerator(rescale=1./255,
                                   shear_range=0.2,
                                   zoom_range=0.2,
                                   horizontal_flip=True)

valid_datagen = ImageDataGenerator(rescale=1./255,
                                   shear_range=0.2,
                                   zoom_range=0.2,
                                   horizontal_flip=True)

train_generator = train_datagen.flow_from_directory(
                        train_path,
                        target_size=(image_size,image_size),
                        batch_size=batch_size,
                        class_mode='sparse',
                        color_mode='rgb')

valid_generator = valid_datagen.flow_from_directory(
    directory=eval_path,
    target_size=(224, 224),
    color_mode='rgb',
    batch_size=batch_size,
    class_mode='sparse',
    shuffle=True,
)

المصدر

منشور ذات صلة
تقنیة تحليل التمييز الخطي 5 Minutes

تقنیة التحليل التمييزي الخطي (Linear Discriminant Analysis) تنفیذها في البایثون

حسن خنفري

يتم استخدام تحليل التمييز الخطي (LDA) لنمذجة الاختلافات في المجموعات، بعبارة اخرى، لفصل فئتين أو أكثر. ويتم استخدامه لإبراز الخصائص في مساحة ذات أبعاد أعلى في مساحة ذات أبعاد أقل.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

السلة