0

Моя цель - создать нейронную сеть с одним скрытым слоем (с активацией ReLU), которая может аппроксимировать простую одномерную функцию квадратного корня. я реализовал сеть с NumPy, также сделал чек градиента, кажется, что все в порядке, за результат, за исключением: по какой-то причине я могу получить только линейные аппроксимации, например: noisy sqrt approxНейронная сеть для одномерной регрессии с numpy дает только линейные результаты

попытался изменить гиперпараметры, без любой успех. Есть идеи?

import numpy as np 

step_size = 1e-6 
input_size, output_size = 1, 1 
h_size = 10 
train_size = 500 
x_train = np.abs(np.random.randn(train_size, 1) * 1000) 
y_train = np.sqrt(x_train) + np.random.randn(train_size, 1) * 0.5 

#initialize weights and biases 
Wxh = np.random.randn(input_size, h_size) * 0.01 
bh = np.zeros((1, h_size)) 
Why = np.random.randn(h_size, output_size) * 0.01 
by = np.zeros((1, output_size)) 

for i in range(300000): 
    #forward pass 
    h = np.maximum(0, np.dot(x_train, Wxh) + bh1) 
    y_est = np.dot(h, Why) + by 

    loss = np.sum((y_est - y_train)**2)/train_size 
    dy = 2 * (y_est - y_train)/train_size 

    print("loss: ",loss) 

    #backprop at output 
    dWhy = np.dot(h.T, dy) 
    dby = np.sum(dy, axis=0, keepdims=True) 
    dh = np.dot(dy, Why.T) 

    #backprop ReLU non-linearity  
    dh[h <= 0] = 0 

    #backprop Wxh, and bh 
    dWxh = np.dot(x_train.T, dh) 
    dbh = np.sum(dh1, axis=0, keepdims=True) 

    Wxh += -step_size * dWxh 
    bh += -step_size * dbh 
    Why += -step_size * dWhy 
    by += -step_size * dby 

Edit: Кажется, проблема заключалась в отсутствии нормализации и данные будучи отличны от нуля в центре. После применения этих преобразований на подготовку данных, мне удалось получить следующий результат: noisy sqrt2

ответ

1

я могу получить свой код, чтобы получить вид кусочно-линейной аппроксимации:

Piecewise linear approximation to $y=\sqrt(x)$

если ноль -Центр и нормализуют свои входные и выходные диапазоны:

# normalise range and domain 
x_train -= x_train.mean() 
x_train /= x_train.std() 
y_train -= y_train.mean() 
y_train /= y_train.std() 

Участок производится следующим образом:

x = np.linspace(x_train.min(),x_train.max(),3000) 
y = np.dot(np.maximum(0, np.dot(x[:,None], Wxh) + bh), Why) + by 
import matplotlib.pyplot as plt 
plt.plot(x,y) 
plt.show() 
+0

Включена нормализация, и она работает очень хорошо, действительно, спасибо. Можете ли вы дать некоторую интуицию, почему так важно, чтобы наш набор данных был нормализован и нулевой? – dlpyth

+1

Мое предположение, что ваши ReLUs застревают в вашем полном наборе данных. Если скрытые активации всегда одинаковы, независимо от входного шаблона, выход будет линейной функцией. Убедившись, что некоторые из ваших входов отрицательные, я полагаю, что у вас больше шансов иметь некоторые скрытые единицы и некоторые из них, так что разные наборы скрытых модулей могут изучать разные части функции sqrt. – wildwilhelm