C'est le troisième de la série.
La dernière fois, nous avons confirmé que le réseau neuronal peut être formé pour produire la moyenne et l'écart type de 10 nombres donnés.
Cette fois, je vais donner des données de distribution normale et tester si elle peut être entraînée pour sortir les trois paramètres qui sont à la base de la distribution normale.
La distribution normale ne comprend que trois paramètres. Ici, les trois paramètres sont µ, σ et k.
La formule générale de la distribution normale est
y=k \times\frac{1}{\sqrt{2\pi\sigma^2}}exp{\left(-\frac{
(x - \mu)^2
}{
2\sigma^2
}\right)}
est. Si vous regardez la formule, vous pouvez voir la signification des trois paramètres (au moins pour k et µ). Rendez cette expression disponible en python.
3-001.py
import math
#Définissez la fonction f.
f = lambda x,mu,sigma,k: k * (math.exp(-(x - mu)**2/2/sigma**2)) / math.sqrt(2*math.pi*sigma**2)
J'ai décidé de générer 50 000 éléments de données comme suit. Les trois paramètres sont des valeurs aléatoires avec une plage comme indiqué ci-dessous.
Tout d'abord, divisons la coordonnée x entre 0 et 10 en 100 et créons un ndarray.
3-002.py
import numpy as np
n = np.linspace(0, 10, 100)
Créons une donnée de forme d'onde pour que l'image sorte. Il n'y a pas de raison particulière, mais j'ai essayé de définir µ = 3, σ = 1 et k = 5.
3-003.py
import matplotlib.pyplot as plt
exampleData = []
for i in range(len(n)):
exampleData.append(f(n[i],3, 1, 5))
plt.title("Example of normal distribution")
plt.scatter(n, exampleData,label = "µ=3, σ=1, k=5",marker='.', s=20,alpha=1)
plt.legend(fontsize=14) #Afficher la légende
plt.xlabel("x")
plt.ylabel("y")
plt.show()
100 données numériques sont jetées dans NN. J'ai utilisé un nuage de points ici pour que je puisse voir qu'il s'agit de données discrètes.
Maintenant, générons les données qui sont réellement utilisées pour l'entraînement. Faites deux listes pour stocker les données d'entraînement et les données de réponse correctes.
3-004.py
p = []
y = []
for kkk in range(50000):
mu1 = np.random.rand()*4 + 3 #Déterminez la valeur au hasard. 3 à 7
si1 = np.random.rand()*1.9 + 0.1 #Déterminez la valeur au hasard. 0.de 1 à 2
k1 = np.random.rand()*9.5 + 0.5 #Déterminez la valeur au hasard. 0.5 à 10
y .append(mu1)#Enregistrer les bonnes réponses
y .append(si1)#Enregistrer les bonnes réponses
y .append(k1)#Enregistrer les bonnes réponses
for i in range(len(n)):
p.append(f(n[i],mu1, si1, k1))#Passez la valeur de coordonnée x et trois paramètres à la fonction définie f et stockez la valeur de retour dans la liste p.
Modifiez la liste en ndarray, puis modifiez la forme pour la jeter dans le NN.
3-005.py
#Faites-en un ndarray et changez la forme.
t = np.array(p)
t = t.reshape(50000,len(n))
label = np.array(y)
label = label.reshape(50000,3)
Divisez les données dans la première moitié 40000 et la seconde moitié 10000. La première moitié est pour la formation et la seconde moitié est pour l'évaluation.
3-006.py
#Formation au premier semestre 40 000. Évalué dans la seconde moitié de 10000.
d_training_x = t[:40000,:]
d_training_y = label[:40000,:]
d_test_x = t[40000:,:]
d_test_y = label[40000:,:]
Je ne sais pas si ce qui suit est optimal, mais j'ai connecté 5 couches entièrement connectées. Réduisez progressivement le nombre de sorties pour que 3 nombres soient émis à la fin.
3-007.py
import keras
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import Adam
batch_size = 128 #Entraînez 128 données d'entraînement à la fois
epochs = 20 #Combien de tours pour apprendre les données d'entraînement
model = Sequential()
model.add(Dense(100, activation='linear', input_shape=(len(n),)))
model.add(Dense(100, activation='tanh'))
model.add(Dense(40, activation='linear'))
model.add(Dense(20, activation='tanh'))
model.add(Dense(3, activation='linear'))
#Descente de gradient probabiliste Adam
optimizer = Adam(lr=0.001, beta_1=0.9, beta_2=0.999)
#Erreur moyenne au carré de la fonction de perte
model.compile(loss='mean_squared_error',optimizer=optimizer)
model.summary()##Vérifiez la forme de NN
La formation a commencé. La valeur de retour de fit () est stockée dans l'historique des variables et la progression de l'apprentissage est représentée graphiquement plus tard.
3-008.py
#Apprentissage
history = model.fit(d_training_x, d_training_y,
batch_size=batch_size,
epochs=100,
verbose=1,# verbose..Redondant, bavard
validation_data=(d_test_x, d_test_y))
Représentons graphiquement la progression de l'apprentissage.
3-009.py
#Dessiner un graphique
import matplotlib.pyplot as plt
plt.plot(history.history['val_loss'], label = "val_loss")
plt.plot(history.history['loss'], label = "loss")
plt.legend() #Afficher la légende
plt.title("Can NN learn to calculate normal distribution?")
plt.xlabel("epoch")
plt.ylabel("Loss")
plt.show()
L'axe vertical Loss est l'erreur de somme des carrés de la différence entre les données de réponse correctes et les données de sortie du NN. Deux graphiques sont tracés: la perte pour les données utilisées pour l'entraînement et val_loss lorsqu'elle est prédite à l'aide des données d'évaluation.
Donnons des données d'évaluation au NN formé.
3-010.py
#Donner des données au NN formé
inp = d_test_x[:200,:]
out = d_test_y[:200,:]
pred = model.predict(inp, batch_size=1)
Représentons graphiquement la sortie.
3-011.py
plt.title("Can NN learn to calculate normal distribution?")
plt.scatter(out[:,0], pred[:,0],label = "µ",marker='.', s=20,alpha=0.3)
plt.scatter(out[:,1], pred[:,1],label = "σ",marker='.', s=20,color="green",alpha=0.3)
plt.scatter(out[:,2], pred[:,2],label = "k",marker='.', s=20,color="red",alpha=0.3)
plt.legend(fontsize=14) #Afficher la légende
plt.xlabel("expected value")
plt.ylabel("prediction")
plt.show()
Vous pouvez voir que la valeur de réponse correcte et la sortie de NN sont assez proches. En d'autres termes, j'ai pu apprendre correctement.
C'est difficile à voir car il se chevauche, mais les trois paramètres sont affichés assez correctement. C'est fait! Série 1ère préparation Moyenne et écart type de la deuxième série Série 3e distribution normale Série 4e yen