Resumo do primeiro curso de aprendizado profundo de Wu Enda

 

O núcleo do estudo aprofundado do Sr. Wu Enda do primeiro curso é entender as três etapas de propagação para frente, cálculo de custo e propagação de volta (na verdade, contanto que você se acalme e aplique as fórmulas no tutorial sobre o rascunho, não será difícil), o professor Wu Enda explicou principalmente esses conceitos por meio de regressão logística

A primeira é como processar as amostras de entrada. Para uma imagem colorida, existem três canais de RGB. No computador, os valores de pixel nos canais são armazenados por meio de três matrizes. Por exemplo, na imagem colorida de dpi na figura acima, o número de pixels é o seguinte 64\vezes 64 : 64\vezes 64\vezes 3=12288Precisamos usar um vetor de recursos x para representar esta imagem. A dimensão do vetor de recursos é o número de pixels na imagem, ou seja, n_{x}isso é uma amostra. Para m amostras, uma matriz bidimensional pode ser definida e os autovalores de comportamento são listados como O número de amostras, expresso em código como este

image = np.array(imageio.imread(r"cat.jpg"))  #读取图片
num_px=64    #图片大小
my_image = np.array(Image.fromarray(image).resize((num_px, num_px),Image.ANTIALIAS)) #将图片重塑成指定大小num_px*num_px,Image.ANTIALIAS表示为高质量
my_image = my_image.reshape((1, num_px * num_px * 3)).T   #将特征向量的shape转化为(1,num_px * num_px * 3).T

 Com a entrada já podemos construir nossa rede neural, tome como exemplo uma rede neural de duas camadas, ou seja, existe apenas uma camada oculta.

w600

Suponha que existam m amostras na camada de entrada e o tamanho de uma única amostra seja num_px*num_px, então o tamanho da camada de entrada é ( , n^{[0]}m)=(num_px*num_px*3,m), há n^{[1]}um neurônio em a camada oculta e n^{[2]}um neurônio na camada de saída, primeiro você precisa inicializar o peso W e viés b:

def param_init(layer_num,layer_dims):
    W = []
    b = []
    for i in range(layer_num):
        sW = np.random.randn(layer_size[i+1],layer_size[i])
        sb = np.zeros((layer_size[i+1],1))
        W.append(sW)
        b.append(sb)
    return W,b

Ou você pode colocar o valor inicializado em um dicionário:

def init_parameters(layer_dims):
    parameters = {}
    for i in range(1,len(layer_dims)):
        parameters['W'+str(i)] = np.random.randn(layer_dims[i],layer_dims[i-1])
        parameters['b'+str(i)] = np.zeros((layer_dims[i],1))
            
    assert(parameters['W'+str(i)].shape == (layer_dims[i],layer_dims[i-1]))
    assert(parameters['b'+str(i)].shape == (layer_dims[i],1))
    
    return parameters

W^{[1]}A dimensão de is ( n^{[1]}, n^{[0]}), b^{[1]}a dimensão de is ( n^{[1]}, 1), W^{[2]}a dimensão de is ( n^{[2}, n^{[1]}) e a dimensão de is ( , 1), W^{[1]}e a derivação de três processos é realizada abaixo (preguiçoso, veja o figura abaixo):n^{[2]}

  • Código de propagação para frente:

def forward_propagation(X,W,b,layer_num,layer_size,activate_fun):
    Z = []
    A = []
    for i in range(layer_num):
        if i==0:
            sZ = np.dot(W[i],X)+b[i]
        else:
            sZ = np.dot(W[i],A[i-1])+b[i]
        sA = activate_fun[i](sZ)
        Z.append(sZ)
        A.append(sA)
    return Z,A
  • Calcule o custo:

def compute_cost(prediction,Y):
    m = Y.shape[1]
    logprobs = np.multiply(np.log(prediction+1e-5), Y) + np.multiply((1 - Y), np.log(1 - prediction+1e-5))
    cost = (-1./m)*np.nansum(logprobs)
    cost = np.squeeze(cost)
    return cost
  • Retropropagação (porque a função de ativação da camada de saída é uma função sigmóide, o dZ da última camada é calculado diretamente, ou seja dZ[l-1]=A[l-1]-Y):

def backward_propagation(l,X,Y,W,Z,A,derivate_function):
    dZ = list(range(l))
    dA = list(range(l))
    dW = list(range(l))
    db = list(range(l))
    m = Y.shape[1]
    
    dZ[l-1] = A[l-1] - Y
    for i in range(l-1,-1,-1):
        if i>0:
            dW[i] = (1/m)*np.dot(dZ[i],A[i-1].T)
        else:
            dW[i] = (1/m)*np.dot(dZ[i],X.T)
        db[i] = (1/m)*np.sum(dZ[i],axis=1,keepdims=True)
        dA[i-1] = np.dot(W[i].T,dZ[i])
        dZ[i-1] = np.multiply(dA[i-1],np.int64(A[i-1]>0))

    return dW,db
  • Atualizar pesos e vieses:

def update_param(W,b,dW,db,learning_rate=0.5):
    for i in range(len(W)):
        W[i] = W[i] - learning_rate*dW[i]
        b[i] = b[i] - learning_rate*db[i]
    return W,b
  •  resultado da previsão:

def predict(X,W,b,layer_num,layer_size,activate_fun):
    
    # Computes probabilities using forward propagation, and classifies to 0/1 using 0.5 as the threshold.
    ### START CODE HERE ### (≈ 2 lines of code)
    Z,A = forward_propagation(X,W,b,layer_num,layer_size,activate_fun)
    predictions = np.round(A[layer_num-1])
    
    ### END CODE HERE ###
    
    return predictions

A ideia do código acima é completar um programa que possa construir qualquer número de camadas e qualquer número de neurônios em cada camada, e então usar o dever de casa da terceira semana do primeiro curso do primeiro curso de deep learning por Sr. Wu Enda para verificar.

X,Y = load_planar_dataset()

#使用逻辑回归的分类结果

clf = sklearn.linear_model.LogisticRegressionCV()
clf.fit(X.T,Y.T.ravel())

plot_decision_boundary(lambda x:clf.predict(x),X,Y.reshape(X[0,:].shape))

 Continuando, uma rede neural de quatro camadas (layer_num) é construída aqui, e o número de neurônios em cada camada da camada de entrada até a parte traseira é 6, 4, 4, 1, respectivamente:

layer_num = 4
layer_size = [X.shape[0],6,4,4,1]
activate_fun = [relu,relu,relu,sigmoid]
derivate_function = [derivate_relu,derivate_relu,derivate_relu,derivate_sigm]
W,b = param_init(layer_num,layer_size)
for i in range(20000):
    Z,A = forward_propagation(X,W,b,layer_num,layer_size,activate_fun)
    cost = compute_cost(A[layer_num-1],Y)
    dW,db = backward_propagation(layer_num,X,Y,W,Z,A,derivate_function)
    W,b = update_param(W,b,dW,db,learning_rate=0.07)
    if i%100==0:
        print("Cost after iteration %i: %f" % (i, cost))
# Print accuracy
predictions = predict(X,W,b,layer_num,layer_size,activate_fun)
print ('Accuracy: %d' % float((np.dot(Y, predictions.T) + np.dot(1 - Y, 1 - predictions.T)) / float(Y.size) * 100) + '%')
plot_decision_boundary(lambda x: predict(x.T,W,b,layer_num,layer_size,activate_fun), X, Y.reshape(X[0,:].shape))
plt.title("Decision Boundary for hidden layer size " + str(layer_num))

resultado:

A taxa de precisão é de 90%. Embora não seja alta, o modelo pode ser usado e, em seguida, outro conjunto de dados de duas categorias é usado para verificação adicional. Os resultados são os seguintes:

# Datasets
noisy_circles, noisy_moons, blobs, gaussian_quantiles, no_structure = load_extra_datasets()

datasets = {"noisy_circles": noisy_circles,
            "noisy_moons": noisy_moons,
            "blobs": blobs,
            "gaussian_quantiles": gaussian_quantiles}

### START CODE HERE ### (choose your dataset)
dataset = "noisy_moons"
### END CODE HERE ###

X, Y = datasets[dataset]
X, Y = X.T, Y.reshape(1, Y.shape[0])
  • Usando resultados de regressão logística

  •  Usando o resultado da rede neural acima:



 Como sou preguiçoso, não otimizei ainda mais o código, mas para o primeiro curso de aprendizado profundo, tem um efeito de aprendizado, ou uma palavra: apenas acalme-se e empurre devagar. sempre pode sair

Link do código anexado: https://download.csdn.net/download/weixin_42149550/11634095

Acho que você gosta

Origin blog.csdn.net/weixin_42149550/article/details/100113196
Recomendado
Clasificación