این صفحه به‌وسیله ‏Cloud Translation API‏ ترجمه شده است.
Switch to English

مدل ترتیبی

مشاهده در TensorFlow.org در Google Colab اجرا کنید مشاهده منبع در 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
[<tensorflow.python.keras.layers.core.Dense at 0x7f65406f4cf8>,
 <tensorflow.python.keras.layers.core.Dense at 0x7f65407f4128>,
 <tensorflow.python.keras.layers.core.Dense at 0x7f652e69a9b0>]

از طریق روش add() می توانید به صورت تدریجی یک مدل Sequential ایجاد کنید:

model = keras.Sequential()
model.add(layers.Dense(2, activation="relu"))
model.add(layers.Dense(3, activation="relu"))
model.add(layers.Dense(4))

توجه داشته باشید که یک روش pop() مربوطه نیز برای حذف لایه ها وجود دارد: یک مدل Sequential بسیار شبیه لیستی از لایه ها است.

model.pop()
print(len(model.layers))  # 2
2

همچنین توجه داشته باشید که سازنده Sequential مانند هر لایه یا مدل در Keras یک آرگومان name را می پذیرد. این برای حاشیه نویسی نمودارهای 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"))

تعیین شکل ورودی از قبل

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

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.624763  ,  0.4083134 , -0.5529761 ],
        [ 0.6743641 , -0.5915712 , -0.7844806 ],
        [ 0.5746553 , -0.5919968 , -0.56293225],
        [ 0.0971899 , -0.7555427 , -0.44926038]], 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
[<tensorflow.python.keras.layers.core.Dense at 0x7f65406b2dd8>]

یک گزینه ساده این است که فقط یک آرگومان 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()

هنگام ساخت یک معماری Sequential جدید ، جمع آوری تدریجی لایه ها با جمع بندی مدل add() و چاپ مکرر مفید است. به عنوان مثال ، این امکان را برای شما فراهم می کند تا چگونگی نمونه Conv2D از پشته ای از لایه های MaxPooling2D و 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
_________________________________________________________________

بسیار عملی ، درست است؟

با داشتن یک مدل چه باید کرد

پس از آماده شدن معماری مدل خود ، می خواهید:

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

هنگامی که یک مدل Sequential ساخته شد ، مانند یک مدل API عملکردی رفتار می کند. این بدان معنی است که هر لایه دارای یک ویژگی input و output است. از این ویژگی ها می توان برای انجام کارهای زیبا استفاده کرد ، مانند ایجاد سریع مدلی که خروجی تمام لایه های میانی را در یک مدل Sequential استخراج می کند:

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

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

در اینجا دو طرح متداول یادگیری انتقال شامل مدل های متوالی آورده شده است.

اول ، بیایید بگوییم که شما یک مدل Sequential دارید و می خواهید همه لایه ها را به جز یک لایه آخر منجمد کنید. در این حالت ، شما به سادگی بر روی model.layers تکرار می کنید و set layer.trainable = False در هر لایه 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(...)

اگر یادگیری را منتقل کنید ، احتمالاً مرتباً خود را با استفاده از این دو الگو خواهید یافت.

این در مورد تمام مواردی است که شما باید در مورد مدل های متوالی بدانید!

برای کسب اطلاعات بیشتر در مورد مدل های ساختمانی در کراس ، به این موارد مراجعه کنید: