برای ایجاد یک مجموعه داده جدید (چه در TFDS و چه در مخزن خودتان) از این راهنما استفاده کنید.
لیست مجموعه دادههای ما را بررسی کنید تا ببینید آیا مجموعه داده مورد نظر شما از قبل موجود است یا خیر.
TL;DR
سادهترین راه برای نوشتن یک مجموعه داده جدید، استفاده از رابط خط فرمان TFDS است:
cd path/to/my/project/datasets/
tfds new my_dataset # Create `my_dataset/my_dataset.py` template files
# [...] Manually modify `my_dataset/my_dataset_dataset_builder.py` to implement your dataset.
cd my_dataset/
tfds build # Download and prepare the dataset to `~/tensorflow_datasets/`
برای استفاده از مجموعه داده جدید با tfds.load('my_dataset') :
-
tfds.loadبه طور خودکار مجموعه داده تولید شده در~/tensorflow_datasets/my_dataset/(مثلاً توسطtfds build) را شناسایی و بارگذاری میکند. - از طرف دیگر، میتوانید
import my.project.datasets.my_dataset:
import my.project.datasets.my_dataset # Register `my_dataset`
ds = tfds.load('my_dataset') # `my_dataset` registered
نمای کلی
مجموعه دادهها در انواع فرمتها و در انواع مکانها توزیع میشوند، و همیشه در فرمتی ذخیره نمیشوند که آماده ورود به خط لوله یادگیری ماشین باشد. TFDS را وارد کنید.
TFDS آن مجموعه دادهها را به یک فرمت استاندارد (دادههای خارجی -> فایلهای سریالیشده) پردازش میکند، که سپس میتوانند به عنوان خط لوله یادگیری ماشین (فایلهای سریالیشده -> tf.data.Dataset ) بارگذاری شوند. سریالیسازی فقط یک بار انجام میشود. دسترسی بعدی مستقیماً از آن فایلهای از پیش پردازششده خوانده میشود.
بیشتر پیشپردازش به صورت خودکار انجام میشود. هر مجموعه داده، یک زیرکلاس از tfds.core.DatasetBuilder را پیادهسازی میکند که موارد زیر را مشخص میکند:
- دادهها از کجا میآیند (مثلاً URLهای آن)؛
- مجموعه دادهها چه شکلی هستند (یعنی ویژگیهای آن)؛
- نحوه تقسیم دادهها (مثلاً
TRAINوTEST)؛ - و مثالهای منفرد در مجموعه دادهها.
مجموعه داده خود را بنویسید
قالب پیشفرض: tfds new
از TFDS CLI برای تولید فایلهای پایتون قالب مورد نیاز استفاده کنید.
cd path/to/project/datasets/ # Or use `--dir=path/to/project/datasets/` below
tfds new my_dataset
این دستور یک پوشه جدید my_dataset/ با ساختار زیر ایجاد میکند:
my_dataset/
__init__.py
README.md # Markdown description of the dataset.
CITATIONS.bib # Bibtex citation for the dataset.
TAGS.txt # List of tags describing the dataset.
my_dataset_dataset_builder.py # Dataset definition
my_dataset_dataset_builder_test.py # Test
dummy_data/ # (optional) Fake data (used for testing)
checksum.tsv # (optional) URL checksums (see `checksums` section).
در اینجا TODO(my_dataset) را جستجو کنید و آن را مطابق با نیاز خود تغییر دهید.
مثال مجموعه داده
تمام مجموعه دادهها، زیرکلاسهای پیادهسازیشدهی tfds.core.DatasetBuilder هستند که اکثر کدهای تکراری (boilerplate) را مدیریت میکند. این کلاسها از موارد زیر پشتیبانی میکنند:
- مجموعه دادههای کوچک/متوسط که میتوانند روی یک دستگاه واحد تولید شوند (این آموزش).
- مجموعه دادههای بسیار بزرگ که نیاز به تولید توزیعشده دارند (با استفاده از Apache Beam ، به راهنمای مجموعه دادههای عظیم ما مراجعه کنید)
در اینجا یک مثال مینیمال از سازنده مجموعه داده که مبتنی بر tfds.core.GeneratorBasedBuilder است، آورده شده است:
class Builder(tfds.core.GeneratorBasedBuilder):
"""DatasetBuilder for my_dataset dataset."""
VERSION = tfds.core.Version('1.0.0')
RELEASE_NOTES = {
'1.0.0': 'Initial release.',
}
def _info(self) -> tfds.core.DatasetInfo:
"""Dataset metadata (homepage, citation,...)."""
return self.dataset_info_from_configs(
features=tfds.features.FeaturesDict({
'image': tfds.features.Image(shape=(256, 256, 3)),
'label': tfds.features.ClassLabel(
names=['no', 'yes'],
doc='Whether this is a picture of a cat'),
}),
)
def _split_generators(self, dl_manager: tfds.download.DownloadManager):
"""Download the data and define splits."""
extracted_path = dl_manager.download_and_extract('http://data.org/data.zip')
# dl_manager returns pathlib-like objects with `path.read_text()`,
# `path.iterdir()`,...
return {
'train': self._generate_examples(path=extracted_path / 'train_images'),
'test': self._generate_examples(path=extracted_path / 'test_images'),
}
def _generate_examples(self, path) -> Iterator[Tuple[Key, Example]]:
"""Generator of examples for each split."""
for img_path in path.glob('*.jpeg'):
# Yields (key, example)
yield img_path.name, {
'image': img_path,
'label': 'yes' if img_path.name.startswith('yes_') else 'no',
}
توجه داشته باشید که برای برخی از قالبهای داده خاص، ما سازندگان مجموعه داده آماده برای استفاده را ارائه میدهیم تا بیشتر پردازش دادهها را انجام دهند.
بیایید به طور مفصل 3 روش انتزاعی برای بازنویسی را بررسی کنیم.
_info : فراداده مجموعه داده
_info مقدار tfds.core.DatasetInfo را که شامل فرادادههای مجموعه داده است، برمیگرداند.
def _info(self):
# The `dataset_info_from_configs` base method will construct the
# `tfds.core.DatasetInfo` object using the passed-in parameters and
# adding: builder (self), description/citations/tags from the config
# files located in the same package.
return self.dataset_info_from_configs(
homepage='https://dataset-homepage.org',
features=tfds.features.FeaturesDict({
'image_description': tfds.features.Text(),
'image': tfds.features.Image(),
# Here, 'label' can be 0-4.
'label': tfds.features.ClassLabel(num_classes=5),
}),
# If there's a common `(input, target)` tuple from the features,
# specify them here. They'll be used if as_supervised=True in
# builder.as_dataset.
supervised_keys=('image', 'label'),
# Specify whether to disable shuffling on the examples. Set to False by default.
disable_shuffling=False,
)
بیشتر فیلدها باید واضح باشند. برخی نکات دقیق:
-
features: این ویژگی ساختار، شکل و... مجموعه دادهها را مشخص میکند. از انواع دادههای پیچیده (صوتی، تصویری، توالیهای تو در تو و...) پشتیبانی میکند. برای اطلاعات بیشتر به ویژگیهای موجود یا راهنمای رابط ویژگی مراجعه کنید. -
disable_shuffling: به بخش حفظ ترتیب مجموعه دادهها مراجعه کنید.
نوشتن فایل BibText CITATIONS.bib :
- برای دستورالعمل استناد، در وبسایت مجموعه دادهها جستجو کنید (از آن در قالب BibTex استفاده کنید).
- برای مقالات arXiv : مقاله را پیدا کنید و روی لینک
BibTextدر سمت راست کلیک کنید. - مقاله را در گوگل اسکالر پیدا کنید و روی علامت نقل قول دوتایی زیر عنوان کلیک کنید و در پنجره باز شده، روی
BibTeXکلیک کنید. - اگر هیچ مقاله مرتبطی وجود ندارد (مثلاً فقط یک وبسایت وجود دارد)، میتوانید از ویرایشگر آنلاین BibTeX برای ایجاد یک ورودی BibTeX سفارشی استفاده کنید (منوی کشویی دارای نوع ورودی
Onlineاست).
بهروزرسانی فایل TAGS.txt :
- تمام تگهای مجاز از قبل در فایل تولید شده پر شدهاند.
- تمام برچسبهایی که به مجموعه دادهها مربوط نمیشوند را حذف کنید.
- تگهای معتبر در tensorflow_datasets/core/valid_tags.txt فهرست شدهاند.
- برای افزودن برچسب به آن لیست، لطفاً یک PR ارسال کنید.
حفظ ترتیب مجموعه دادهها
به طور پیشفرض، رکوردهای مجموعه دادهها هنگام ذخیره شدن، به منظور یکنواختتر کردن توزیع کلاسها در سراسر مجموعه دادهها، جابجا میشوند، زیرا اغلب رکوردهای متعلق به یک کلاس، مجاور هم هستند. برای تعیین اینکه مجموعه دادهها باید بر اساس کلید تولید شده توسط _generate_examples مرتب شوند، فیلد disable_shuffling باید روی True تنظیم شود. به طور پیشفرض، روی False تنظیم شده است.
def _info(self):
return self.dataset_info_from_configs(
# [...]
disable_shuffling=True,
# [...]
)
به خاطر داشته باشید که غیرفعال کردن قابلیت shuffling تأثیر منفی بر عملکرد دارد، زیرا دیگر نمیتوان Shardها را به صورت موازی خواند.
_split_generators : دادهها را دانلود و تقسیم میکند
دانلود و استخراج دادههای منبع
اکثر مجموعه دادهها نیاز به دانلود دادهها از وب دارند. این کار با استفاده از آرگومان ورودی tfds.download.DownloadManager از _split_generators انجام میشود. dl_manager دارای متدهای زیر است:
-
download:http(s)://وftp(s)://پشتیبانی میکند -
extract: در حال حاضر از فایلهای.zip،.gzو.tarپشتیبانی میکند. -
download_and_extract: مشابهdl_manager.extract(dl_manager.download(urls))
همه این متدها tfds.core.Path (نامهای مستعار برای epath.Path ) را برمیگردانند که اشیاء شبه pathlib.Path هستند.
این متدها از ساختار تو در تو دلخواه ( list ، dict ) پشتیبانی میکنند، مانند:
extracted_paths = dl_manager.download_and_extract({
'foo': 'https://example.com/foo.zip',
'bar': 'https://example.com/bar.zip',
})
# This returns:
assert extracted_paths == {
'foo': Path('/path/to/extracted_foo/'),
'bar': Path('/path/extracted_bar/'),
}
دانلود و استخراج دستی
برخی از دادهها نمیتوانند به طور خودکار دانلود شوند (مثلاً نیاز به ورود دارند)، در این حالت، کاربر دادههای منبع را به صورت دستی دانلود کرده و در manual_dir/ قرار میدهد (پیشفرض روی ~/tensorflow_datasets/downloads/manual/ ).
سپس میتوان از طریق dl_manager.manual_dir به فایلها دسترسی پیدا کرد:
class MyDataset(tfds.core.GeneratorBasedBuilder):
MANUAL_DOWNLOAD_INSTRUCTIONS = """
Register into https://example.org/login to get the data. Place the `data.zip`
file in the `manual_dir/`.
"""
def _split_generators(self, dl_manager):
# data_path is a pathlib-like `Path('<manual_dir>/data.zip')`
archive_path = dl_manager.manual_dir / 'data.zip'
# Extract the manually downloaded `data.zip`
extracted_path = dl_manager.extract(archive_path)
...
مکان manual_dir را میتوان با tfds build --manual_dir= یا با استفاده از tfds.download.DownloadConfig سفارشیسازی کرد.
خواندن مستقیم آرشیو
dl_manager.iter_archive فایلهای آرشیو را به ترتیب و بدون استخراج میخواند. این کار میتواند فضای ذخیرهسازی را ذخیره کرده و عملکرد برخی از سیستمهای فایل را بهبود بخشد.
for filename, fobj in dl_manager.iter_archive('path/to/archive.zip'):
...
fobj همان متدهایی را دارد که with open('rb') as fobj: (مثلاً fobj.read() )
تعیین تقسیمبندی مجموعه دادهها
اگر مجموعه داده دارای تقسیمبندیهای از پیش تعریفشدهای است (مثلاً MNIST تقسیمبندیهای train و test دارد)، آنها را نگه دارید. در غیر این صورت، فقط یک تقسیمبندی all مشخص کنید. کاربران میتوانند به صورت پویا زیرتقسیمبندیهای خود را با API subsplit ایجاد کنند (مثلاً split='train[80%:]' ). توجه داشته باشید که هر رشته الفبایی میتواند به عنوان نام تقسیمبندی استفاده شود، جدا از all ذکر شده.
def _split_generators(self, dl_manager):
# Download source data
extracted_path = dl_manager.download_and_extract(...)
# Specify the splits
return {
'train': self._generate_examples(
images_path=extracted_path / 'train_imgs',
label_path=extracted_path / 'train_labels.csv',
),
'test': self._generate_examples(
images_path=extracted_path / 'test_imgs',
label_path=extracted_path / 'test_labels.csv',
),
}
_generate_examples : مولد مثال
_generate_examples برای هر تقسیم از دادههای منبع، مثالهایی تولید میکند.
این متد معمولاً مصنوعات مجموعه داده منبع (مثلاً یک فایل CSV) را میخواند و تاپلهای (key, feature_dict) را ارائه میدهد:
-
key: شناسهی مثال. برای ترکیب قطعی مثالها با استفاده ازhash(key)یا برای مرتبسازی بر اساس کلید، زمانی که ترکیب غیرفعال است (به بخش حفظ ترتیب مجموعه دادهها مراجعه کنید)، استفاده میشود. باید:- منحصر به فرد : اگر دو مثال از کلید یکسانی استفاده کنند، یک استثنا ایجاد میشود.
- قطعی : نباید به
download_dir،os.path.listdirorder و... وابسته باشد. تولید دو باره دادهها باید کلید یکسانی را تولید کند. - قابل مقایسه : اگر عملگر درهمسازی غیرفعال باشد، از کلید برای مرتبسازی مجموعه دادهها استفاده خواهد شد.
-
feature_dict: یکdictحاوی مقادیر نمونه.- ساختار باید با ساختار
features=تعریف شده درtfds.core.DatasetInfoمطابقت داشته باشد. - انواع دادههای پیچیده (تصویر، ویدئو، صدا، ...) به طور خودکار رمزگذاری میشوند.
- هر ویژگی اغلب چندین نوع ورودی را میپذیرد (مثلاً video accept
/path/to/vid.mp4,np.array(shape=(l, h, w, c)),List[paths],List[np.array(shape=(h, w, c)],List[img_bytes],...) - برای اطلاعات بیشتر به راهنمای کانکتور ویژگی مراجعه کنید.
- ساختار باید با ساختار
def _generate_examples(self, images_path, label_path):
# Read the input data out of the source files
with label_path.open() as f:
for row in csv.DictReader(f):
image_id = row['image_id']
# And yield (key, feature_dict)
yield image_id, {
'image_description': row['description'],
'image': images_path / f'{image_id}.jpeg',
'label': row['label'],
}
دسترسی به فایل و tf.io.gfile
برای پشتیبانی از سیستمهای ذخیرهسازی ابری، از استفاده از عملیات ورودی/خروجی (I/O) داخلی پایتون خودداری کنید.
در عوض، dl_manager اشیاء شبیه به pathlib را که مستقیماً با فضای ذخیرهسازی Google Cloud سازگار هستند، برمیگرداند:
path = dl_manager.download_and_extract('http://some-website/my_data.zip')
json_path = path / 'data/file.json'
json.loads(json_path.read_text())
روش دیگر، استفاده از API tf.io.gfile به جای API داخلی برای عملیات فایل است:
-
open->tf.io.gfile.GFile -
os.rename->tf.io.gfile.rename - ...
Pathlib باید به tf.io.gfile ترجیح داده شود (به rational مراجعه کنید).
وابستگیهای اضافی
برخی از مجموعه دادهها فقط در طول تولید به وابستگیهای اضافی پایتون نیاز دارند. برای مثال، مجموعه داده SVHN از scipy برای بارگذاری برخی از دادهها استفاده میکند.
اگر در حال اضافه کردن مجموعه داده به مخزن TFDS هستید، لطفاً tfds.core.lazy_imports برای کوچک نگه داشتن بسته tensorflow-datasets استفاده کنید. کاربران فقط در صورت نیاز، وابستگیهای اضافی را نصب میکنند.
برای استفاده از lazy_imports :
- یک ورودی برای مجموعه داده خود به
DATASET_EXTRASدرsetup.pyاضافه کنید. این کار باعث میشود که کاربران بتوانند، برای مثال،pip install 'tensorflow-datasets[svhn]'برای نصب وابستگیهای اضافی انجام دهند. - یک ورودی برای وارد کردن اطلاعات به
LazyImporterوLazyImportsTestاضافه کنید. - برای دسترسی به وابستگی (برای مثال،
tfds.core.lazy_imports.scipy) درDatasetBuilderخودtfds.core.lazy_importsاستفاده کنید.
دادههای خراب
برخی از مجموعه دادهها کاملاً پاک نیستند و حاوی دادههای خراب هستند (برای مثال، تصاویر در فایلهای JPEG هستند اما برخی از آنها JPEG نامعتبر هستند). این مثالها باید نادیده گرفته شوند، اما در توضیحات مجموعه دادهها یادداشتی بگذارید که چند مثال حذف شدهاند و چرا.
پیکربندی/انواع مجموعه دادهها (tfds.core.BuilderConfig)
برخی از مجموعه دادهها ممکن است چندین نوع یا گزینههایی برای نحوه پیشپردازش دادهها و نوشتن روی دیسک داشته باشند. برای مثال، cycle_gan برای هر جفت شیء ( cycle_gan/horse2zebra ، cycle_gan/monet2photo ،...) یک پیکربندی دارد.
این کار از طریق tfds.core.BuilderConfig انجام میشود:
شیء پیکربندی خود را به عنوان یک زیرکلاس از
tfds.core.BuilderConfigتعریف کنید. برای مثال،MyDatasetConfig.@dataclasses.dataclass class MyDatasetConfig(tfds.core.BuilderConfig): img_size: Tuple[int, int] = (0, 0)عضو کلاس
BUILDER_CONFIGS = []را درMyDatasetتعریف کنید کهMyDatasetConfigهایی را که مجموعه داده در معرض نمایش قرار میدهد، فهرست میکند.class MyDataset(tfds.core.GeneratorBasedBuilder): VERSION = tfds.core.Version('1.0.0') # pytype: disable=wrong-keyword-args BUILDER_CONFIGS = [ # `name` (and optionally `description`) are required for each config MyDatasetConfig(name='small', description='Small ...', img_size=(8, 8)), MyDatasetConfig(name='big', description='Big ...', img_size=(32, 32)), ] # pytype: enable=wrong-keyword-argsself.builder_configدرMyDatasetبرای پیکربندی تولید داده استفاده کنید (مثلاًshape=self.builder_config.img_size). این ممکن است شامل تنظیم مقادیر مختلف در_info()یا تغییر دسترسی به دادههای دانلود باشد.
یادداشتها:
- هر پیکربندی یک نام منحصر به فرد دارد. نام کامل یک پیکربندی
dataset_name/config_nameاست (مثلاًcoco/2017). - اگر مشخص نشده باشد، اولین پیکربندی در
BUILDER_CONFIGSاستفاده خواهد شد (مثلاًtfds.load('c4')که به طور پیشفرض رویc4/en).
برای مثالی از مجموعه دادهای که از BuilderConfig استفاده میکند، به anli مراجعه کنید.
نسخه
نسخه میتواند به دو معنی متفاوت اشاره داشته باشد:
- نسخه داده اصلی "خارجی": مثلاً COCO نسخه ۲۰۱۹، نسخه ۲۰۱۷،...
- نسخه کد TFDS «داخلی»: مثلاً تغییر نام یک ویژگی در
tfds.features.FeaturesDict، رفع اشکال در_generate_examples
برای بهروزرسانی یک مجموعه داده:
- برای بهروزرسانی دادههای «خارجی»: ممکن است چندین کاربر بخواهند به طور همزمان به یک سال/نسخه خاص دسترسی داشته باشند. این کار با استفاده از یک
tfds.core.BuilderConfigبرای هر نسخه (مثلاًcoco/2017،coco/2019) یا یک کلاس برای هر نسخه (مثلاًVoc2007،Voc2012) انجام میشود. - برای بهروزرسانی «داخلی» کد: کاربران فقط جدیدترین نسخه را دانلود میکنند. هرگونه بهروزرسانی کد باید ویژگی کلاس
VERSIONرا افزایش دهد (مثلاً از1.0.0بهVERSION = tfds.core.Version('2.0.0')) که از نسخهبندی معنایی پیروی میکند.
افزودن یک ورودی برای ثبت نام
فراموش نکنید که ماژول مجموعه داده را به پروژه خود __init__ وارد کنید تا به طور خودکار در tfds.load و tfds.builder ثبت شود.
import my_project.datasets.my_dataset # Register MyDataset
ds = tfds.load('my_dataset') # MyDataset available
برای مثال، اگر در tensorflow/datasets مشارکت میکنید، ماژول import را به زیرشاخهی آن، __init__.py (مثلاً image/__init__.py ) اضافه کنید.
بررسی اشکالات رایج در پیادهسازی
لطفاً اشکالات رایج در پیادهسازی را بررسی کنید.
مجموعه دادههای خود را آزمایش کنید
دانلود و آمادهسازی: tfds build
برای تولید مجموعه داده، tfds build از دایرکتوری my_dataset/ اجرا کنید:
cd path/to/datasets/my_dataset/
tfds build --register_checksums
برخی از پرچمهای مفید برای توسعه:
-
--pdb: اگر یک استثنا رخ دهد، حالت اشکالزدایی را وارد میکند. -
--overwrite: اگر مجموعه داده از قبل ایجاد شده باشد، فایلهای موجود را حذف میکند. -
--max_examples_per_split: فقط X مثال اول (پیشفرض ۱) را تولید میکند، نه کل مجموعه داده را. -
--register_checksums: مجموعهای بررسی آدرسهای اینترنتی دانلود شده را ثبت میکند. فقط باید در زمان توسعه استفاده شود.
برای لیست کامل پرچمها، به مستندات CLI مراجعه کنید.
چک سام ها
توصیه میشود که چکسامهای مجموعه دادههای خود را ثبت کنید تا قطعیت تضمین شود، به مستندسازی کمک شود و... این کار با تولید مجموعه دادهها با --register_checksums انجام میشود (به بخش قبل مراجعه کنید).
اگر مجموعه دادههای خود را از طریق PyPI منتشر میکنید، فراموش نکنید که فایلهای checksums.tsv را اکسپورت کنید (مثلاً در package_data فایل setup.py ).
مجموعه دادههای خود را آزمایش واحد کنید
tfds.testing.DatasetBuilderTestCase یک TestCase پایه برای آزمایش کامل یک مجموعه داده است. این مجموعه داده از "دادههای ساختگی" به عنوان دادههای آزمایشی استفاده میکند که ساختار مجموعه داده منبع را تقلید میکنند.
- دادههای آزمایشی باید در دایرکتوری
my_dataset/dummy_data/قرار گیرند و باید از مجموعه دادههای منبع، همانطور که دانلود و استخراج شدهاند، تقلید کنند. این دادهها را میتوان به صورت دستی یا خودکار با یک اسکریپت ( مثال اسکریپت ) ایجاد کرد. - مطمئن شوید که از دادههای مختلف در تقسیمبندی دادههای آزمایشی خود استفاده میکنید، زیرا اگر تقسیمبندیهای مجموعه دادههای شما همپوشانی داشته باشند، آزمایش با شکست مواجه خواهد شد.
- دادههای آزمایشی نباید حاوی هیچ گونه محتوای دارای حق نشر باشند . در صورت شک، دادهها را با استفاده از محتوای مجموعه دادههای اصلی ایجاد نکنید.
import tensorflow_datasets as tfds
from . import my_dataset_dataset_builder
class MyDatasetTest(tfds.testing.DatasetBuilderTestCase):
"""Tests for my_dataset dataset."""
DATASET_CLASS = my_dataset_dataset_builder.Builder
SPLITS = {
'train': 3, # Number of fake train example
'test': 1, # Number of fake test example
}
# If you are calling `download/download_and_extract` with a dict, like:
# dl_manager.download({'some_key': 'http://a.org/out.txt', ...})
# then the tests needs to provide the fake output paths relative to the
# fake data directory
DL_EXTRACT_RESULT = {
'name1': 'path/to/file1', # Relative to my_dataset/dummy_data dir.
'name2': 'file2',
}
if __name__ == '__main__':
tfds.testing.test_main()
برای تست مجموعه داده، دستور زیر را اجرا کنید.
python my_dataset_test.py
برای ما بازخورد ارسال کنید
ما به طور مداوم در تلاشیم تا گردش کار ایجاد مجموعه دادهها را بهبود بخشیم، اما تنها در صورتی میتوانیم این کار را انجام دهیم که از مشکلات آگاه باشیم. هنگام ایجاد مجموعه دادهها با چه مشکلات یا خطاهایی مواجه شدید؟ آیا بخشی وجود داشت که گیجکننده باشد یا بار اول کار نکند؟
لطفا نظرات خود را در GitHub به اشتراک بگذارید.