В настоящее время я пытаюсь выполнить обратное распространение для функции f (x, W) = || sigmoid (Wx) || ^ 2, где W - матрица 3x3, x - матрица 3x1, а sigmoid выполняет поэлементно сигмовидная функция (1/1-е ^ х). Вот мой код:
import numpy as np
from math import *
#forward pass
W = np.array([[0.1, 0.5, 0.2],[-0.3, 0.8, 0.5],[0.5,0.2,0.3]])
x = np.array([[0.2],[0.4],[0.1]])
q = np.dot(W,x)
sig = np.round(1 / (1 + np.exp(-q)), 3)
loss = np.round(np.sum(sig**2), 3)
f = loss
print('type W:',type(W))
print('shape W:',W.shape)
print('\ntype x:',type(x))
print('shape x:',x.shape)
print('\ntype q:',type(q))
print('shape q:',q.shape)
print('\ntype sig:',type(sig))
print('shape sig:',sig.shape)
print('\ntype Loss:',type(loss))
print('shape Loss:',loss.shape)
#print forward pass values
print('\nValues of forward pass:')
print('q:\n', np.round(q, 3))
print('sig:\n', np.round(sig, 3))
print('L2 Loss:',f)
#backward pass
#backprop f = loss: df/loss = 1
df_df = 1
#backprop loss = np.sum(sig*sig): (dloss/dsig)(df/df)
df_dsig = 2*sig*df_df
#backprop sig = 1 / 1 + np.exp(-q): (dsig/dq)(df/dsig)
dsig_dq = ((1 - sig)*sig)*df_dsig
#backprop q = np.dot(W,x): (dq/dW)(dsig/dq)(df/dsig)
df_dW = np.round((x.T)*(dsig_dq)*(df_dsig), 3)
df_dx = np.round((2*W.T)*(dsig_dq)*(df_dsig), 3)
print('\ndf_dsig:', df_dsig)
print('\ntype df/dsig:', type(df_dsig))
print('shape df/dsig:', df_dsig.shape)
print('\ntype dsig/dq:', type(dsig_dq))
print('shape dsig/dq:', dsig_dq.shape)
print('\ntype df/dW:', type(df_dW))
print('shape df/dW:', df_dW.shape)
print('\ntype df/dx:', type(df_dx))
print('shape df/dx:', df_dx.shape)
print('\ntype dsig_dq*df_dsig:', type(dsig_dq*df_dsig))
print('shape dsig_dq*df_dsig:', (dsig_dq*df_dsig).shape)
#print backprop values
print('\nValues of backpropagation:')
print(np.round(df_dsig, 3))
print(np.round(dsig_dq, 3))
#printing gradient values of f(x,W) with respect to x_i and W_i,j
print('\nGradients of f(x,W) are:')
print('df/dW:\n', df_dW)
print('df/dx:\n', df_dx)
Это распечатывает:
type W: <class 'numpy.ndarray'>
shape W: (3, 3)
type x: <class 'numpy.ndarray'>
shape x: (3, 1)
type q: <class 'numpy.ndarray'>
shape q: (3, 1)
type sig: <class 'numpy.ndarray'>
shape sig: (3, 1)
type Loss: <class 'numpy.float64'>
shape Loss: ()
Values of forward pass:
q:
[[0.24]
[0.31]
[0.21]]
sig:
[[0.56 ]
[0.577]
[0.552]]
L2 Loss: 0.951
df_dsig: [[1.12 ]
[1.154]
[1.104]]
type df/dsig: <class 'numpy.ndarray'>
shape df/dsig: (3, 1)
type dsig/dq: <class 'numpy.ndarray'>
shape dsig/dq: (3, 1)
type df/dW: <class 'numpy.ndarray'>
shape df/dW: (3, 3)
type df/dx: <class 'numpy.ndarray'>
shape df/dx: (3, 3)
type dsig_dq*df_dsig: <class 'numpy.ndarray'>
shape dsig_dq*df_dsig: (3, 1)
Values of backpropagation:
[[1.12 ]
[1.154]
[1.104]]
[[0.276]
[0.282]
[0.273]]
Gradients of f(x,W) are:
df/dW:
[[0.062 0.124 0.031]
[0.065 0.13 0.033]
[0.06 0.121 0.03 ]]
df/dx:
[[ 0.062 -0.185 0.309]
[ 0.325 0.52 0.13 ]
[ 0.121 0.301 0.181]]
Я печатаю тип и форму всего, чтобы мне и всем было легче понять. Но, глядя на строки:
df_dW = np.round((x.T)*(dsig_dq)*(df_dsig), 3)
df_dx = np.round((2*W.T)*(dsig_dq)*(df_dsig), 3)
Здесь, безусловно, что-то не так. Я думаю, что по совпадению я получаю обе матрицы 3x3, но обратное распространение df_dW должно быть 3x3, а df_dx должно быть 3x1, как и исходные входные параметры. Я понятия не имею, почему я получаю их как 3х3, но я подумал, что это может быть в уравнении сиг. Я занимался этим так много часов, надеюсь, кто-нибудь может помочь мне здесь и исправить мою ошибку. Спасибо!