หน้านี้ได้รับการแปลโดย 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 ต่อไปนี้:

# 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)))

แบบจำลองตามลำดับ ไม่เหมาะสม เมื่อ:

  • โมเดลของคุณมีอินพุตหลายอินพุตหรือเอาต์พุตหลายตัว
  • เลเยอร์ใด ๆ ของคุณมีหลายอินพุตหรือหลายเอาต์พุต
  • คุณต้องทำการแชร์เลเยอร์
  • คุณต้องการโทโพโลยีที่ไม่ใช่เชิงเส้น (เช่นการเชื่อมต่อที่เหลือแบบจำลองหลายสาขา)

การสร้างแบบจำลองตามลำดับ

คุณสามารถสร้างแบบจำลองตามลำดับโดยส่งรายการของเลเยอร์ไปยังตัวสร้างลำดับ:

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() :

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.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)>]

โดยปกติแล้วสิ่งนี้ยังใช้กับแบบจำลองตามลำดับ เมื่อคุณสร้างอินสแตนซ์โมเดลแบบต่อเนื่องโดยไม่มีรูปร่างอินพุตจะไม่ "สร้าง": ไม่มีน้ำหนัก (และการเรียก 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()

เมื่อสร้างสถาปัตยกรรมตามลำดับใหม่จะมีประโยชน์ในการซ้อนเลเยอร์ด้วย 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
_________________________________________________________________

ปฏิบัติมากใช่ไหม?

จะทำอย่างไรเมื่อคุณมีแบบจำลอง

เมื่อสถาปัตยกรรมแบบจำลองของคุณพร้อมแล้วคุณจะต้อง:

การแยกคุณลักษณะด้วยแบบจำลองตามลำดับ

เมื่อสร้างแบบจำลองตามลำดับแล้วจะทำงานเหมือน โมเดล Functional 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 โปรดดู: