ช่วยปกป้อง Great Barrier Reef กับ TensorFlow บน Kaggle เข้าร่วมท้าทาย

แบบจำลองลำดับ

ดูบน TensorFlow.org ทำงานใน Google Colab ดูแหล่งที่มาบน GitHub ดาวน์โหลดโน๊ตบุ๊ค

ติดตั้ง

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

เมื่อใดควรใช้แบบจำลองลำดับ

Sequential รูปแบบที่เหมาะสมสำหรับกองธรรมดาของชั้นซึ่งแต่ละชั้นมีเมตริกซ์การป้อนข้อมูลตรงหนึ่งและหนึ่ง output เมตริกซ์

แผนผังดังต่อไปนี้ 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 โดยส่งรายการเลเยอร์ไปยัง Sequential constructor:

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
_________________________________________________________________

โมเดลที่สร้างด้วยรูปร่างอินพุตที่กำหนดไว้ล่วงหน้าเช่นนี้จะมีน้ำหนักเสมอ (แม้กระทั่งก่อนที่จะเห็นข้อมูลใดๆ ก็ตาม) และมีรูปร่างเอาต์พุตที่กำหนดไว้เสมอ

โดยทั่วไป แนวทางปฏิบัติที่ดีที่สุดที่แนะนำคือให้ระบุรูปร่างอินพุตของโมเดลตามลำดับล่วงหน้าเสมอ หากคุณรู้ว่ามันคืออะไร

ธรรมดาเวิร์กโฟลว์การแก้จุดบกพร่อง: 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
_________________________________________________________________

มีประโยชน์มากใช่มั้ย?

จะทำอย่างไรเมื่อมีนางแบบ

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

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

เมื่อรูปแบบต่อเนื่องได้รับการสร้างขึ้นมันจะทำงานเหมือน รุ่น 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(...)

หากคุณโอนย้ายการเรียนรู้ คุณอาจจะพบว่าตัวเองมักใช้รูปแบบทั้งสองนี้

นั่นคือทั้งหมดที่คุณต้องรู้เกี่ยวกับโมเดล Sequential!

หากต้องการข้อมูลเพิ่มเติมเกี่ยวกับแบบจำลองอาคารใน Keras โปรดดูที่: