import pickle import numpy as np #dados estão armezenados como um objeto python em disco usando pickle with open('data.pkl', 'rb') as f: data = pickle.load(f) data['X'].shape #(5000,400) data['y'].shape #(5000,1)
# seleciona 1 aleatoriamente ex = data['X'][np.random.randint(5000),] # e mostra a imagem plt.imshow(ex.reshape(20,20).T,cmap=plt.get_cmap('Greys'))
#dados estão armezenados como um objeto python em disco usando pickle with open('weights.pkl', 'rb') as f: weights = pickle.load(f) weights['Theta1'].shape #(25, 401) weights['Theta2'].shape #(10,26)
from scipy.special import expit #função sigmoide vetorizada def propagateForward(a0,Thetas): a = a0 for theta in Thetas: a = np.insert(a,0,1,axis=0) # adiciona o bias z = theta.dot(a) # z = theta * a a = expit(z) # a = g(z) return(a) def predict(example,Thetas): output = propagateForward(example,Thetas) return np.argmax(output,axis=0)
errors = [] for i in range(len(X)): #classes estão no intervalo 1..10 prediction = predict(data['X'][i,:],weights.values())+1 if (prediction != data['y'][i,0]): errors.append(i) print("Taxa de erro: ",(len(errors)*100)/5000,"%") # Taxa de erro: 2.48 %
predictions = predict(data['X'].T,weights.values())+1 errors = np.where(predictions != np.ravel(data['y'])) print("Taxa de erro: ",(len(np.ravel(errors))*100)/5000,"%")
J(θ)=2m1i=i∑m−ylog(hθ(x))−(1−y)log(1−hθ(x))+λj=1∑nθj
J(θ)=2m1i=i∑mk=1∑K−yklog(hθ(x))k−(1−yk)log(1−hθ(x))k+λl∑Li∑slj=1∑s(l+1)(Θijl)2
Vamos considerar a rede de 4 camadas (L=4)
Na última camada:
δj4=aj4−yj
Ou, em notação vetorial
δ4=a4−y
δ4 e o vetor de erros da camada 4
Com δ4 calculado, podemos determinar o erro das outras camadas como:
δ3δ2=(Θ3)⊺δ4.∗g′(z3)=(Θ2)⊺δ3.∗g′(z2)
g′(zk) pode ser computado como ak.∗(1−ak)
δ3δ2=(Θ3)⊺δ4.∗a3.∗(1−a3)=(Θ2)⊺δ3.∗a2.∗(1−a2)
∂Θijl∂J(Θ)∝ajl∗δil+1
Fazer uma passagem para a frente
Usar a saída da última camada e o rótulo real para calcular o erro
Propagar o erro para as camadas anteriores, calculando Δijl
Calular o gradiente
Podemos usar esse gradiente em algum algoritmo de otimização
def flattenParams(thetas): flattened = np.concatenate([theta.flatten() for theta in thetas]) shapes = [theta.shape for theta in thetas] return (flattened,shapes) def reshapeParams(flattened_array,shapes): begin = 0 thetas = [] for shape in shapes: end = begin+np.prod(shape) thetas.append(flattened_array[begin:end].reshape(shape)) begin = end return np.array(thetas)
import numpy as np from scipy.optimize import minimize from sklearn.preprocessing import OneHotEncoder def train(X,y,shapes, alpha=0.01,regularize=True,maxiter=1000): Y=OneHotEncoder().fit_transform(y).toarray() initial_theta = randomParams(shapes) res = minimize(cost_gradient_step, initial_theta, args=(shapes,X,Y,alpha,regularize), jac=True,method='L-BFGS-B',options={'maxiter': maxiter}) return(reshapeParams(res['x'],shapes)) shapes = np.array([(25, 401), (10, 26)]) thetas = train(data['X'],data['y'],shapes)
def cost(h,Y,thetas,alpha=0,regularize=True): m = len(Y) J = np.sum(np.multiply(-Y, np.log(h.T)) - np.multiply((1 - Y), np.log(1 - h.T)))/m if regularize: J += (float(alpha) / (2 * m)) * (np.sum([np.sum(np.power(t[:,1:],2)) for t in thetas])) return J def randomParams(shapes,epsilon_init=0.12): size = sum([np.prod(shape) for shape in shapes]) return np.random.random(size=size)*2*epsilon_init-epsilon_init
propagateForward
def propagateForward(a0,thetas): a = a0 a_values = [] for theta in thetas: a = np.insert(a,0,1,axis=0) #Add the bias unit a_values.append(a) z = theta.dot(a) a = expit(z) return(a_values,a)
def propagateBackward(as_values,h, thetas, Y, alpha=0, regularize=True): L = len(as_values) m = len(Y) delta = h.T-Y deltas = [np.dot(delta.T,as_values[L-1].T)/m] for i in reversed(range(1,L)): g_z = np.multiply(as_values[i],(1-as_values[i])) delta = np.multiply(np.dot(thetas[i].T,delta.T),g_z) deltas.append((np.dot(delta,as_values[i-1].T)[1:,])/m) deltas = list(reversed(deltas)) if regularize: for i in range(L): # não regulariza a0 deltas[i][:, 1:] = deltas[i][:, 1:] + ((thetas[i][:, 1:] * alpha) / m) return(deltas)
def cost_gradient_step(params,shapes,X,Y,alpha=0,regularize=True): thetas = reshapeParams(params,shapes) as_values, h = propagateForward(X.T,thetas) c = cost(h,Y,thetas,alpha,regularize) D = propagateBackward(as_values,h,thetas,Y,alpha,regularize) D,_ = flattenParams(D) return c, D