ดูบน 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 _________________________________________________________________
มีประโยชน์มากใช่มั้ย?
จะทำอย่างไรเมื่อมีนางแบบ
เมื่อสถาปัตยกรรมแบบจำลองของคุณพร้อม คุณจะต้อง:
- ฝึกโมเดลของคุณ ประเมิน และรันการอนุมาน ดูของเรา แนวทางในการฝึกอบรมและการประเมินผลที่มีในตัวลูป
- บันทึกโมเดลของคุณลงในดิสก์และกู้คืน ดูของเรา คู่มืออนุกรมและประหยัด
- เร่งความเร็วการฝึกโมเดลโดยใช้ประโยชน์จาก GPU หลายตัว ดูของเรา คู่มือ multi-GPU และการฝึกอบรมการกระจาย
การแยกคุณลักษณะด้วยแบบจำลองตามลำดับ
เมื่อรูปแบบต่อเนื่องได้รับการสร้างขึ้นมันจะทำงานเหมือน รุ่น 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 โปรดดูที่: