در این قسمت چگونگی انجام محاسبات را به صورت بهینه تر از طریق پیاده سازی به روش برداری شده بررسی میکنیم. و میآموزیم که چرا شبکه های عصبی خوب هستند و چطور میتوانیم از آن ها برای یادگیری چیز های پیچیده و غیر خطی استفاده کنیم.
برای یادآوری عبارات زیر مثالی های شبکه های عصبی بودند:
$$ \begin{align*} a_1^{(2)} = g(\Theta_{10}^{(1)}x_0 + \Theta_{11}^{(1)}x_1 + \Theta_{12}^{(1)}x_2 + \Theta_{13}^{(1)}x_3) \newline a_2^{(2)} = g(\Theta_{20}^{(1)}x_0 + \Theta_{21}^{(1)}x_1 + \Theta_{22}^{(1)}x_2 + \Theta_{23}^{(1)}x_3) \newline a_3^{(2)} = g(\Theta_{30}^{(1)}x_0 + \Theta_{31}^{(1)}x_1 + \Theta_{32}^{(1)}x_2 + \Theta_{33}^{(1)}x_3) \newline h_\Theta(x) = a_1^{(3)} = g(\Theta_{10}^{(2)}a_0^{(2)} + \Theta_{11}^{(2)}a_1^{(2)} + \Theta_{12}^{(2)}a_2^{(2)} + \Theta_{13}^{(2)}a_3^{(2)}) \newline \end{align*} $$
ما قصد داریم متغیر جدیدی را به صورت $z_k ^{(j)}$ معرفی کنیم، که تابع $g$ آن را به عنوان ورودی میگیرد.
در مثال قبلی اگر متغیر $z$ را جایگزین کنیم: $$ \begin{align*}a_1^{(2)} = g(z_1^{(2)}) \newline a_2^{(2)} = g(z_2^{(2)}) \newline a_3^{(2)} = g(z_3^{(2)}) \newline \end{align*} $$
به عبارت دیگر، برای لایه $j=2$ و گره $k$ متغیر $z$ به این صورت خواهد بود: $$ z_k ^{(2)} = \Theta_{k,0} ^{(1)}x_0 + \Theta_{k,1} ^{(1)}x_1 + … + \Theta_{k,n} ^{(1)} x_n $$
به طور مثال: $$ z_1 ^{(2)} = \Theta_{1,0} ^{(1)}x_0 + \Theta_{1,1} ^{(1)}x_1 + \Theta_{1,2} ^{(1)} x_2 + \Theta_{1,3} ^{(1)}x_3 $$ $$ a_1 ^2 = g(z_1 ^{(2)} ) $$
ما میتوانیم محاسبات شبکه عصبی را به صورت برداری شده درآوریم، برای نمایش $x$ و $z^j$ به صورت برداری میتوانیم بنویسیم:
$$ \begin{align*}x = \begin{bmatrix}x_0 \newline x_1 \newline\cdots \newline x_n\end{bmatrix} & z^{(j)} = \begin{bmatrix}z_1^{(j)} \newline z_2^{(j)} \newline\cdots \newline z_n^{(j)}\end{bmatrix}\end{align*} $$
با تنظیم $x = a^{(1)}$ میتوانیم معادله را به صورت زیر بازنویسی کنیم: $$ z^{(j)} = \Theta^{(j - 1)} a^{(j - 1)} $$
ما ماتریس $\Theta^{(j - 1)}$ با ابعاد $ s_j \times (n+1) $ ($s_j$ تعداد گره های فعال ساز ما است) را با بردار $a^{(j - 1)}$ با ارتفاع $n+1$ ضرب میکنیم، که به عنوان خروجی به ما بردار $z^{(j)}$ را با ارتفاغ $s_j$ میدهد.
اکنون ما یک بردار از گره های فعال ساز مان از لایه j ام داریم: $$ a^{(j)} = g(z^{(j)}) $$
همانطور که میبینیم g، تابع سیگموئید را به صورت عنصر به عنصر به هر یک از اعضای بردار $z^{(j)}$ اعمال میکند.
و سپس میتوانیم واحد بایاس که برابر ۱ است را بعد از محاسبه $a^{(j)}$ اضافه کنیم. واحد بایاس همان $a_0 ^{(1)}$ است که برابر با ۱ میباشد.
قبل از محاسبه فرضیه نهایی اجازه دهید یک بردار $z$ دیگر را هم محاسبه کنیم: $$ z^{(j+1)} = \Theta^{(j)} a^{(j)} $$
این بردار را از طریق ضرب ماتریس تتا بعد از $\Theta^{(j - 1)}$ با مقادیر تمام گره های فعال سازی که به دست آورده ایم، محاسبه میکنیم.
آخرین ماتریس تتا یعنی $\Theta^{(j)}$ فقط یک ردیف خواهد داشت که در یک ستون $a^{(j)}$ ضرب میشود، به طوری که نتیجه آن یک عدد است.
سپس فرضیه نهایی خودمان را به این صورت نتیجه میگیریم:
$$ h_\theta(x) = a^{(j+1)} = g(z^{(j+1)}) $$
توجه داشته باشید که در این مرحله آخر، بین لایه $j$ و لایه $j+1$ دقیقا همان کاری انجام میهیم که در رگرسیون لجستیک انجام دادیم.
افزودن تمام این لایه های میانی در شبکه های عصبی به ما این امکان را می دهد که با ظرافت بیشتری فرضیه های غیر خطی جالب و پیچیده تری تولید کنیم!