ดูบน TensorFlow.org | ทำงานใน Google Colab | ดูแหล่งที่มาบน GitHub | ดาวน์โหลดโน๊ตบุ๊ค |
เราขอแนะนำให้ใช้ tf.keras
เป็น API ระดับสูงสำหรับการสร้างเครือข่ายประสาทเทียม ที่กล่าวว่า TensorFlow API ส่วนใหญ่ใช้งานได้พร้อมการดำเนินการที่กระตือรือร้น
import tensorflow as tf
print(tf.config.list_physical_devices('GPU'))
[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
เลเยอร์: ชุดปฏิบัติการที่มีประโยชน์ทั่วไป
เวลาส่วนใหญ่ในการเขียนโค้ดสำหรับโมเดลการเรียนรู้ของเครื่อง คุณต้องการดำเนินการในระดับนามธรรมที่สูงกว่าการดำเนินการแต่ละรายการและการจัดการตัวแปรแต่ละตัว
โมเดลแมชชีนเลิร์นนิงจำนวนมากสามารถแสดงออกได้ในฐานะองค์ประกอบและการซ้อนเลเยอร์ที่ค่อนข้างง่าย และ TensorFlow มีทั้งชุดของเลเยอร์ทั่วไปจำนวนมาก ตลอดจนวิธีง่ายๆ ในการเขียนเลเยอร์เฉพาะแอปพลิเคชันของคุณเองตั้งแต่เริ่มต้นหรือเป็นองค์ประกอบของ ชั้นที่มีอยู่
TensorFlow มี Keras API แบบเต็มในแพ็คเกจ tf.keras และเลเยอร์ Keras นั้นมีประโยชน์มากเมื่อสร้างแบบจำลองของคุณเอง
# In the tf.keras.layers package, layers are objects. To construct a layer,
# simply construct the object. Most layers take as a first argument the number
# of output dimensions / channels.
layer = tf.keras.layers.Dense(100)
# The number of input dimensions is often unnecessary, as it can be inferred
# the first time the layer is used, but it can be provided if you want to
# specify it manually, which is useful in some complex models.
layer = tf.keras.layers.Dense(10, input_shape=(None, 5))
รายการทั้งหมดของเลเยอร์ที่มีอยู่ก่อนสามารถดูได้ใน เอกสารประกอบ ประกอบด้วย Dense (เลเยอร์ที่เชื่อมต่ออย่างสมบูรณ์), Conv2D, LSTM, BatchNormalization, Dropout และอื่นๆ อีกมากมาย
# To use a layer, simply call it.
layer(tf.zeros([10, 5]))
<tf.Tensor: shape=(10, 10), dtype=float32, numpy= array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)>
# Layers have many useful methods. For example, you can inspect all variables
# in a layer using `layer.variables` and trainable variables using
# `layer.trainable_variables`. In this case a fully-connected layer
# will have variables for weights and biases.
layer.variables
[<tf.Variable 'dense_1/kernel:0' shape=(5, 10) dtype=float32, numpy= array([[-0.4370762 , 0.6231566 , -0.44082257, -0.48535 , 0.17860883, -0.521853 , -0.45774594, -0.5409817 , 0.29194772, -0.18690601], [ 0.3304953 , -0.27142242, -0.48322448, -0.19328138, -0.14415592, 0.05973059, 0.56227285, 0.5323917 , -0.4914217 , 0.62182254], [-0.5313885 , 0.54680306, 0.1632638 , -0.10741419, -0.04727739, -0.35414204, 0.07529551, -0.06515282, -0.19732419, 0.25217015], [ 0.49743277, 0.31172627, 0.04989761, 0.1200847 , 0.42642146, 0.5887727 , 0.5771937 , 0.08720696, 0.43024355, -0.17298424], [-0.07610255, 0.04131562, 0.3136508 , -0.6197298 , 0.2331146 , 0.04888463, -0.54215366, 0.41208786, 0.27439958, 0.08524591]], dtype=float32)>, <tf.Variable 'dense_1/bias:0' shape=(10,) dtype=float32, numpy=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)>]
# The variables are also accessible through nice accessors
layer.kernel, layer.bias
(<tf.Variable 'dense_1/kernel:0' shape=(5, 10) dtype=float32, numpy= array([[-0.4370762 , 0.6231566 , -0.44082257, -0.48535 , 0.17860883, -0.521853 , -0.45774594, -0.5409817 , 0.29194772, -0.18690601], [ 0.3304953 , -0.27142242, -0.48322448, -0.19328138, -0.14415592, 0.05973059, 0.56227285, 0.5323917 , -0.4914217 , 0.62182254], [-0.5313885 , 0.54680306, 0.1632638 , -0.10741419, -0.04727739, -0.35414204, 0.07529551, -0.06515282, -0.19732419, 0.25217015], [ 0.49743277, 0.31172627, 0.04989761, 0.1200847 , 0.42642146, 0.5887727 , 0.5771937 , 0.08720696, 0.43024355, -0.17298424], [-0.07610255, 0.04131562, 0.3136508 , -0.6197298 , 0.2331146 , 0.04888463, -0.54215366, 0.41208786, 0.27439958, 0.08524591]], dtype=float32)>, <tf.Variable 'dense_1/bias:0' shape=(10,) dtype=float32, numpy=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)>)
การใช้เลเยอร์ที่กำหนดเอง
วิธีที่ดีที่สุดในการใช้เลเยอร์ของคุณเองคือการขยายคลาส tf.keras.Layer และนำไปใช้:
-
__init__
ซึ่งคุณสามารถเริ่มต้นการป้อนข้อมูลอิสระทั้งหมดได้ -
build
โดยที่คุณทราบรูปร่างของเทนเซอร์อินพุตและสามารถทำการเริ่มต้นที่เหลือได้ -
call
ที่คุณทำการคำนวณไปข้างหน้า
โปรดทราบว่าคุณไม่จำเป็นต้องรอจนกว่าจะมีการเรียก build
เพื่อสร้างตัวแปรของคุณ คุณยังสามารถสร้างพวกมันใน __init__
ได้ อย่างไรก็ตาม ข้อดีของการสร้างพวกมันใน build
ด์คือช่วยให้สามารถสร้างตัวแปรช่วงปลายตามรูปร่างของอินพุตที่เลเยอร์จะทำงาน ในอีกทางหนึ่ง การสร้างตัวแปรใน __init__
จะทำให้ต้องระบุรูปร่างที่จำเป็นในการสร้างตัวแปรอย่างชัดเจน
class MyDenseLayer(tf.keras.layers.Layer):
def __init__(self, num_outputs):
super(MyDenseLayer, self).__init__()
self.num_outputs = num_outputs
def build(self, input_shape):
self.kernel = self.add_weight("kernel",
shape=[int(input_shape[-1]),
self.num_outputs])
def call(self, inputs):
return tf.matmul(inputs, self.kernel)
layer = MyDenseLayer(10)
_ = layer(tf.zeros([10, 5])) # Calling the layer `.builds` it.
print([var.name for var in layer.trainable_variables])
['my_dense_layer/kernel:0']
โค้ดโดยรวมจะอ่านและบำรุงรักษาได้ง่ายขึ้นหากใช้เลเยอร์มาตรฐานทุกครั้งที่ทำได้ เนื่องจากผู้อ่านคนอื่นๆ จะคุ้นเคยกับการทำงานของเลเยอร์มาตรฐาน หากคุณต้องการใช้เลเยอร์ที่ไม่มีอยู่ใน tf.keras.layers
ให้พิจารณายื่นเรื่อง github หรือส่งคำขอดึงให้เรา!
รุ่น: การเขียนเลเยอร์
สิ่งต่าง ๆ ที่คล้ายกับเลเยอร์ที่น่าสนใจในโมเดลการเรียนรู้ของเครื่องนั้นถูกนำไปใช้โดยการเขียนเลเยอร์ที่มีอยู่ ตัวอย่างเช่น แต่ละบล็อกที่เหลือใน resnet เป็นองค์ประกอบของการบิดเบี้ยว การปรับให้เป็นมาตรฐานแบบกลุ่ม และทางลัด เลเยอร์สามารถซ้อนกันภายในเลเยอร์อื่นได้
โดยทั่วไปแล้ว คุณจะสืบทอดจาก keras.Model
เมื่อคุณต้องการเมธอด model เช่น Model.fit
, Model.evaluate
และ Model.save
(ดูรายละเอียดใน เลเยอร์และโมเดล Keras ที่กำหนดเอง )
ฟีเจอร์อื่นๆ ที่จัดทำโดย keras.Model
(แทนที่จะเป็น keras.layers.Layer
) คือนอกเหนือจากการติดตามตัวแปรแล้ว keras.Model
ยังติดตามเลเยอร์ภายในด้วย ทำให้ตรวจสอบได้ง่ายขึ้น
ตัวอย่างเช่นนี่คือบล็อก ResNet:
class ResnetIdentityBlock(tf.keras.Model):
def __init__(self, kernel_size, filters):
super(ResnetIdentityBlock, self).__init__(name='')
filters1, filters2, filters3 = filters
self.conv2a = tf.keras.layers.Conv2D(filters1, (1, 1))
self.bn2a = tf.keras.layers.BatchNormalization()
self.conv2b = tf.keras.layers.Conv2D(filters2, kernel_size, padding='same')
self.bn2b = tf.keras.layers.BatchNormalization()
self.conv2c = tf.keras.layers.Conv2D(filters3, (1, 1))
self.bn2c = tf.keras.layers.BatchNormalization()
def call(self, input_tensor, training=False):
x = self.conv2a(input_tensor)
x = self.bn2a(x, training=training)
x = tf.nn.relu(x)
x = self.conv2b(x)
x = self.bn2b(x, training=training)
x = tf.nn.relu(x)
x = self.conv2c(x)
x = self.bn2c(x, training=training)
x += input_tensor
return tf.nn.relu(x)
block = ResnetIdentityBlock(1, [1, 2, 3])
_ = block(tf.zeros([1, 2, 3, 3]))
block.layers
[<keras.layers.convolutional.Conv2D at 0x7fc7e439bf90>, <keras.layers.normalization.batch_normalization.BatchNormalization at 0x7fc7dc1e5dd0>, <keras.layers.convolutional.Conv2D at 0x7fc7dc1a1cd0>, <keras.layers.normalization.batch_normalization.BatchNormalization at 0x7fc7dc12c490>, <keras.layers.convolutional.Conv2D at 0x7fc7dc12c8d0>, <keras.layers.normalization.batch_normalization.BatchNormalization at 0x7fc7dc12cf50>]
len(block.variables)
18
block.summary()
Model: "" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) multiple 4 batch_normalization (BatchN multiple 4 ormalization) conv2d_1 (Conv2D) multiple 4 batch_normalization_1 (Batc multiple 8 hNormalization) conv2d_2 (Conv2D) multiple 9 batch_normalization_2 (Batc multiple 12 hNormalization) ================================================================= Total params: 41 Trainable params: 29 Non-trainable params: 12 _________________________________________________________________
อย่างไรก็ตาม ส่วนใหญ่แล้ว โมเดลที่ประกอบด้วยหลายเลเยอร์มักจะเรียกชั้นหนึ่งต่อจากอีกชั้นหนึ่ง ซึ่งสามารถทำได้ในโค้ดเพียงเล็กน้อยโดยใช้ tf.keras.Sequential
:
my_seq = tf.keras.Sequential([tf.keras.layers.Conv2D(1, (1, 1),
input_shape=(
None, None, 3)),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Conv2D(2, 1,
padding='same'),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Conv2D(3, (1, 1)),
tf.keras.layers.BatchNormalization()])
my_seq(tf.zeros([1, 2, 3, 3]))
<tf.Tensor: shape=(1, 2, 3, 3), dtype=float32, numpy= array([[[[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]], [[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]]]], dtype=float32)>
my_seq.summary()
Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d_3 (Conv2D) (None, None, None, 1) 4 batch_normalization_3 (Batc (None, None, None, 1) 4 hNormalization) conv2d_4 (Conv2D) (None, None, None, 2) 4 batch_normalization_4 (Batc (None, None, None, 2) 8 hNormalization) conv2d_5 (Conv2D) (None, None, None, 3) 9 batch_normalization_5 (Batc (None, None, None, 3) 12 hNormalization) ================================================================= Total params: 41 Trainable params: 29 Non-trainable params: 12 _________________________________________________________________
ขั้นตอนถัดไป
ตอนนี้คุณสามารถกลับไปที่สมุดบันทึกก่อนหน้าและปรับตัวอย่างการถดถอยเชิงเส้นเพื่อใช้เลเยอร์และแบบจำลองเพื่อให้มีโครงสร้างที่ดีขึ้น