ดูบน TensorFlow.org | ทำงานใน Google Colab | ดูแหล่งที่มาบน GitHub | ดาวน์โหลดโน๊ตบุ๊ค |
ในคู่มือก่อนหน้านี้ คุณได้เรียนรู้เกี่ยวกับ เท นเซอร์ ตัวแปร เทปเกรเดียนต์ และ โมดูล ในคู่มือนี้ คุณจะประกอบสิ่งเหล่านี้เข้าด้วยกันเพื่อฝึกโมเดล
TensorFlow ยังรวม tf.Keras API ซึ่งเป็น API เครือข่ายประสาทเทียมระดับสูงที่ให้นามธรรมที่เป็นประโยชน์เพื่อลดต้นแบบ อย่างไรก็ตาม ในคู่มือนี้ คุณจะใช้คลาสพื้นฐาน
ติดตั้ง
import tensorflow as tf
import matplotlib.pyplot as plt
colors = plt.rcParams['axes.prop_cycle'].by_key()['color']
การแก้ปัญหาแมชชีนเลิร์นนิง
การแก้ปัญหาแมชชีนเลิร์นนิงมักประกอบด้วยขั้นตอนต่อไปนี้:
- รับข้อมูลการฝึกอบรม
- กำหนดรูปแบบ
- กำหนดฟังก์ชันการสูญเสีย
- เรียกใช้ข้อมูลการฝึกคำนวณการสูญเสียจากค่าที่เหมาะสม
- คำนวณการไล่ระดับสีสำหรับการสูญเสียนั้นและใช้เครื่องมือ เพิ่มประสิทธิภาพ เพื่อปรับตัวแปรให้พอดีกับข้อมูล
- ประเมินผลลัพธ์ของคุณ
เพื่อจุดประสงค์ในการอธิบายประกอบ ในคู่มือนี้ คุณจะพัฒนาโมเดลเชิงเส้นอย่างง่าย \(f(x) = x * W + b\)ซึ่งมีตัวแปรสองตัว: \(W\) (น้ำหนัก) และ \(b\) (bias)
นี่เป็นปัญหาพื้นฐานที่สุดของแมชชีนเลิร์นนิง: จาก \(x\) และ \(y\)ให้ลองค้นหาความชันและออฟเซ็ตของเส้นโดย ใช้การถดถอยเชิงเส้นอย่างง่าย
ข้อมูล
การเรียนรู้ภายใต้การดูแลใช้ อินพุต (ปกติจะแสดงเป็น x ) และ เอาต์พุต (ระบุ y มักเรียกว่า labels ) เป้าหมายคือการเรียนรู้จากอินพุตและเอาต์พุตที่จับคู่กัน เพื่อให้คุณสามารถคาดการณ์มูลค่าของเอาต์พุตจากอินพุตได้
ข้อมูลที่ป้อนเข้าแต่ละครั้งใน TensorFlow มักใช้เทนเซอร์แทน และมักเป็นเวกเตอร์ ในการฝึกภายใต้การดูแล ผลลัพธ์ (หรือค่าที่คุณต้องการคาดการณ์) ก็เป็นเมตริกซ์เช่นกัน
นี่คือข้อมูลที่สังเคราะห์โดยการเพิ่มสัญญาณรบกวนแบบเกาส์เซียน (ปกติ) ให้กับจุดตามแนวเส้น
# The actual line
TRUE_W = 3.0
TRUE_B = 2.0
NUM_EXAMPLES = 201
# A vector of random x values
x = tf.linspace(-2,2, NUM_EXAMPLES)
x = tf.cast(x, tf.float32)
def f(x):
return x * TRUE_W + TRUE_B
# Generate some noise
noise = tf.random.normal(shape=[NUM_EXAMPLES])
# Calculate y
y = f(x) + noise
# Plot all the data
plt.plot(x, y, '.')
plt.show()
เทนเซอร์มักจะถูกรวบรวมเป็น แบตช์ หรือกลุ่มของอินพุตและเอาต์พุตที่ซ้อนกัน การผสมเป็นกลุ่มสามารถให้ประโยชน์ในการฝึกอบรมและทำงานได้ดีกับตัวเร่งความเร็วและการคำนวณแบบเวกเตอร์ เมื่อพิจารณาว่าชุดข้อมูลนี้มีขนาดเล็กเพียงใด คุณสามารถถือว่าชุดข้อมูลทั้งหมดเป็นชุดเดียวได้
กำหนดรูปแบบ
ใช้ tf.Variable
เพื่อแสดงน้ำหนักทั้งหมดในแบบจำลอง tf.Variable
เก็บค่าและจัดเตรียมไว้ในรูปแบบเทนเซอร์ตามต้องการ ดู คู่มือตัวแปร สำหรับรายละเอียดเพิ่มเติม
ใช้ tf.Module
เพื่อสรุปตัวแปรและการคำนวณ คุณสามารถใช้วัตถุ Python ใดก็ได้ แต่วิธีนี้สามารถบันทึกได้อย่างง่ายดาย
ที่นี่ คุณกำหนดทั้ง w และ b เป็นตัวแปร
class MyModel(tf.Module):
def __init__(self, **kwargs):
super().__init__(**kwargs)
# Initialize the weights to `5.0` and the bias to `0.0`
# In practice, these should be randomly initialized
self.w = tf.Variable(5.0)
self.b = tf.Variable(0.0)
def __call__(self, x):
return self.w * x + self.b
model = MyModel()
# List the variables tf.modules's built-in variable aggregation.
print("Variables:", model.variables)
# Verify the model works
assert model(3.0).numpy() == 15.0
Variables: (<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=0.0>, <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=5.0>) 2021-12-08 17:11:44.542944: W tensorflow/python/util/util.cc:368] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
ตัวแปรเริ่มต้นถูกตั้งค่าไว้ที่นี่ด้วยวิธีตายตัว แต่ Keras มาพร้อมกับตัวย่อจำนวนหนึ่งที่คุณสามารถใช้ได้ ไม่ว่าจะมีหรือไม่มี Keras ที่เหลือก็ตาม
กำหนดฟังก์ชันการสูญเสีย
ฟังก์ชันการสูญเสียจะวัดว่าเอาต์พุตของโมเดลสำหรับอินพุตที่กำหนดตรงกับเอาต์พุตเป้าหมายมากเพียงใด เป้าหมายคือเพื่อลดความแตกต่างนี้ให้เหลือน้อยที่สุดระหว่างการฝึก กำหนดการสูญเสีย L2 มาตรฐานหรือที่เรียกว่าข้อผิดพลาด "ค่าเฉลี่ยกำลังสอง":
# This computes a single loss value for an entire batch
def loss(target_y, predicted_y):
return tf.reduce_mean(tf.square(target_y - predicted_y))
ก่อนการฝึกโมเดล คุณสามารถเห็นภาพมูลค่าการสูญเสียโดยพล็อตการคาดการณ์ของโมเดลเป็นสีแดง และข้อมูลการฝึกเป็นสีน้ำเงิน:
plt.plot(x, y, '.', label="Data")
plt.plot(x, f(x), label="Ground truth")
plt.plot(x, model(x), label="Predictions")
plt.legend()
plt.show()
print("Current loss: %1.6f" % loss(y, model(x)).numpy())
Current loss: 10.301712
กำหนดวงจรการฝึก
วงการฝึกประกอบด้วยการทำงานสามอย่างซ้ำ ๆ กันตามลำดับ:
- การส่งชุดข้อมูลเข้าผ่านแบบจำลองเพื่อสร้างผลลัพธ์
- คำนวณการสูญเสียโดยเปรียบเทียบเอาท์พุตกับเอาท์พุต (หรือเลเบล)
- ใช้เทปไล่ระดับเพื่อค้นหาการไล่ระดับสี
- การเพิ่มประสิทธิภาพตัวแปรด้วยการไล่ระดับสีเหล่านั้น
สำหรับตัวอย่างนี้ คุณสามารถฝึกโมเดลโดยใช้ การไล่ระดับสี
มีรูปแบบการไล่ระดับสีแบบไล่ระดับหลายแบบที่บันทึกไว้ใน tf.keras.optimizers
แต่ด้วยจิตวิญญาณของการสร้างจากหลักการแรก คุณจะใช้คณิตศาสตร์พื้นฐานด้วยตนเองโดยใช้ tf.GradientTape
สำหรับการแยกความแตกต่างโดยอัตโนมัติ และ tf.assign_sub
สำหรับการลดค่า (ซึ่งรวม tf.assign
และ tf.sub
กัน):
# Given a callable model, inputs, outputs, and a learning rate...
def train(model, x, y, learning_rate):
with tf.GradientTape() as t:
# Trainable variables are automatically tracked by GradientTape
current_loss = loss(y, model(x))
# Use GradientTape to calculate the gradients with respect to W and b
dw, db = t.gradient(current_loss, [model.w, model.b])
# Subtract the gradient scaled by the learning rate
model.w.assign_sub(learning_rate * dw)
model.b.assign_sub(learning_rate * db)
สำหรับการดูการฝึก คุณสามารถส่ง x และ y ชุดเดียวกันผ่านลูปการฝึก และดูว่า W
และ b
พัฒนาขึ้นอย่างไร
model = MyModel()
# Collect the history of W-values and b-values to plot later
weights = []
biases = []
epochs = range(10)
# Define a training loop
def report(model, loss):
return f"W = {model.w.numpy():1.2f}, b = {model.b.numpy():1.2f}, loss={current_loss:2.5f}"
def training_loop(model, x, y):
for epoch in epochs:
# Update the model with the single giant batch
train(model, x, y, learning_rate=0.1)
# Track this before I update
weights.append(model.w.numpy())
biases.append(model.b.numpy())
current_loss = loss(y, model(x))
print(f"Epoch {epoch:2d}:")
print(" ", report(model, current_loss))
ทำแบบฝึกหัด
current_loss = loss(y, model(x))
print(f"Starting:")
print(" ", report(model, current_loss))
training_loop(model, x, y)
Starting: W = 5.00, b = 0.00, loss=10.30171 Epoch 0: W = 4.46, b = 0.40, loss=10.30171 Epoch 1: W = 4.06, b = 0.72, loss=10.30171 Epoch 2: W = 3.77, b = 0.97, loss=10.30171 Epoch 3: W = 3.56, b = 1.18, loss=10.30171 Epoch 4: W = 3.40, b = 1.34, loss=10.30171 Epoch 5: W = 3.29, b = 1.47, loss=10.30171 Epoch 6: W = 3.21, b = 1.58, loss=10.30171 Epoch 7: W = 3.15, b = 1.66, loss=10.30171 Epoch 8: W = 3.10, b = 1.73, loss=10.30171 Epoch 9: W = 3.07, b = 1.78, loss=10.30171
พล็อตวิวัฒนาการของตุ้มน้ำหนักเมื่อเวลาผ่านไป:
plt.plot(epochs, weights, label='Weights', color=colors[0])
plt.plot(epochs, [TRUE_W] * len(epochs), '--',
label = "True weight", color=colors[0])
plt.plot(epochs, biases, label='bias', color=colors[1])
plt.plot(epochs, [TRUE_B] * len(epochs), "--",
label="True bias", color=colors[1])
plt.legend()
plt.show()
เห็นภาพว่าแบบจำลองที่ได้รับการฝึกทำงานอย่างไร
plt.plot(x, y, '.', label="Data")
plt.plot(x, f(x), label="Ground truth")
plt.plot(x, model(x), label="Predictions")
plt.legend()
plt.show()
print("Current loss: %1.6f" % loss(model(x), y).numpy())
Current loss: 0.897898
วิธีแก้ปัญหาเดียวกัน แต่กับ Keras
การเปรียบเทียบโค้ดด้านบนกับโค้ดที่เทียบเท่ากันใน Keras นั้นมีประโยชน์
การกำหนดโมเดลจะเหมือนกันทุกประการหากคุณ subclass tf.keras.Model
โปรดจำไว้ว่าโมเดล Keras สืบทอดมาจากโมดูลในที่สุด
class MyModelKeras(tf.keras.Model):
def __init__(self, **kwargs):
super().__init__(**kwargs)
# Initialize the weights to `5.0` and the bias to `0.0`
# In practice, these should be randomly initialized
self.w = tf.Variable(5.0)
self.b = tf.Variable(0.0)
def call(self, x):
return self.w * x + self.b
keras_model = MyModelKeras()
# Reuse the training loop with a Keras model
training_loop(keras_model, x, y)
# You can also save a checkpoint using Keras's built-in support
keras_model.save_weights("my_checkpoint")
Epoch 0: W = 4.46, b = 0.40, loss=10.30171 Epoch 1: W = 4.06, b = 0.72, loss=10.30171 Epoch 2: W = 3.77, b = 0.97, loss=10.30171 Epoch 3: W = 3.56, b = 1.18, loss=10.30171 Epoch 4: W = 3.40, b = 1.34, loss=10.30171 Epoch 5: W = 3.29, b = 1.47, loss=10.30171 Epoch 6: W = 3.21, b = 1.58, loss=10.30171 Epoch 7: W = 3.15, b = 1.66, loss=10.30171 Epoch 8: W = 3.10, b = 1.73, loss=10.30171 Epoch 9: W = 3.07, b = 1.78, loss=10.30171ตัวยึดตำแหน่ง22
แทนที่จะเขียนลูปการฝึกใหม่ในแต่ละครั้งที่คุณสร้างแบบจำลอง คุณสามารถใช้คุณสมบัติในตัวของ Keras เป็นทางลัดได้ สิ่งนี้มีประโยชน์เมื่อคุณไม่ต้องการเขียนหรือดีบักลูปการฝึกของ Python
หากเป็นเช่นนั้น คุณจะต้องใช้ model.compile()
เพื่อตั้งค่าพารามิเตอร์ และ model.fit()
ในการฝึก การใช้ Keras ของการสูญเสีย L2 และการไล่ระดับการไล่ระดับสีอาจเป็นรหัสน้อยกว่าอีกครั้งเป็นทางลัด สามารถใช้การสูญเสีย Keras และตัวเพิ่มประสิทธิภาพนอกเหนือจากฟังก์ชันอำนวยความสะดวกเหล่านี้ได้เช่นกัน และตัวอย่างก่อนหน้านี้อาจใช้งานได้
keras_model = MyModelKeras()
# compile sets the training parameters
keras_model.compile(
# By default, fit() uses tf.function(). You can
# turn that off for debugging, but it is on now.
run_eagerly=False,
# Using a built-in optimizer, configuring as an object
optimizer=tf.keras.optimizers.SGD(learning_rate=0.1),
# Keras comes with built-in MSE error
# However, you could use the loss function
# defined above
loss=tf.keras.losses.mean_squared_error,
)
Keras fit
คาดหวังข้อมูลแบบแบตช์หรือชุดข้อมูลที่สมบูรณ์เป็นอาร์เรย์ NumPy อาร์เรย์ NumPy ถูกสับเป็นแบทช์และเริ่มต้นเป็นขนาดแบทช์ 32
ในกรณีนี้ เพื่อให้ตรงกับลักษณะการทำงานของลูปที่เขียนด้วยลายมือ คุณควรส่ง x
เป็นชุดขนาด 1000 ชุดเดียว
print(x.shape[0])
keras_model.fit(x, y, epochs=10, batch_size=1000)
201 Epoch 1/10 1/1 [==============================] - 0s 242ms/step - loss: 10.3017 Epoch 2/10 1/1 [==============================] - 0s 3ms/step - loss: 6.3148 Epoch 3/10 1/1 [==============================] - 0s 3ms/step - loss: 4.0341 Epoch 4/10 1/1 [==============================] - 0s 3ms/step - loss: 2.7191 Epoch 5/10 1/1 [==============================] - 0s 3ms/step - loss: 1.9548 Epoch 6/10 1/1 [==============================] - 0s 2ms/step - loss: 1.5068 Epoch 7/10 1/1 [==============================] - 0s 3ms/step - loss: 1.2422 Epoch 8/10 1/1 [==============================] - 0s 2ms/step - loss: 1.0845 Epoch 9/10 1/1 [==============================] - 0s 2ms/step - loss: 0.9899 Epoch 10/10 1/1 [==============================] - 0s 3ms/step - loss: 0.9327 <keras.callbacks.History at 0x7f02ad940050>
โปรดทราบว่า Keras พิมพ์การสูญเสียหลังการฝึก ไม่ใช่ก่อนหน้า ดังนั้นการสูญเสียครั้งแรกจึงลดลง แต่อย่างอื่นก็แสดงให้เห็นโดยพื้นฐานแล้วประสิทธิภาพการฝึกอบรมเดียวกัน
ขั้นตอนถัดไป
ในคู่มือนี้ คุณได้เห็นวิธีใช้คลาสหลักของเมตริกซ์ ตัวแปร โมดูล และเทปเกรเดียนต์เพื่อสร้างและฝึกโมเดล และเพิ่มเติมว่าแนวคิดเหล่านั้นจับคู่กับ Keras อย่างไร
อย่างไรก็ตาม นี่เป็นปัญหาที่ง่ายมาก สำหรับคำแนะนำเชิงปฏิบัติเพิ่มเติม โปรดดูที่ คำแนะนำการฝึกแบบกำหนดเอง
สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการใช้ลูปการฝึก Keras ในตัว โปรดดู คู่มือ นี้ สำหรับข้อมูลเพิ่มเติมเกี่ยวกับลูปการฝึกและ Keras โปรดดู คู่มือ นี้ สำหรับการเขียนลูปการฝึกแบบกระจายแบบกำหนดเอง โปรดดู คู่มือ นี้