C'est le deuxième de la série. Est-il possible de former un réseau de neurones (NN) pour produire la moyenne de certaines données numériques données? Et qu'en est-il de l'écart type? Faisons le.
Les problèmes que NN peut apprendre sont en gros divisés en «problèmes de classification» et «problèmes de retour». Cette fois, cela correspond au "problème de retour".
Faisons le. En général, il est difficile de préparer les données de formation pour la formation NN, mais cette fois, il est facile de se préparer.
Pour le moment, j'ai décidé de préparer 50 000 jeux de données de formation. Un ensemble se compose de 10 numéros. Les 10 nombres sont 10 nombres aléatoires qui suivent les données de distribution de la moyenne a et de l'écart type b en utilisant numpy aléatoire.normal (a, b, 10), mais ici a et b eux-mêmes sont aussi Il est généré par random.rand () de numpy.
Calculez "10 nombres" et "la moyenne et l'écart type de ceux-ci" et enregistrez-les d'abord dans la liste.
001.py
import numpy as np
trainDataSize = 50000 #Nombre d'ensembles de données à créer
dataLength = 10 #Nombre de données par ensemble
d = []#Remplissez 10 listes vides chacune.
average_std = []#La deuxième liste vide. Entrez deux nombres à la fois.
for num in range(trainDataSize):
xx = np.random.normal(np.random.rand(),np.random.rand(),dataLength)
average_std.append(np.mean(xx))
average_std.append(np.std(xx))
d.append(xx)
Une fois que vous avez une liste avec les 50000 ensembles, convertissez-la à nouveau en ndarray.
002.py
d = np.array(d) #Faites-en un ndarray.
average_std = np.array(average_std)#Faites-en un ndarray.
La raison pour laquelle je n'utilise pas ndarray depuis le début est qu'il est lent.
002.py
#Mauvais code. Car c'est tard.
d = np.array([])#Tableau numpy vide
for num in range(trainDataSize):
xx = np.random.normal(np.random.rand(),np.random.rand(),dataLength)
d = np.append(d,xx) #Ce processus est lent!
Le ndarray créé est celui dans lequel les données numériques sont lancées dans l'ordre. Modifiez maintenant la forme de la matrice.
003.py
d = d.reshape(50000,10)
average_std = average_std.reshape(50000,2)
Divisez l'ensemble de données 50000 en deux, 40000 ensembles pour la formation et 10 000 ensembles pour l'évaluation. Puisque nous ne considérerons pas d'hyper paramètres cette fois, nous le diviserons en deux parties.
004.py
#Formation au premier semestre 40 000. Évalué dans la seconde moitié de 10000.
d_training_x = d[:40000,:]
d_training_y = average_std[:40000,:]
d_test_x = d[40000:,:]
d_test_y = average_std[40000:,:]
Le point est
005.py
import keras
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import Adam
model = Sequential()
model.add(Dense(100, activation='tanh', input_shape=(10,)))#Il y a 10 emplacements d'entrée.
model.add(Dense(100, activation='tanh'))
model.add(Dense(40, activation='sigmoid'))
model.add(Dense(20, activation='sigmoid'))
model.add(Dense(2, activation='linear')) #Il y a deux emplacements de sortie.
#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() #Sortie de résumé NN
Enfin, je vais ajouter les données d'entraînement.
006.py
history = model.fit(d_training_x, d_training_y,
batch_size=256,#Les données d'entraînement sont lancées à la fois pour 256 ensembles de données.
epochs=20,#Combien de tours les données d'entraînement seront-elles répétées?
verbose=1,#verbeux est redondant, ce qui signifie à son tour «parler». S'il est défini sur 1, le processus de formation sera généré un par un.
validation_data=(d_test_x, d_test_y))
Ici, la valeur de retour de fit () est stockée dans l'historique des variables. En regardant l'historique des valeurs de retour avec type (), cela ressemble à un objet. Vérifions avec vars ().
007.py
type(history) # <class 'keras.callbacks.callbacks.History'>
vars(history)
#Beaucoup d'informations sont produites.
#En regardant les informations de sortie, les champs de l'objet historique sont les suivants.
# validation_data (liste)、
# model (Référence au modèle NN)、
# params (dictionnaire. la clé est'batch_size'、'epochs'、'steps'、'samples'、'verbose'、'do_validation'、'metrics')
# epoch (liste)、
# history (dictionnaire. la clé est'val_loss'、'loss')
#
#La clé de l'histoire est'val_loss'Quand'loss'Est.
#la perte est la perte de données d'entraînement. val_la perte est la perte des données à évaluer. Puisque le nom de la variable est ici histoire, histoire.history['val_loss']Vous pouvez accéder aux données de progression de la progression de l'apprentissage.
Tracons la progression de l'apprentissage.
008.py
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 average and standard deviation?")
plt.xlabel("epoch")
plt.ylabel(" Loss")
plt.show()
Le graphique que j'ai écrit avec ceci:
Vous pouvez voir que l'apprentissage a progressé, mais avec quelle précision avez-vous pu «calculer»? Jetez les 200 premiers ensembles de données d'évaluation dans le NN et tracez la sortie (axe vertical) par rapport aux résultats du calcul mathématique (axe horizontal).
009.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)
#Faire un graphique:moyenne
plt.scatter(out[:,0], pred[:,0])
plt.legend() #Afficher la légende
plt.title("average")
plt.xlabel("mathematical calculation")
plt.ylabel("NN output")
#Tracer une ligne. Si vous arrivez sur cette ligne, vous pouvez bien prévoir.
x = np.arange(-0.5, 2, 0.01)
y = x
plt.plot(x, y)
plt.show()
Vous pouvez voir que le «calcul» est fait avec une précision approximativement élevée. Alors qu'en est-il de l'écart type?
009.py
#Faire un graphique:écart-type
plt.scatter(out[:,1], pred[:,1])
plt.legend() #Afficher la légende
plt.title("standard deviation")
plt.xlabel("mathematical calculation")
plt.ylabel("NN output")
x = np.arange(0, 1.5, 0.01)
y = x
plt.plot(x, y)
plt.show()
Est-ce un endroit décent? La moyenne est meilleure, mais l'écart type ne suffit pas.
En gros, le calcul effectué par le réseau de neurones consiste à obtenir le produit de la valeur d'entrée * x * multipliée par chaque paramètre de poids * w *, et à obtenir la valeur de sortie en utilisant la somme de ces produits comme entrée de la fonction d'activation. ,est.
En ce qui concerne la moyenne, multipliez chaque valeur d'entrée par 0,1 (dans ce cas, 1/10 = 0,1 car il y a 10 valeurs à saisir) et additionnez-les pour obtenir la moyenne, donc NN calcule la moyenne de 10 valeurs avec une grande précision. Il est facile d'imaginer ce que vous pouvez faire.
D'autre part, qu'en est-il de l'écart type? Calculez la valeur moyenne, puis ajoutez la valeur moyenne multipliée par -1 à chaque valeur d'entrée (c'est-à-dire prenez la différence par rapport à la moyenne), mettez-la au carré, ajoutez-la et divisez par 9. , Doit être l'écart type. La partie délicate de ce processus est la quadrature.
En interne, NN multiplie un paramètre de pondération fixe et une valeur d'entrée, les ajoute ensemble et les transmet à la fonction d'activation. Est-il vraiment possible de renvoyer la valeur au carré de n'importe quelle valeur d'entrée avec presque aucune erreur? Vous devriez pouvoir exprimer n'importe quelle courbe en augmentant les paramètres, mais je ne suis pas sûr de quel type de calcul il s'agira.
Ce serait peut-être bien s'il y avait une fonction d'activation qui mettait au carré (étendue à la nième puissance) la valeur d'entrée. J'aimerais y réfléchir quelque part.
Maintenant que nous avons un NN qui peut générer des valeurs proches de la moyenne et de l'écart type, je voudrais conclure la partie 2. 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