הצג באתר TensorFlow.org | הפעל בגוגל קולאב | צפה במקור ב-GitHub | הורד מחברת |
להכין
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
מתי להשתמש במודל Sequential
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)))
רציפי מודל אינו מתאים כאשר:
- לדגם שלך יש מספר כניסות או יציאות מרובות
- לכל אחת מהשכבות שלך יש מספר כניסות או יציאות מרובות
- אתה צריך לעשות שיתוף שכבות
- אתה רוצה טופולוגיה לא ליניארית (למשל חיבור שיורי, מודל רב-ענפים)
יצירת מודל רצף
אתה יכול ליצור מודל Sequential על ידי העברת רשימה של שכבות לבנאי Sequential:
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)>]
מטבע הדברים, זה חל גם על דגמים Sequential. כשאתה מופע מודל סדרתית בלי צורה קלט, זה לא "בנה": אין לו משקולות (וקראו 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 _________________________________________________________________
עם זאת, זה יכול להיות מאוד שימושי בעת בניית מודל Sequential בהדרגה כדי להיות מסוגל להציג את סיכום המודל עד כה, כולל צורת הפלט הנוכחית. במקרה זה, אתה צריך להתחיל המודל שלך על ידי העברת 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 _________________________________________________________________
למודלים שנבנו עם צורת קלט מוגדרת מראש כמו זו תמיד יש משקלים (אפילו לפני שרואים נתונים כלשהם) ותמיד יש להם צורת פלט מוגדרת.
באופן כללי, מומלץ לציין תמיד את צורת הקלט של מודל Sequential מראש אם אתה יודע מה זה.
זרימת עבודת באגים נפוצה: add()
+ summary()
כאשר בניית ארכיטקטורה סדרתית חדשה, זה שימושי כדי לערום שכבות בהדרגה עם add()
ולהדפיס סיכומי מודל בתדירות גבוהה. למשל, זה מאפשר לך לעקוב כיצד ערימה של Conv2D
ו MaxPooling2D
שכבות היא downsampling מפות תכונת תמונה:
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 _________________________________________________________________
מאוד פרקטי, נכון?
מה לעשות ברגע שיש לך דוגמנית
ברגע שארכיטקטורת המודל שלך מוכנה, תרצה:
- אמן את המודל שלך, העריך אותו והפעל מסקנות. ראה שלנו מדריך לאימון & הערכה עם לולאות מובנהיות
- שמור את הדגם שלך בדיסק ושחזר אותו. ראה שלנו מדריך בהמשכים & חיסכון .
- האיץ את אימון המודלים על ידי מינוף מספר GPUs. ראה שלנו המדריך-GPU הרב והכשרה מופצת .
חילוץ תכונה עם דגם Sequential
לאחר מודל סדרתית נבנה, הוא מתנהג כמו מודל 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)
העבר למידה עם מודל רצף
למידת העברה מורכבת מהקפאת השכבות התחתונות במודל והכשרת השכבות העליונות בלבד. אם אתה לא מכיר אותו, לוודא לקרוא שלנו מדריך ללמידת העברה .
להלן שני שרטוטים נפוצים של למידה בהעברה הכוללים מודלים רציפים.
ראשית, נניח שיש לך מודל Sequential, ואתה רוצה להקפיא את כל השכבות מלבד האחרונה. במקרה זה, היית פשוט לחזר מעל 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(...)
שרטוט נפוץ נוסף הוא להשתמש במודל Sequential כדי לערום מודל מיומן מראש וכמה שכבות סיווג שבוצעו לאחרונה. ככה:
# 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, ראה: