از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
آموزش مدلهای میدان تابش عصبی (NeRF) با Keras/TensorFlow و DeepVision
سرفصلهای مطلب
میدان های تابشی عصبی که در زبان عامیانه به آن ها می گویند NeRFs در سال 2020 جهان را تحت تأثیر طوفان قرار داده اند که در کنار این مقاله منتشر شده است «NeRF: نمایش صحنهها بهعنوان میدانهای تابشی عصبی برای سنتز نمایش»و با توجه به تصاویر پراکنده و موقعیت های دوربین، همچنان سنگ بنای ترکیب با کیفیت بالا از نماهای جدید هستند.
از آن زمان، آنها برنامه های کاربردی متعددی پیدا کرده اند، اما احتمالاً برجسته ترین آنها در مدل سازی حجمی جغرافیایی، با تکیه شرکت هایی مانند Google روی NeRF برای ایجاد ساختارهای سه بعدی ساختمان ها و مکان های میراث از زوایای مختلف تصاویر ماهواره ای و شرکت های متخصص در انجام بازسازی سه بعدی و دیجیتالی کردن مکان های فرهنگی شناخته شده.
در این راهنما، ما یک مدل میدان تابش عصبی (NeRF) را آموزش خواهیم داد روی مجموعه داده اصلی Tiny NeRF، با استفاده از TensorFlow/Keras و DeepVision، برای انجام سنتز نمای جدید/بازسازی سه بعدی.
در یک ساعت، روی یک ماشین تجاری، نماهای جدیدی از تصاویر را از مجموعه داده TinyNeRF ارائه خواهید کرد:
دیدگاه رمان سنتز و میدان های تابشی عصبی
این بخش خلاصه/مقدمه سادهسازیشدهای درباره روش کار میدانهای تابشی عصبی ارائه میدهد، اما اگر در این زمینه تازه کار هستید، ممکن است کمی زمان ببرد تا به طور مستقیم روش کار آنها را هضم کنید.
NeRF ها برای سنتز نمای جدید – ایجاد نماهای جدید از اشیا و تصاویر، با توجه به برخی نماها. در واقع، میتوانید سنتز نمای جدید را به عنوان تبدیل 2 بعدی-> 3 بعدی در نظر بگیرید، و روشهای زیادی برای حل این مشکل وجود دارد که برخی از آنها موفقتر از دیگران هستند.
از لحاظ تاریخی یک مشکل چالش برانگیز، راه حل ارائه شده توسط NeRF ها بسیار ساده است و در عین حال نتایج پیشرفته ای را به همراه دارد و تصاویری با کیفیت بسیار بالا از زوایای جدید ایجاد می کند:
این، به طور طبیعی، آنها را به عنوان یک رویکرد اساسی برای حل ترکیب دیدگاه جدید، با بسیاری از مقالات بعدی در حال بررسی، تنظیم و بهبود قرار داد. روی ایده های موجود در آن
خط لوله از داده ها به نتایج را می توان به صورت زیر خلاصه کرد:
جایی که شبکه عصبی از تصاویر پراکنده با تولید مصنوعی یاد می گیرد اشعه ها که در فواصل زمانی معین پیش بینی و نمونه برداری می شوند. با توجه به فرادادههای مربوط به تصاویر، مانند موقعیتهای دوربین در هنگام گرفتن تصاویر، تصاویر در فضا قرار میگیرند. به همین دلیل – شما فقط نمی توانید هر تصویری را وارد کنید، و نیاز موقعیت های دوربین برای اینکه بتوانید تصاویر را به طور دقیق در فضا قرار دهید تا پرتوها مجموعه ای قابل درک از نقاط را ایجاد کنند. سپس نقاط نمونه برداری شده مجموعه ای سه بعدی از نقاط را تشکیل می دهند که صحنه حجمی را نشان می دهد:
شبکه عصبی تقریباً a عملکرد صحنه حجمی – مقادیر RGB و چگالی (σ) یک صحنه. در واقع، ما شبکه را آموزش می دهیم تا حفظ کردن رنگ و چگالی هر نقطه ورودی، تا بتوان تصاویر را از دیدگاه های جدید بازسازی کرد. همانطور که گفته شد – NeRF ها آموزش داده نمی شوند روی مجموعه ای از تصاویر و می تواند به تصاویر جدید تعمیم یابد. NeRF ها برای رمزگذاری یک صحنه آموزش داده می شوند و سپس فقط برای آن یک صحنه استفاده می شوند. همانطور که وزن شبکه خود صحنه را نشان می دهد.
این مشکل اصلی NeRF ها است – شما باید یک شبکه برای هر صحنه ای که می خواهید رمزگذاری کنید و آموزش آموزش دهید. process هم تا حدودی کند است و هم برای ورودی های بزرگ به حافظه زیادی نیاز دارد. بهبود در زمان آموزش یک حوزه تحقیقاتی با تکنیک های جدید مانند “بهینه سازی شبکه وکسل مستقیم” که به طور قابل توجهی زمان آموزش را بدون تغییر کیفیت تصویر در آن بهبود می بخشد process.
میدان های تابشی عصبی در DeepVision و TensorFlow
پیادهسازیهای NeRF برای کسانی که تازه به رندر حجمی میپردازند میتواند کمی دلهرهآور باشد، و مخازن کد معمولاً شامل بسیاری از روشهای کمکی برای برخورد با دادههای حجمی هستند که ممکن است برای برخی غیرمعمول به نظر برسد. DeepVision یک کتابخانه بینایی کامپیوتری جدید است که هدف آن یکسان سازی بینایی کامپیوتر تحت یک API مشترک، با باطن های قابل تعویض (TensorFlow و PyTorch)، تبدیل وزن خودکار بین مدل ها، و مدل هایی با پیاده سازی یکسان در چارچوب های Backend است.
برای کاهش مانع ورود، DeepVision یک پیادهسازی ساده و در عین حال واقعی از مدلهای Neural Radiance Field را با چندین راهاندازی برای تطبیق ماشینهای بیشتر و کمتر قدرتمند با تنظیمات سختافزاری متفاوت ارائه میدهد:
NeRFTiny
NeRFSmall
NeRFMedium
NeRF
NeRFLarge
برای ایجاد این تنظیمات از دو پارامتر استفاده می شود – width
و depth
. از آنجایی که NeRF ها در اصل فقط یک مدل MLP هستند که از tf.keras.layers.Dense()
لایه ها (با یک الحاق واحد بین لایه ها)، depth
به طور مستقیم نشان دهنده تعداد Dense
لایه ها، در حالی که width
تعداد واحدهای مورد استفاده در هر یک را نشان می دهد.
NeRF
مطابق با تنظیمات مورد استفاده در کاغذ اصلی است، اما ممکن است اجرای آن دشوار باشد روی برخی از ماشین های محلی، در این صورت، NeRFMedium
عملکرد بسیار مشابهی را با نیازهای حافظه کوچکتر ارائه می دهد.
بیایید پیش برویم و DeepVision را با آن نصب کنیم pip
:
$ pip install deepvision-toolkit
نمونه سازی یک مدل به همین سادگی است:
import deepvision
model = deepvision.models.NeRFMedium(input_shape=(num_pos, input_features),
backend='tensorflow')
model.summary()
خود مدل بسیار ساده است:
Model: "ne_rftf"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_1 (InputLayer) ((None, 640000, 195 0 ()
))
dense (Dense) (None, 640000, 128) 25088 ('input_1(0)(0)')
dense_1 (Dense) (None, 640000, 128) 16512 ('dense(0)(0)')
dense_2 (Dense) (None, 640000, 128) 16512 ('dense_1(0)(0)')
dense_3 (Dense) (None, 640000, 128) 16512 ('dense_2(0)(0)')
dense_4 (Dense) (None, 640000, 128) 16512 ('dense_3(0)(0)')
concatenate (Concatenate) (None, 640000, 323) 0 ('dense_4(0)(0)',
'input_1(0)(0)')
dense_5 (Dense) (None, 640000, 128) 41472 ('concatenate(0)(0)')
dense_6 (Dense) (None, 640000, 4) 516 ('dense_5(0)(0)')
==================================================================================================
Total params: 133,128
Trainable params: 133,124
Non-trainable params: 4
__________________________________________________________________________________________________
ما نگاهی دقیق تر به روش برخورد با خروجی های مدل و روش رندر کردن تصاویر تولید شده توسط وزن های مدل در یک لحظه خواهیم داشت.
در حال بارگیری مجموعه داده TinyNeRF
از آنجایی که NeRF ها می توانند تا حدودی گران باشند روی تصاویر ورودی بزرگتر، آنها با مجموعه داده کوچکی از تصاویر 100×100، دوبله منتشر شدند. TinyNeRF برای آسان تر کردن تست و تکرار متعاقباً به یک مجموعه داده کلاسیک برای آزمایش NeRF تبدیل شده است روی و برای ورود به این حوزه، مشابه روش تبدیل MNIST به “Hello World” تشخیص رقم.
مجموعه داده به صورت یک موجود است .npz
فایل، و حاوی تصاویر، نقاط کانونی (که برای عادی سازی استفاده می شود) و ژست های دوربین، و می توانید از انتشار کد رسمی دریافت کنید:
import requests
import numpy as np
import matplotlib.pyplot as plt
url = "https://people.eecs.berkeley.edu/~bmild/nerf/tiny_nerf_data.npz"
save_path = 'tiny_nerf.npz'
file_data = requests.get(url).content
with open(save_path, "wb") as file:
file.write(file_data)
data = np.load(save_path)
images, poses, focal = data("images"), data("poses"), data("focal")
print(images.shape)
print(poses.shape)
print(focal)
106 تصویر، هر کدام 100×100، با 3 کانال (RGB) وجود دارد. تمام تصاویر مربوط به یک بولدوزر کوچک لگو است. بیایید پنج تصویر اول را ترسیم کنیم:
fig, ax = plt.subplots(1, 5, figsize=(20, 12))
for i in range(5):
ax(i).imshow(images(i))
را موقعیت های دوربین ارائه شده در مجموعه داده برای قادر به بازسازی فضایی که در آن تصاویر گرفته شده است، بسیار مهم هستند، که به ما امکان می دهد پرتوها را از طریق تصاویر پخش کنیم و یک فضای حجمی با نقاط نمونه برداری شده تشکیل دهیم. روی هر طرح ریزی
با این حال، از آنجایی که این مجموعه داده نیاز به آماده سازی زیادی برای مرحله آموزش دارد – DeepVision یک پیشنهاد می دهد load_tiny_nerf()
بارگذار مجموعه داده، که آماده سازی را برای شما انجام می دهد، با یک گزینه اختیاری validation_split
، pos_embed
و num_ray_samples
، و یک وانیل را برمی گرداند tf.data.Dataset
که می توانید خطوط لوله با کارایی بالا ایجاد کنید:
import deepvision
train_ds, valid_ds = deepvision.datasets.load_tiny_nerf(pos_embed=16,
num_ray_samples=32,
save_path='tiny_nerf.npz',
validation_split=0.2,
backend='tensorflow')
شما مطلقاً نیازی به ایجاد یک مجموعه اعتبار سنجی در اینجا ندارید، زیرا نکته اصلی است است برای اضافه کردن و به خاطر سپردن کامل تصاویر، و مجموعه اعتبار سنجی در اینجا در درجه اول به عنوان یک بررسی سلامت عقل ایجاد می شود.
بیایید نگاهی به طول و اشکال ورودی در مجموعه داده آموزشی بیندازیم:
print('Train dataset length:', len(train_ds))
print(train_ds)
این نتیجه در:
Train dataset length: 84
<ZipDataset element_spec=(TensorSpec(shape=(100, 100, 3), dtype=tf.float32, name=None),
(TensorSpec(shape=(320000, 99), dtype=tf.float32, name=None), TensorSpec(shape=(100, 100, 32), dtype=tf.float32, name=None)))>
را pos_embed
آرگومان تعداد را تعیین می کند تعبیه های موضعی برای تبدیل مختصات 5 بعدی (x، y، z و زوایای دید تتا و فی) استفاده می شود. تعبیه های موقعیتی بودند حیاتی برای اینکه شبکه بتواند توابع فرکانس بالاتر را نشان دهد، که در گذشته “یک عنصر مفقود” در کارکرد این نوع تکنیک بود، زیرا شبکه ها به دلیل تعصب خود برای تقریب توابع نشان دهنده تنوع فرکانس بالا در رنگ و هندسه تلاش می کردند. به جای یادگیری توابع فرکانس پایین:
را num_ray_samples
نشان دهنده تعداد نمونه های گرفته شده در طول هر پرتو پرتاب شده در تصویر است.
طبیعتاً، هرچه از جاسازیها و نمونههای پرتوی موقعیتی بیشتری استفاده کنید، وضوح صحنه حجمی را به طور تقریبی بالاتر میبرید، و بنابراین، جزئیات بیشتر تصاویر نهایی به قیمت هزینههای محاسباتی بالاتر خواهد بود.
آموزش NeRF با TensorFlow/Keras و DeepVision
بیایید نگاهی به یک مثال سرتاسر بارگذاری داده ها، تهیه مجموعه داده، نمونه سازی یک مدل و آموزش آن با استفاده از DeepVision و اکوسیستم TensorFlow/Keras بیندازیم:
import deepvision
from deepvision.datasets import load_tiny_nerf
import tensorflow as tf
config = {
'img_height': 100,
'img_width': 100,
'pos_embed': 32,
'num_ray_samples': 64,
'batch_size': 1
}
num_pos = config('img_height') * config('img_width') * config('num_ray_samples')
input_features = 6 * config('pos_embed') + 3
train_ds, valid_ds = load_tiny_nerf(pos_embed=config('pos_embed'),
num_ray_samples=config('num_ray_samples'),
save_path='tiny_nerf.npz',
validation_split=0.2,
backend='tensorflow')
train_ds = train_ds.batch(config('batch_size')).prefetch(tf.data.AUTOTUNE)
valid_ds = valid_ds.batch(config('batch_size')).prefetch(tf.data.AUTOTUNE)
model = deepvision.models.NeRFMedium(input_shape=(num_pos, input_features),
backend='tensorflow')
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3),
loss=tf.keras.losses.MeanSquaredError())
callbacks = (tf.keras.callbacks.ReduceLROnPlateau())
history = model.fit(train_ds,
epochs=50,
validation_data=valid_ds,
callbacks=callbacks)
در Nvidia GTX1660Super، آموزش با 32 جاسازی موقعیتی و 64 نمونه پرتو 1 دقیقه در هر دوره طول می کشد، اما تنظیمات کوچکتر، مانند 8 تا 16 جاسازی موقعیتی و 32 نمونه اشعه ممکن است به 7 ثانیه در هر دوره نیاز داشته باشد.
Epoch 1/50
84/84 (==============================) - 65s 746ms/step - loss: 0.0603 - psnr: 12.6432 - val_loss: 0.0455 - val_psnr: 13.7601 - lr: 0.0010
...
Epoch 50/50
84/84 (==============================) - 55s 658ms/step - loss: 0.0039 - psnr: 24.1984 - val_loss: 0.0043 - val_psnr: 23.8576 - lr: 0.0010
بعد از تقریباً یک ساعت، روی یک GPU تجاری واحد، مدل به 24 PSNR دست می یابد. نکته ای که در مورد NeRF ها وجود دارد این است که – هر چه مدت زمان بیشتری تمرین کنید، به نمایش تصاویر اصلی نزدیک تر می شود، به این معنی که معمولاً با افزایش زمان تمرین، معیارها را در طول زمان افزایش خواهید داد. داشتن یک کمک می کند ReduceLROnPlateau
پاسخ به تماس برای کنترل کاهش نرخ یادگیری برای تنظیم دقیق نتایج در نزدیکی پایان آموزش.
مدل دو معیار را گزارش می کند – loss
و psnr
. از دست دادن میانگین مربعات خطا برای هر پیکسل است و به عنوان یک تابع ضرر عالی برای NeRF ها عمل می کند، اما تفسیر آن دشوار است.
نسبت سیگنال به نویز اوج (PSNR) نسبت بین سیگنال (حداکثر قدرت یک سیگنال) و نویز (قدرت نویز که صحت سیگنال را خراب می کند) است که تصویر را کاهش می دهد. نسبت سیگنال به نویز پیک می تواند به عنوان یک مورد استفاده شود کیفیت تصویر متریک، و تفسیر آن برای انسان بسیار شهودی است.
در حال حاضر در PSNR 24، تصاویر نسبتاً واضح می شوند و NeRF ها می توانند به PSNR های بیش از 40 برسند. روی به TinyNeRF زمان کافی برای آموزش داده شده است.
تجسم خروجی ها
شبکه یک تانسور شکل خروجی می دهد (batch_size, 640000, 4)
که در آن کانال ها نشان دهنده RGB و تراکم هستند و 640000 نقطه صحنه را رمزگذاری می کند. برای نشان دادن اینها به عنوان تصویر، می خواهیم تانسور را به شکلی تغییر دهیم (batch_size, img_height, img_width, num_ray_samples, 4)
و سپس 4 کانال را به RGB و sigma و process آنها را در یک تصویر (و به صورت اختیاری، یک نقشه عمق / دقت).
به طور خاص، کانال های RGB از طریق a عبور می کنند سیگموئید فعال سازی، در حالی که کانال سیگما از طریق a عبور می کند ReLU فعال سازی، قبل از پردازش بیشتر و کاهش به یک تانسور شکل (batch_size, img_height, img_width, rgb_channels)
، و دو تانسور شکل (batch_size, img_height, img_width, depth_channel)
و (batch_size, img_height, img_width, accuracy)
.
برای ساختن این process راحت تر، ما می توانیم استفاده کنیم nerf_render_image_and_depth_tf()
تابع از volumetric_utils
، که مدل را برای پیشبینی RGB و سیگما از ورودیها میپذیرد و دستهای از تصاویر، نقشههای عمق و نقشههای دقت را برمیگرداند:
import matplotlib.pyplot as plt
from deepvision.models.volumetric.volumetric_utils import nerf_render_image_and_depth_tf
for batch in train_ds.take(5):
(images, rays) = batch
(rays_flat, t_vals) = rays
image_batch, depth_maps, _ = nerf_render_image_and_depth_tf(model=model,
rays_flat=rays_flat,
t_vals=t_vals,
img_height=config('img_height'),
img_width=config('img_width'),
num_ray_samples=config('num_ray_samples'))
fig, ax = plt.subplots(1, 2)
ax(0).imshow(tf.squeeze(image_batch(0)))
ax(1).imshow(tf.squeeze(depth_maps(0)))
در اینجا، ما 5 دسته (هر کدام با یک تصویر) و نقشه های عمق آنها را ترسیم می کنیم.
در طول آموزش، خود مدل متکی است روی را nerf_render_image_and_depth_tf()
تابع تبدیل پیش بینی ها به تصاویر و محاسبه میانگین مربعات خطا و PSNR برای نتایج. اجرای این کد نتیجه می دهد:
نتیجه
در این راهنما – ما برخی از عناصر کلیدی Neural Radiance Fields را بهعنوان مقدمهای کوتاه بر موضوع، و سپس بارگیری و آمادهسازی مجموعه داده TinyNeRF در TensorFlow، با استفاده از tf.data
و آموزش یک مدل NeRF با اکوسیستم Keras و DeepVision.
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-01 17:26:03