เอกสารที่ทดสอบได้
TensorFlow ใช้ DocTest เพื่อทดสอบข้อมูลโค้ดในสตริงเอกสาร Python ข้อมูลโค้ดต้องเป็นโค้ด Python ที่สามารถเรียกใช้งานได้ หากต้องการเปิดใช้งานการทดสอบ ให้เพิ่มบรรทัดหน้าด้วย >>>
(วงเล็บมุมซ้าย 3 อัน) ตัวอย่างเช่น ต่อไปนี้เป็นข้อความที่ตัดตอนมาจากฟังก์ชัน tf.concat
ในไฟล์ต้นฉบับ array_ops.py :
def concat(values, axis, name="concat"):
"""Concatenates tensors along one dimension.
...
>>> t1 = [[1, 2, 3], [4, 5, 6]]
>>> t2 = [[7, 8, 9], [10, 11, 12]]
>>> concat([t1, t2], 0)
<tf.Tensor: shape=(4, 3), dtype=int32, numpy=
array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12]], dtype=int32)>
<... more description or code snippets ...>
Args:
values: A list of `tf.Tensor` objects or a single `tf.Tensor`.
axis: 0-D `int32` `Tensor`. Dimension along which to concatenate. Must be
in the range `[-rank(values), rank(values))`. As in Python, indexing for
axis is 0-based. Positive axis in the rage of `[0, rank(values))` refers
to `axis`-th dimension. And negative axis refers to `axis +
rank(values)`-th dimension.
name: A name for the operation (optional).
Returns:
A `tf.Tensor` resulting from concatenation of the input tensors.
"""
<code here>
หากต้องการประเมินคุณภาพเอกสารอ้างอิง โปรดดูส่วนตัวอย่างของ คำแนะนำเอกสาร API ของ TensorFlow 2 (โปรดทราบว่า Task Tracker บนชีตนี้ไม่ได้ใช้งานอีกต่อไป)
ทำให้โค้ดทดสอบได้ด้วย DocTest
ปัจจุบัน เอกสารจำนวนมากใช้ backticks (```) เพื่อระบุโค้ด วิธีทำให้โค้ดทดสอบได้ด้วย DocTest:
- ลบเครื่องหมายย้อนกลับ (```) และใช้วงเล็บปีกกาซ้าย (>>>) ที่ด้านหน้าของแต่ละบรรทัด ใช้ (...) นำหน้าบรรทัดต่อเนื่อง
- เพิ่มบรรทัดใหม่เพื่อแยกตัวอย่าง DocTest ออกจากข้อความ Markdown เพื่อแสดงผลอย่างถูกต้องบน tensorflow.org
การปรับแต่ง
TensorFlow ใช้การปรับแต่งบางอย่างกับตรรกะ doctest ในตัว:
- มันไม่ได้เปรียบเทียบค่าทศนิยมเป็นข้อความ: ค่าทศนิยมจะถูกแยกออกจากข้อความและเปรียบเทียบโดยใช้
allclose
กับ liberalatol
และrtol
tolerences สิ่งนี้ช่วยให้:- เอกสารที่ชัดเจนยิ่งขึ้น - ผู้เขียนไม่จำเป็นต้องใส่ทศนิยมทั้งหมด
- การทดสอบที่มีประสิทธิภาพมากขึ้น - การเปลี่ยนแปลงเชิงตัวเลขในการใช้งานพื้นฐานไม่ควรทำให้ doctest ล้มเหลว
- จะตรวจสอบเอาต์พุตหากผู้เขียนรวมเอาต์พุตสำหรับบรรทัดเท่านั้น ซึ่งช่วยให้ได้เอกสารที่ชัดเจนยิ่งขึ้น เนื่องจากผู้เขียนมักไม่จำเป็นต้องบันทึกค่ากลางที่ไม่เกี่ยวข้องเพื่อป้องกันไม่ให้มีการพิมพ์
ข้อพิจารณาหลักคำสอน
- โดยรวม : เป้าหมายของ doctest คือการจัดหาเอกสารและยืนยันว่าเอกสารใช้งานได้ สิ่งนี้แตกต่างจากการทดสอบหน่วย ดังนั้น:
- เก็บตัวอย่างง่ายๆ
- หลีกเลี่ยงผลลัพธ์ที่ยาวหรือซับซ้อน
- ใช้ตัวเลขกลมถ้าเป็นไปได้
- รูปแบบเอาต์พุต : เอาต์พุตของข้อมูลโค้ดจะต้องอยู่ใต้โค้ดที่สร้างเอาต์พุตโดยตรง นอกจากนี้ เอาต์พุตใน docstring จะต้องเท่ากับเอาต์พุตที่จะเป็นหลังจากเรียกใช้โค้ดทุกประการ ดูตัวอย่างข้างต้น นอกจากนี้ โปรดดู ส่วนนี้ ในเอกสาร DocTest หากเอาต์พุตเกินขีดจำกัด 80 บรรทัด คุณสามารถใส่เอาต์พุตพิเศษบนบรรทัดใหม่ได้ แล้ว DocTest จะจดจำมัน ตัวอย่างเช่น ดูบล็อกหลายบรรทัดด้านล่าง
- Globals : โมดูล
`tf`
,np
และos
มีให้ใช้งานเสมอใน DocTest ของ TensorFlow ใช้สัญลักษณ์ : ใน DocTest คุณสามารถเข้าถึงสัญลักษณ์ที่กำหนดในไฟล์เดียวกันได้โดยตรง หากต้องการใช้สัญลักษณ์ที่ไม่ได้กำหนดไว้ในไฟล์ปัจจุบัน โปรดใช้ API สาธารณะของ TensorFlow
tf.xxx
แทนxxx
ดังที่คุณเห็นในตัวอย่างด้านล่าง`random.normal`
เข้าถึงได้ผ่าน`tf.random.normal`
นี่เป็นเพราะว่า`random.normal`
ไม่ปรากฏในNewLayer
def NewLayer(): """This layer does cool stuff. Example usage: >>> x = tf.random.normal((1, 28, 28, 3)) >>> new_layer = NewLayer(x) >>> new_layer <tf.Tensor: shape=(1, 14, 14, 3), dtype=int32, numpy=...> """
ค่าจุดลอยตัว : doctest ของ TensorFlow แยกค่า float ออกจากสตริงผลลัพธ์ และเปรียบเทียบการใช้
np.allclose
กับค่าความคลาดเคลื่อนที่สมเหตุสมผล (atol=1e-6
,rtol=1e-6
) วิธีนี้ผู้เขียนไม่จำเป็นต้องกังวลเกี่ยวกับเอกสารที่แม่นยำเกินไปซึ่งทำให้เกิดความล้มเหลวเนื่องจากปัญหาด้านตัวเลข เพียงวางค่าที่คาดหวังเอาต์พุตที่ไม่ได้กำหนดไว้ : ใช้จุดไข่ปลา (
...
) สำหรับส่วนที่ไม่แน่นอนและ DocTest จะเพิกเฉยต่อสตริงย่อยนั้นx = tf.random.normal((1,))
print(x)
<tf.Tensor: shape=(1,), dtype=float32, numpy=..., dtype=float32)>
บล็อกหลายบรรทัด : DocTest เข้มงวดเกี่ยวกับความแตกต่างระหว่างคำสั่งบรรทัดเดียวและหลายบรรทัด โปรดสังเกตการใช้ (...) ด้านล่าง:
if x > 0:
print("X is positive")
model.compile(
loss="mse",
optimizer="adam")
ข้อยกเว้น : รายละเอียดข้อยกเว้นจะถูกละเว้น ยกเว้นข้อยกเว้นที่เกิดขึ้น ดู สิ่งนี้ สำหรับรายละเอียดเพิ่มเติม
np_var = np.array([1, 2])
tf.keras.backend.is_keras_tensor(np_var)
Traceback (most recent call last):
ValueError: Unexpectedly found an instance of type `<class x27;numpy.ndarray'>`.
ใช้สำเนา tf-doctest ภายในโปรเจ็กต์
API บางตัวใน TensorFlow มาจากโครงการภายนอก:
-
tf.estimator
(จาก tensorflow_estimator ) -
tf.summary
เทนเซอร์บอร์ด ) -
tf.keras.preprocessing
(จาก keras-preprocessing )
หากคุณกำลังทำงานในโปรเจ็กต์ภายนอกหรือบน TensorFlow API ที่อยู่ในโปรเจ็กต์ภายนอก คำแนะนำเหล่านี้จะไม่ทำงานเว้นแต่ว่าโปรเจ็กต์นั้นจะมีสำเนา tf_doctest
ในเครื่องของตัวเอง และคุณใช้สำเนานั้นแทนของ TensorFlow
ตัวอย่างเช่น: tf_estimator_doctest.py
ทดสอบบนเครื่องของคุณ
มีสองวิธีในการทดสอบโค้ดใน docstring ภายในเครื่อง:
หากคุณเพียงเปลี่ยน docstring ของคลาส/ฟังก์ชัน/เมธอด คุณสามารถทดสอบได้โดยส่งพาธของไฟล์นั้นไปที่ tf_doctest.py ตัวอย่างเช่น:
python tf_doctest.py --file=<file_path>
สิ่งนี้จะเรียกใช้งานโดยใช้ TensorFlow เวอร์ชันที่คุณติดตั้งไว้ เพื่อให้แน่ใจว่าคุณกำลังใช้โค้ดเดียวกันกับที่คุณกำลังทดสอบ:
- ใช้ pip install tf-nightly ที่เป็นปัจจุบัน
pip install -U tf-nightly
- ปรับคำขอดึงของคุณใหม่ไปยังการดึงล่าสุดจากสาขาหลัก ของ TensorFlow
- ใช้ pip install tf-nightly ที่เป็นปัจจุบัน
หากคุณกำลังเปลี่ยนโค้ดและ docstring ของคลาส/ฟังก์ชัน/เมธอด คุณจะต้อง สร้าง TensorFlow จาก source เมื่อคุณตั้งค่าให้สร้างจากแหล่งที่มาแล้ว คุณสามารถรันการทดสอบได้:
bazel run //tensorflow/tools/docs:tf_doctest
หรือ
bazel run //tensorflow/tools/docs:tf_doctest -- --module=ops.array_ops
--module
สัมพันธ์กับtensorflow.python