Topic: Rete Neurale  (Letto 149 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline nwtn

  • python unicellularis
  • *
  • Post: 2
  • Punti reputazione: 0
    • Mostra profilo
Rete Neurale
« il: Agosto 28, 2020, 19:39 »
Buongiorno,

sono nuovo del forum e non sono molto esperto.
ho bisogno di una rete neurale con 9 ingressi e un uscita. Cercando su internet ho riadattato il codice che trovate sotto.

funziona abbastanza bene modificando le dimensioni delle matrici per il caso 1 input, 1 output  con la funzione seno.

oggi ho provato a farla funzionare con una combinazione lineare di 9 variabili ma non giunge a convergenza.

Potete controllarla e dirmi cosa sbaglio in modo semplice?

grazie mille



import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import preprocessing
from sklearn.preprocessing import MinMaxScaler
from sklearn import metrics
from sklearn.metrics import confusion_matrix
import itertools


def Relu(Z):
    return np.maximum(0,Z)

def Sigmoid(Z):
    return 1/(1+np.exp(-Z))


def dRelu(x):
    x[x<=0] = 0
    x[x>0] = 1
    return x
def dSigmoid(Z):
    s = 1/(1+np.exp(-Z))
    dZ = s * (1-s)
    return dZ

class dlnet:
    def __init__(self, x, y):
        self.X=x
        self.Y=y
        self.Yh=np.zeros((1,self.Y.shape[1]))
        self.L=2
        self.dims = [9, 200, 1]
        self.param = {}
        self.ch = {}
        self.grad = {}
        self.loss = []
        self.lr=0.06
        self.sam = self.Y.shape[1]


    def nInit(self):
            np.random.seed(1)
            self.param['W1'] = np.random.randn(self.dims[1], self.dims[0]) / np.sqrt(self.dims[0])
            self.param['b1'] = np.zeros((self.dims[1], 1))
            self.param['W2'] = np.random.randn(self.dims[2], self.dims[1]) / np.sqrt(self.dims[1])
            self.param['b2'] = np.zeros((self.dims[2], 1))
            return


    def Sigmoid(Z):
        return 1/(1+np.exp(-Z))
    def Relu(Z):
        return np.maximum(0,Z)
    def forward(self):
            Z1 = self.param['W1'].dot(self.X) + self.param['b1']
            A1 = Relu(Z1)
            self.ch['Z1'],self.ch['A1']=Z1,A1

            Z2 = self.param['W2'].dot(A1) + self.param['b2']
            A2 = Sigmoid(Z2)
            self.ch['Z2'],self.ch['A2']=Z2,A2
            self.Yh=A2
            loss=self.nloss(A2)
            return self.Yh, loss


    def nloss(self,Yh):
            loss = (1./self.sam) * (-np.dot(self.Y,np.log(Yh).T) - np.dot(1-self.Y, np.log(1-Yh).T))
            return loss



    def dRelu(x):
        x[x<=0] = 0
        x[x>0] = 1
        return x
    def dSigmoid(Z):
        s = 1/(1+np.exp(-Z))
        dZ = s * (1-s)
        return dZ
    def backward(self):
            dLoss_Yh = - (np.divide(self.Y, self.Yh ) - np.divide(1 - self.Y, 1 - self.Yh))

            dLoss_Z2 = dLoss_Yh * dSigmoid(self.ch['Z2'])
            dLoss_A1 = np.dot(self.param["W2"].T,dLoss_Z2)
            dLoss_W2 = 1./self.ch['A1'].shape[1] * np.dot(dLoss_Z2,self.ch['A1'].T)
            dLoss_b2 = 1./self.ch['A1'].shape[1] * np.dot(dLoss_Z2, np.ones([dLoss_Z2.shape[1],1]))

            dLoss_Z1 = dLoss_A1 * dRelu(self.ch['Z1'])
            dLoss_A0 = np.dot(self.param["W1"].T,dLoss_Z1)
            dLoss_W1 = 1./self.X.shape[1] * np.dot(dLoss_Z1,self.X.T)
            dLoss_b1 = 1./self.X.shape[1] * np.dot(dLoss_Z1, np.ones([dLoss_Z1.shape[1],1]))

            self.param["W1"] = self.param["W1"] - self.lr * dLoss_W1
            self.param["b1"] = self.param["b1"] - self.lr * dLoss_b1
            self.param["W2"] = self.param["W2"] - self.lr * dLoss_W2
            self.param["b2"] = self.param["b2"] - self.lr * dLoss_b2




    def gd(self,X, Y, xtot,ytot, iter = 3000):
            np.random.seed(1)

            self.nInit()

            for i in range(0, iter):

                for kk in range(0, xtot.shape[0]):



                    self.X= xtot.iloc[kk:kk+1,:].values.transpose()
                    self.Y=ytot.iloc[kk:kk+1,:].values.transpose()

                    Yh, loss=self.forward()
                    self.backward()

                if i % 5 == 0:
                    print ("Cost after iteration %i: %f" %(i, loss))
                    self.loss.append(loss)

            nn.test2(xtot,ytot)

            return


    def test(self):
        print(self.Yh)
        self.X=pd.DataFrame([[np.radians(30)]])
        self.X=self.X.values.transpose()
        self.forward()
        print(self.Yh)





    def test2(self, xtot,ytot):


        uscite=pd.DataFrame()

        for kk in range(0, xtot.shape[0]):

            self.X= xtot.iloc[kk:kk+1,:].values.transpose()
            self.Y=ytot.iloc[kk:kk+1,:].values.transpose()

            Yh, loss=self.forward()
            uscite=uscite.append([[self.Y[0][0]]+[self.Yh[0][0]]])

        uscite.to_csv('risultato_neurale.csv')


df = pd.DataFrame(1/100*np.random.randint(0,100,size=(100, 9)))
results=pd.DataFrame()
for contatore in range (0,df.shape[0]+0):
    ff=np.dot([[4,3,2,9,-3,-4,2,-5,2]],df.iloc[contatore:contatore+1,:].values.transpose())[0][0]
    results=results.append([[ff]])
results=results/(max(results.max()[0],-results.min()[0])*1.2)
print((max(results)*1.2))

xtot=df
ytot=results

#####################################################


x=xtot.iloc[0:1,:].values.transpose()
y=ytot.iloc[0:1,:].values.transpose()



##
##x=[[np.radians(20),np.radians(40),np.radians(70)]])

##x=np.array([[.1,.2]])
##y=np.array([[.1,.2]])

nn = dlnet(x,y)
nn.gd(x, y, xtot,ytot, iter = 15000)

print('finito1')

##nn.test()
##print('finito2')

Offline caronte

  • python erectus
  • ***
  • Post: 236
  • Punti reputazione: 0
    • Mostra profilo
Re:Rete Neurale
« Risposta #1 il: Agosto 29, 2020, 22:15 »
ciao
scusami ma hai almeno qualche nozione di base di "reti "?
hai capito (dubito) quello che hai scritto e cosa fa? invece di quelloc h dovrebbe fare?

hai fatto un bel po di casino...
adesso in linea di massiama scopo di puro comprendonio, scrivere un neural net in puro Python potrebbe andar anche bene;
ma in casi reali NON si fa e non serve assolutamente farlo;
detto cio'
li tu ti vai a calcolare le varie derivate (in chain rules) a mano...
definisci a doppio le varie funzioni di attivazione...
poi a quanto vedo applichi una cross-entropy loss (la tua nloss) ad un problema di regressione...??? chiaramente non sai bene quello che stai facendo;
ma poi alla fine hai visto che array passi alla classe che ti dovrebbe inizializzare la tua rete neurale?
quelal 'x' e quella 'y'??? cioe' come target stai passando praticamente uno scalare...e ti chiedi perche' non converge??

comincia a leggerti qualcosa sulle basi e poi se vuoi ne riparliamo
saluti

Offline nwtn

  • python unicellularis
  • *
  • Post: 2
  • Punti reputazione: 0
    • Mostra profilo
Re:Rete Neurale
« Risposta #2 il: Settembre 01, 2020, 07:34 »
ciao
ho qualche nozione, ma non so bene come riprodurla su python.

hai scritto che di solito non si costruisce da 0. Mi puoi indicare una libreria o una funziona già disponibile e semplice da usare?
Ho  tratto il mio codice da un esempio su internet e l'ho modificato leggermente. Trovi sotto la fonte

guarda qui:
https://towardsdatascience.com/coding-a-2-layer-neural-network-from-scratch-in-python-4dd022d19fd2
https://github.com/javismiles/Deep-Learning-predicting-breast-cancer-tumor-malignancy

grazie per i tuoi commenti ma alcuni non li ho capiti.:


definisci a doppio le varie funzioni di attivazione... ||| cosa intendi?
poi a quanto vedo applichi una cross-entropy loss (la tua nloss) ad un problema di regressione...  ||| era quella applicata nell'esempio. Sceglierne una invece di un altra cambia drasticamente l'applicabilità del codice?

alla seguente riga

nn.gd(x, y, xtot,ytot, iter = 15000)

x e y sono array.
l'ho appena controllato anche facendo il debug e passando il mouse sopra x e y. Che cosa intendi?

grazie







Offline caronte

  • python erectus
  • ***
  • Post: 236
  • Punti reputazione: 0
    • Mostra profilo
Re:Rete Neurale
« Risposta #3 il: Settembre 03, 2020, 14:20 »
allora, ti lascio un esempio molto basilare di rete con soli due layers; (ammesso che tu abbia tutte le dipendenze installate, vedi gli imports)
uso un modello sequenziale in keras, molto semplice da scrivere; per net piu flessibili sceglieresti un modello funzionale, o direttamente tensorflow ,  Pytorch... e amici cari..

in base ai dati che hai postato tu, si tratta di una regressione, quindi i valori della dipendente sono float;
ecco perche' invece della cross entropy userai una semplice "mean squared error"..ma potresti usarne altre;
come potrai vedere dai risultati, chiaramente il modello non converge (vedi i valori della val_loss) perche' chiaramente tutte le variabili comprese le indipendenti, sono random,
quindi non esiste alcuna correlazione tra loro e la dipendente (target); con dati reali chiaramente il risultato cambia;
come vedi  forward e backpropag sono eseguite direttamente dal framework una volta definito il modello e compilato;

ora questo e' solo u assaggio, chiaramente sono molte le cose da valutare prima di costruire una rete', ma di certo non posso farti un tutorial;
leggiti per cominciare un buon libro, tipo "Deep Learning with Python" che appunto usa Keras;

saluti

edit:
"x e y sono array.
l'ho appena controllato anche facendo il debug e passando il mouse sopra x e y. Che cosa intendi?"

si, sono tensori ma hai controllato le rispettive dimensioni?...


import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras import layers
import tensorflow as tf

# random data
df = pd.DataFrame(1/100*np.random.randint(0, 100, size=(100, 9)))
targets = np.random.rand(100)

# splitta i dati in train e valid, in maniera da testare succesivamente il mdoello su dati non presenti nel train set
x_train, x_valid, y_train, y_valid = train_test_split(df, targets, test_size=0.2, random_state=123)


# definiamo optimiser e logit
mse = tf.keras.losses.MeanSquaredError()
optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)


# inizializza il modello sequenziale
model = Sequential()
model.add(layers.Dense(10, input_dim=df.shape[1], kernel_initializer='normal', activation='relu'))
model.add(layers.Dense(1, activation='linear'))

model.summary()

# compilazione
model.compile(loss=mse, optimizer=optimizer, metrics=['mse'])

#  training
model.fit(x_train, y_train, epochs=10, batch_size=50, verbose=1, validation_split=0.2)

# predictions on valid test
y_preds = model.predict(x_valid)

score = mean_squared_error(y_valid, y_preds)
« Ultima modifica: Settembre 04, 2020, 14:33 da caronte »