Нейронные сети не могут приблизиться к простому умножению и делению - PullRequest
0 голосов
/ 20 апреля 2019

Я пытаюсь приспособить простые нейронные сети с прямой связью к простым данным, где моя цель состоит в том, чтобы просто приблизить (a b c) / d

max_a=2
max_b = 3000
max_c=10
max_d=1

def generate_data(no_elements=10000):
    a = np.random.uniform(0,max_a,no_elements)
    b = np.random.uniform(1,max_b,no_elements)
    c=np.random.uniform(0.001,max_c,no_elements)
    d=np.random.uniform(0.00001,max_d,no_elements)
    df=pd.DataFrame({"a":a,"b":b,"c":c,"d":d})

    e=(df.a*df.b*df.c)/df.d
    df["e"]=e
    return(df)

так я генерируюdata

Затем я провел нормализацию данных

df = generate_data(5000)
np_df=df.iloc[:,:4]
means=np.mean(np_df,axis=0,keepdims=True)
stds=np.std(np_df,axis=0,keepdims=True)
x_train = (np_df-means)/stds
y_train = np_df[:,4]

и построил простую сеть Pytorch для регрессии, чтобы она предсказывала ' e '

class network_Regression(nn.Module):
    def __init__(self,layers):
        super(network_Regression, self).__init__()
        self.linear = nn.ModuleList()
        self.relu = nn.ModuleList()
        self.layers = layers
        for i in range(len(layers)-1):
            self.linear.append(nn.Linear(layers[i],layers[i+1]))
            if i+1 !=  len(layers)-1:
                self.relu.append(nn.ReLU())

    def forward(self,out):
        for i in range(len(self.relu)):
            out = self.linear[i](out)
            out = self.relu[i](out)
        out = self.linear[-1](out)
        return out


model = network_Regression([4,10,10,1])
criterion= nn.MSELoss()
optimizer=optim.Adam(model.parameters())

но когда я пытался обучить эти сети, пробовал эпохи от [1000 до 0,5M]

, он все равно не смог найти простую формулу ((a b c) / d) = e

Я пытался изменить различные уровни скрытого слоя, но потери были около 9 цифр

model.train()
num_epochs = 1000
loss_list=[]
for epoch in range(num_epochs):
    for batch_idx, (data, target) in enumerate(data_loader):
    #print(batch_idx)
        data, target = Variable(data), Variable(target)
        optimizer.zero_grad()
        output = model(data.float())
        loss = criterion(output, target.float())
        #print(batch_idx, loss.data[0])
        loss.backward()
        optimizer.step()
        if epoch >2:
            if batch_idx % 200 == 0:
                loss_list.append(loss.data.item())
        if batch_idx % 400 == 0:
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
            epoch, batch_idx * len(data), len(data_loader.dataset),
            100. * batch_idx / len(data_loader), loss.data.item()))

1 Ответ

0 голосов
/ 22 апреля 2019

Похоже, нейронные сети плохи в умножении и делении.

проверить это для деталей.

Таким образом, в основном я должен преобразовать свои данные в журнале, чтобы в приведенном выше случае приблизиться к ((a b c) / d) = e нейронной сети нужно вычислить простое сложение и вычитание. В соответствии с этим вопросом сложное умножение и деление становится ln (a) + ln (b) + ln (c) -ln (d) = ln (e) и сразу после получения обратного логарифма ln (д) эта идея хорошо работает.

...