عرض على TensorFlow.org | تشغيل في Google Colab | عرض المصدر على جيثب | تحميل دفتر |
يثبت
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
متى تستخدم النموذج المتسلسل
A Sequential
نموذج مناسب لكومة عادي من طبقات حيث كل طبقة لها بالضبط موتر مدخل واحد والموترة ناتج واحد.
تخطيطي، ما يلي Sequential
نموذج:
# Define Sequential model with 3 layers
model = keras.Sequential(
[
layers.Dense(2, activation="relu", name="layer1"),
layers.Dense(3, activation="relu", name="layer2"),
layers.Dense(4, name="layer3"),
]
)
# Call model on a test input
x = tf.ones((3, 3))
y = model(x)
يعادل هذه الوظيفة:
# Create 3 layers
layer1 = layers.Dense(2, activation="relu", name="layer1")
layer2 = layers.Dense(3, activation="relu", name="layer2")
layer3 = layers.Dense(4, name="layer3")
# Call layers on a test input
x = tf.ones((3, 3))
y = layer3(layer2(layer1(x)))
A متسلسل نموذج غير مناسب في الحالات التالية:
- يحتوي نموذجك على مدخلات متعددة أو مخرجات متعددة
- تحتوي أي طبقة من طبقاتك على مدخلات متعددة أو مخرجات متعددة
- ما عليك القيام به لمشاركة الطبقة
- تريد طبولوجيا غير خطية (على سبيل المثال ، اتصال متبقي ، نموذج متعدد الفروع)
إنشاء نموذج تسلسلي
يمكنك إنشاء نموذج تسلسلي عن طريق تمرير قائمة الطبقات إلى المُنشئ المتسلسل:
model = keras.Sequential(
[
layers.Dense(2, activation="relu"),
layers.Dense(3, activation="relu"),
layers.Dense(4),
]
)
طبقات يمكن الوصول إليها من خلال layers
السمة:
model.layers
[<keras.layers.core.Dense at 0x7fdc784478d0>, <keras.layers.core.Dense at 0x7fdbbc3c4650>, <keras.layers.core.Dense at 0x7fdbbc3c4a10>]
يمكنك أيضا إنشاء نموذج متسلسل تدريجيا من خلال add()
الأسلوب:
model = keras.Sequential()
model.add(layers.Dense(2, activation="relu"))
model.add(layers.Dense(3, activation="relu"))
model.add(layers.Dense(4))
علما بأن هناك أيضا المقابلة pop()
طريقة لإزالة طبقات: متتابعة سلوك النموذج تشبه إلى حد كبير قائمة الطبقات.
model.pop()
print(len(model.layers)) # 2
2
نلاحظ أيضا أن منشئ متسلسل يقبل name
الحجة، تماما مثل أي طبقة أو نموذج في Keras. يُعد هذا مفيدًا لإضافة تعليق توضيحي على الرسوم البيانية لـ TensorBoard بأسماء ذات معنى معنوي.
model = keras.Sequential(name="my_sequential")
model.add(layers.Dense(2, activation="relu", name="layer1"))
model.add(layers.Dense(3, activation="relu", name="layer2"))
model.add(layers.Dense(4, name="layer3"))
تحديد شكل الإدخال مقدمًا
بشكل عام ، تحتاج جميع الطبقات في Keras إلى معرفة شكل مدخلاتها حتى تتمكن من تكوين أوزانها. لذلك عندما تقوم بإنشاء طبقة مثل هذه ، في البداية ، ليس لها أي أوزان:
layer = layers.Dense(3)
layer.weights # Empty
[]
تقوم بإنشاء أوزانها في المرة الأولى التي يتم استدعاؤها على أحد المدخلات ، نظرًا لأن شكل الأوزان يعتمد على شكل المدخلات:
# Call layer on a test input
x = tf.ones((1, 4))
y = layer(x)
layer.weights # Now it has weights, of shape (4, 3) and (3,)
[<tf.Variable 'dense_6/kernel:0' shape=(4, 3) dtype=float32, numpy= array([[ 0.5319189 , -0.8767905 , -0.63919735], [-0.6276014 , 0.1689707 , -0.57695866], [ 0.6710613 , 0.5354214 , -0.00893992], [ 0.15670097, -0.15280598, 0.8865864 ]], dtype=float32)>, <tf.Variable 'dense_6/bias:0' shape=(3,) dtype=float32, numpy=array([0., 0., 0.], dtype=float32)>]
وبطبيعة الحال ، ينطبق هذا أيضًا على النماذج المتسلسلة. عند إنشاء مثيل نموذج متسلسل دون شكل المدخلات، وأنها ليست "بنيت": إنه لا يوجد لديه الأوزان (والدعوة model.weights
النتائج في خطأ تفيد فقط هذا). يتم إنشاء الأوزان عندما يرى النموذج لأول مرة بعض بيانات الإدخال:
model = keras.Sequential(
[
layers.Dense(2, activation="relu"),
layers.Dense(3, activation="relu"),
layers.Dense(4),
]
) # No weights at this stage!
# At this point, you can't do this:
# model.weights
# You also can't do this:
# model.summary()
# Call the model on a test input
x = tf.ones((1, 4))
y = model(x)
print("Number of weights after calling the model:", len(model.weights)) # 6
Number of weights after calling the model: 6
بمجرد "بنيت" نموذجا، يمكنك الاتصال في summary()
طريقة لعرض محتوياته:
model.summary()
Model: "sequential_3" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense_7 (Dense) (1, 2) 10 _________________________________________________________________ dense_8 (Dense) (1, 3) 9 _________________________________________________________________ dense_9 (Dense) (1, 4) 16 ================================================================= Total params: 35 Trainable params: 35 Non-trainable params: 0 _________________________________________________________________
ومع ذلك ، يمكن أن يكون مفيدًا جدًا عند إنشاء نموذج تسلسلي بشكل تدريجي حتى تتمكن من عرض ملخص النموذج حتى الآن ، بما في ذلك شكل الإخراج الحالي. في هذه الحالة، يجب أن تبدأ النموذج الخاص بك عن طريق تمرير Input
الكائن إلى النموذج الخاص بك، بحيث أنه يعرف شكل مدخلاته من البداية:
model = keras.Sequential()
model.add(keras.Input(shape=(4,)))
model.add(layers.Dense(2, activation="relu"))
model.summary()
Model: "sequential_4" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense_10 (Dense) (None, 2) 10 ================================================================= Total params: 10 Trainable params: 10 Non-trainable params: 0 _________________________________________________________________
علما بأن Input
لا يتم عرض الكائن كجزء من model.layers
، لأنه ليس من طبقة:
model.layers
[<keras.layers.core.Dense at 0x7fdbbc37c390>]
وثمة بديل بسيط هو مجرد تمرير input_shape
حجة لطبقة الأولى:
model = keras.Sequential()
model.add(layers.Dense(2, activation="relu", input_shape=(4,)))
model.summary()
Model: "sequential_5" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= dense_11 (Dense) (None, 2) 10 ================================================================= Total params: 10 Trainable params: 10 Non-trainable params: 0 _________________________________________________________________
النماذج التي تم إنشاؤها باستخدام شكل إدخال محدد مسبقًا مثل هذا لها دائمًا أوزان (حتى قبل رؤية أي بيانات) ولها دائمًا شكل إخراج محدد.
بشكل عام ، من أفضل الممارسات الموصى بها تحديد شكل الإدخال للنموذج المتسلسل مقدمًا إذا كنت تعرف ما هو.
A التصحيح العمل المشترك: add()
+ summary()
عند بناء هيكل متتابعة جديدة، فإنه من المفيد أن كومة تدريجيا طبقات مع add()
، وكثيرا ما طباعة ملخصات نموذج. على سبيل المثال، وهذا يتيح لك لمراقبة كيف كومة من Conv2D
و MaxPooling2D
طبقات والاختزال خرائط ميزة صورة:
model = keras.Sequential()
model.add(keras.Input(shape=(250, 250, 3))) # 250x250 RGB images
model.add(layers.Conv2D(32, 5, strides=2, activation="relu"))
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.MaxPooling2D(3))
# Can you guess what the current output shape is at this point? Probably not.
# Let's just print it:
model.summary()
# The answer was: (40, 40, 32), so we can keep downsampling...
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.MaxPooling2D(3))
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.Conv2D(32, 3, activation="relu"))
model.add(layers.MaxPooling2D(2))
# And now?
model.summary()
# Now that we have 4x4 feature maps, time to apply global max pooling.
model.add(layers.GlobalMaxPooling2D())
# Finally, we add a classification layer.
model.add(layers.Dense(10))
Model: "sequential_6" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 123, 123, 32) 2432 _________________________________________________________________ conv2d_1 (Conv2D) (None, 121, 121, 32) 9248 _________________________________________________________________ max_pooling2d (MaxPooling2D) (None, 40, 40, 32) 0 ================================================================= Total params: 11,680 Trainable params: 11,680 Non-trainable params: 0 _________________________________________________________________ Model: "sequential_6" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) (None, 123, 123, 32) 2432 _________________________________________________________________ conv2d_1 (Conv2D) (None, 121, 121, 32) 9248 _________________________________________________________________ max_pooling2d (MaxPooling2D) (None, 40, 40, 32) 0 _________________________________________________________________ conv2d_2 (Conv2D) (None, 38, 38, 32) 9248 _________________________________________________________________ conv2d_3 (Conv2D) (None, 36, 36, 32) 9248 _________________________________________________________________ max_pooling2d_1 (MaxPooling2 (None, 12, 12, 32) 0 _________________________________________________________________ conv2d_4 (Conv2D) (None, 10, 10, 32) 9248 _________________________________________________________________ conv2d_5 (Conv2D) (None, 8, 8, 32) 9248 _________________________________________________________________ max_pooling2d_2 (MaxPooling2 (None, 4, 4, 32) 0 ================================================================= Total params: 48,672 Trainable params: 48,672 Non-trainable params: 0 _________________________________________________________________
عملي جدا ، أليس كذلك؟
ماذا تفعل بمجرد أن يكون لديك نموذج
بمجرد أن تصبح بنية النموذج الخاصة بك جاهزة ، سوف ترغب في:
- تدريب نموذجك وتقييمه وتشغيل الاستدلال. ترى لدينا دليل للتدريب والتقييم مع المدمج في الحلقات
- احفظ النموذج الخاص بك على القرص واستعده. ترى لدينا دليل على التسلسل والادخار .
- قم بتسريع تدريب النموذج من خلال الاستفادة من وحدات معالجة الرسومات المتعددة. ترى لدينا دليل متعددة GPU والتدريب توزيعها .
استخراج الميزة بنموذج متسلسل
مرة واحدة وقد تم بناء نموذج متسلسل، فإنه يتصرف وكأنه نموذج API الوظيفي . وهذا يعني أن كل طبقة لها input
و output
السمة. يمكن استخدام هذه السمات للقيام بأشياء أنيقة ، مثل الإنشاء السريع لنموذج يستخرج مخرجات جميع الطبقات الوسيطة في نموذج تسلسلي:
initial_model = keras.Sequential(
[
keras.Input(shape=(250, 250, 3)),
layers.Conv2D(32, 5, strides=2, activation="relu"),
layers.Conv2D(32, 3, activation="relu"),
layers.Conv2D(32, 3, activation="relu"),
]
)
feature_extractor = keras.Model(
inputs=initial_model.inputs,
outputs=[layer.output for layer in initial_model.layers],
)
# Call feature extractor on test input.
x = tf.ones((1, 250, 250, 3))
features = feature_extractor(x)
إليك مثال مشابه يستخرج المعالم من طبقة واحدة فقط:
initial_model = keras.Sequential(
[
keras.Input(shape=(250, 250, 3)),
layers.Conv2D(32, 5, strides=2, activation="relu"),
layers.Conv2D(32, 3, activation="relu", name="my_intermediate_layer"),
layers.Conv2D(32, 3, activation="relu"),
]
)
feature_extractor = keras.Model(
inputs=initial_model.inputs,
outputs=initial_model.get_layer(name="my_intermediate_layer").output,
)
# Call feature extractor on test input.
x = tf.ones((1, 250, 250, 3))
features = feature_extractor(x)
نقل التعلم باستخدام نموذج تسلسلي
يتكون التعلم الانتقالي من تجميد الطبقات السفلية في النموذج وتدريب الطبقات العليا فقط. إذا لم تكن على دراية به، تأكد من أن جهودنا دليل على التعلم نقل .
فيما يلي مخططان شائعان لتعليم النقل يشتملان على نماذج متسلسلة.
أولاً ، لنفترض أن لديك نموذجًا تسلسليًا ، وتريد تجميد كل الطبقات باستثناء الأخيرة. في هذه الحالة، لو كنت ببساطة أعاد على model.layers
ومجموعة layer.trainable = False
في كل طبقة، باستثناء واحد آخر. مثله:
model = keras.Sequential([
keras.Input(shape=(784)),
layers.Dense(32, activation='relu'),
layers.Dense(32, activation='relu'),
layers.Dense(32, activation='relu'),
layers.Dense(10),
])
# Presumably you would want to first load pre-trained weights.
model.load_weights(...)
# Freeze all layers except the last one.
for layer in model.layers[:-1]:
layer.trainable = False
# Recompile and train (this will only update the weights of the last layer).
model.compile(...)
model.fit(...)
مخطط شائع آخر هو استخدام نموذج متسلسل لتكديس نموذج مدرب مسبقًا وبعض طبقات التصنيف التي تمت تهيئتها حديثًا. مثله:
# Load a convolutional base with pre-trained weights
base_model = keras.applications.Xception(
weights='imagenet',
include_top=False,
pooling='avg')
# Freeze the base model
base_model.trainable = False
# Use a Sequential model to add a trainable classifier on top
model = keras.Sequential([
base_model,
layers.Dense(1000),
])
# Compile & train
model.compile(...)
model.fit(...)
إذا قمت بنقل التعلم ، فمن المحتمل أن تجد نفسك تستخدم هذين النموذجين بشكل متكرر.
هذا كل ما تحتاج لمعرفته حول النماذج المتتابعة!
لمعرفة المزيد حول بناء النماذج في Keras ، راجع: