مدل ترتیبی

مشاهده در TensorFlow.org در Google Colab اجرا شود مشاهده منبع در GitHub دانلود دفترچه یادداشت

برپایی

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

زمان استفاده از مدل ترتیبی

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 متوالی است که مناسب نیست که:

  • مدل شما دارای چندین ورودی یا چند خروجی است
  • هر یک از لایه های شما دارای چندین ورودی یا چند خروجی است
  • شما باید به اشتراک گذاری لایه ها را انجام دهید
  • شما توپولوژی غیر خطی می خواهید (به عنوان مثال یک اتصال باقیمانده، یک مدل چند شاخه)

ایجاد یک مدل ترتیبی

شما می توانید یک مدل 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
_________________________________________________________________

با این حال، در هنگام ساخت یک مدل ترتیبی به صورت تدریجی، می تواند بسیار مفید باشد که بتوان خلاصه مدل را تا کنون، از جمله شکل خروجی فعلی را نمایش داد. در این مورد، شما باید مدل خود را با عبور یک شروع 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
_________________________________________________________________

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

به طور کلی، بهترین روش توصیه می‌شود که همیشه شکل ورودی یک مدل ترتیبی را از قبل مشخص کنید، اگر می‌دانید چیست.

گردش کار اشکال زدایی مشترک: 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
_________________________________________________________________

بسیار کاربردی، درست است؟

وقتی یک مدل دارید چه کاری باید انجام دهید

هنگامی که معماری مدل شما آماده شد، می خواهید:

استخراج ویژگی با مدل ترتیبی

هنگامی که یک مدل متوالی ساخته شده است، آن را مانند یک رفتار مدل 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(...)

یکی دیگر از طرح‌های متداول، استفاده از یک مدل ترتیبی برای قرار دادن یک مدل از پیش آموزش‌دیده و چند لایه طبقه‌بندی اولیه اولیه است. مثل این:

# 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، نگاه کنید به: