Обратное распространение в python: numpy Ошибка умножения массива? - PullRequest
0 голосов
/ 05 марта 2020

В настоящее время я пытаюсь выполнить обратное распространение для функции 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, но я подумал, что это может быть в уравнении сиг. Я занимался этим так много часов, надеюсь, кто-нибудь может помочь мне здесь и исправить мою ошибку. Спасибо!

...