Avec le concept «vous pouvez faire des didacticiels d'apprentissage en profondeur sans créer un environnement compliqué», vous pouvez l'essayer en copiant et en collant simplement le code de cet article. (Je veux dire, clonez-le simplement à partir de GitHub et exécutez-le)
environnement macOS Mojave version 10.14.6 python3.6.5
--Définition de l'apprentissage profond
La définition peut différer légèrement selon la source d'information, mais j'estime que les algorithmes appelés apprentissage profond et apprentissage profond sont souvent appelés à partir de trois couches cachées ou plus. (Désolé d'être ambigu)
Cet article traite également des modèles avec moins de couches cachées, mais je ne ferai aucune distinction. Cependant, l'algorithme s'appelle un réseau neuronal et l'apprentissage du poids est appelé apprentissage profond.
--Fonction d'évaluation, fonction de perte La fonction d'évaluation utilise le score R ^ 2 et la fonction de perte utilise MSE. ..
Pour faire simple, le score R ^ 2 est une fonction d'évaluation qui exprime la proximité de la courbe de régression (prédite) par rapport à la courbe correcte de 0 à 1. MSE est appelée la somme moyenne des erreurs de carrés, qui est la valeur moyenne de la somme des erreurs de carrés de la valeur de réponse correcte et de la valeur prédite.
Prédire la courbe SinCos à partir de deux valeurs d'entrée (x1, x2)
L'image ressemble à ceci. Nous allons vérifier comment la précision change en fonction du nombre de couches cachées et du nombre d'unités dans chaque couche.
#Pour plus de simplicité, veuillez suivre les étapes ci-dessous pour cloner le référentiel sur lequel j'ai travaillé.
$ git clone https://github.com/keroido/DNN-learning-Sin-Cos-wave.git
$ cd DNN-learning-Sin-Cos-wave
#Créez un environnement virtuel et entrez dans l'environnement virtuel. (Tout)
$ pip install virtualenv
$ virtualenv venv
$ . venv/bin/activate
#Installez toutes les bibliothèques requises pour l'environnement virtuel.
(venv)$ pip install -r requirements.txt
#En quittant l'environnement virtuel venv$ deactivate
Suivez les étapes ci-dessous pour créer un ensemble de données. Génère des données de 4 colonnes de Sin et Cos x 1000 lignes lorsque les valeurs d'entrée x0, x1 et les deux sont ajoutées.
Prédisez Sin et Cos à partir de ces x0 et x1.
image
index | x0 | x1 | Sin | Cos |
---|---|---|---|---|
0 | 50.199163279521 | 17.5983756102216 | 0.925854354002364 | 0.377880556756848 |
1 | 127.726947420807 | 116.093208916234 | -0.897413633456196 | -0.441190174966475 |
2 | 54.2208002632216 | 116.589734921833 | 0.159699676625697 | -0.987165646325705 |
3 | 156.256738791155 | 8.64049515860479 | 0.260551118156132 | -0.965460053460312 |
: | ... | ... | ... | ... |
: | ... | ... | ... | ... |
999 | 23.2978504439148 | 109.826906405408 | 0.72986697370653 | -0.683589204634239 |
(0 <= x1, x2 <= 180)
Exécutez le programme qui génère l'ensemble de données dans le répertoire suivant. Créez également ici une entrée de stockage pour l'ensemble de données d'apprentissage et une sortie pour le résultat de sortie.
#Vérifiez le répertoire actuel.
$ pwd
[out]: .../DNN-learning-Sin-Cos-wave/code
#Créez un emplacement pour les données d'entrée et un emplacement pour les données de sortie.
$ mkdir ../input ../output
#Exécutez le programme qui génère l'ensemble de données
$ python make_dataset.py
# make_dataset.py
import numpy as np
import pandas as pd
import math
x0 = np.random.rand(1000) * 180
x1 = np.random.rand(1000) * 180
s = [math.sin(math.radians(i+s)) for i, s in zip(x0, x1)]
c = [math.cos(math.radians(i+s)) for i, s in zip(x0, x1)]
df = pd.DataFrame({'x0':x0, 'x1':x1, 'sin':s, 'cos':c})
df.to_csv('../input/data.csv')
Ensuite, data.csv sera généré dans le répertoire d'entrée.
Faisons enfin un apprentissage en profondeur. Le thème de cet article est l'apprentissage en profondeur sans utiliser de GPU, nous allons donc l'implémenter avec scicit-learn.
De plus, même s'il est indiqué train.py, nous évaluons également chaque modèle en même temps.
$ pwd
[out]: .../DNN-learning-Sin-Cos-wave/code
$ python train.py
# train.py
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split #Divisez les données en ensembles d'apprentissage et ensembles de test.
from sklearn.neural_network import MLPRegressor #C'est une fonction d'un réseau neuronal qui fonctionne sur sklearn.
from sklearn.metrics import mean_squared_error # MSE(Erreur de somme moyenne des carrés)
#Lit les données dans le répertoire d'entrée.
df = pd.read_csv('../input/data.csv')
df = df.drop('Unnamed: 0', axis=1)
#X pour x0 et x1, y pour SinCos
X = df.iloc[:, :2]
y = df.iloc[:, 2:]
#Divisez en un ensemble de formation et un ensemble de test.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
#2 couches cachées,3,4 Le nombre d'unités est de 10,50,100,150,200 Essayez toutes les combinaisons.
hidden_layer_sizes = [(10, 10,), (50, 50,), (100, 100,), (150, 150,), (200, 200,),
(10, 10, 10,), (50, 50, 50,), (100, 100, 100,), (150, 150, 150,), (200, 200, 200,),
(10, 10, 10, 10,), (50, 50, 50, 50,), (100, 100, 100, 100,), (150, 150, 150, 150,), (200, 200, 200, 200,)]
ln = list(range(len(hidden_layer_sizes)))
# Sin,Cos MSE et R respectivement^2 Créez un bloc de données pour écrire la partition
score_df = pd.DataFrame(columns={'sin_mse', 'cos_mse', 'r^2_score'})
for i, hidden_layer_size in zip(ln, hidden_layer_sizes):
#Détails du modèle(https://scikit-learn.org/stable/modules/generated/sklearn.neural_network.MLPRegressor.html)
#Si vous changez verbose en True et que vous l'exécutez, vous pourrez voir la progression de l'apprentissage.
model = MLPRegressor(activation='relu', alpha=0, batch_size=100,
hidden_layer_sizes=hidden_layer_size, learning_rate_init=0.03,
random_state=0, verbose=False, solver='adam')
#Nourrissez le modèle d'un jeu de données d'entraînement.
model.fit(X_train, y_train)
#Ensemble de test x0,x1 à Sin,Prédire Cos.
pred = model.predict(X_test)
#À partir de là, le formatage de la trame de données qui génère le résultat prévu dans le répertoire de sortie, etc.
pred = pd.DataFrame(pred)
x = pd.DataFrame({'x':(X_test['x0'] + X_test['x1']).tolist()})
tes = y_test.rename(columns={'sin': 'sin(label)', 'cos': 'cos(label)'}).reset_index(drop=True)
pre = pred.rename(columns={0: 'sin(prediction)', 1: 'cos(prediction)'}).reset_index(drop=True)
ans_df = pd.concat([x, tes, pre], axis=1)
ans_df = ans_df[['x', 'sin(label)', 'sin(prediction)', 'cos(label)', 'cos(prediction)']]
ans_df.to_csv('../output/result_{}_{}_{}.csv'.format(str(i).zfill(2), len(hidden_layer_size), hidden_layer_size[0]))
sin_mse = mean_squared_error(tes['sin(label)'].tolist(), pre['sin(prediction)'].tolist())
cos_mse = mean_squared_error(tes['cos(label)'].tolist(), pre['cos(prediction)'].tolist())
r2 = model.score(X_test, y_test)
score_df.loc['{}'.format(i), 'sin_mse'] = sin_mse
score_df.loc['{}'.format(i), 'cos_mse'] = cos_mse
score_df.loc['{}'.format(i), 'r^2_score'] = r2
col = ['sin_mse', 'cos_mse', 'r^2_score']
score_df = score_df[col]
#Sortie vers le répertoire de sortie
score_df.to_csv('../output/score.csv')
(Désolé pour le code sale ...) Regardez hidden_layer_sizes. Ici, le nombre de couches (nombre de couches cachées) et le nombre d'unités du réseau de neurones sont modifiés de différentes manières, comme indiqué ci-dessous, afin que vous puissiez essayer de déterminer quelle combinaison peut produire une bonne précision.
Nombre de couches\Nombre d'unités | 10 | 50 | 100 | 150 | 200 |
---|---|---|---|---|---|
2 | Esprit | À chaque fois | Mais | Bien | Ku |
3 | Nana | Ru | ensemble | Seulement | Aller |
4 | sensationnel | Ensemble | Est | quoi | ? |
Le notebook jupyter est pratique pour la visualisation, alors utilisons-le.
$ pip install jupyter
$ pwd
[out]: .../DNN-learning-Sin-Cos-wave/code
$ ls
[out]: make_dataset.py train.py viewer.ipynb
$ jupyter notebook
Ouvrez viewer.ipynb lorsque jupyter notebook démarre dans votre navigateur. Ce bloc-notes vous permet d'évaluer et de visualiser les données simplement en les exécutant par le haut. https://github.com/keroido/DNN-learning-Sin-Cos-wave/blob/master/code/viewer.ipynb Ce qui suit est l'exécution sur jupyter. (Le code qui ne nécessite pas d'explication est omis)
En regardant le répertoire de sortie, il y a 15 fichiers csv avec des noms tels que «résultat_00_2_10.csv». En prenant "result_00_2_10.csv" comme exemple, le nom de ce fichier est 00, où 2 est le nombre de couches et 10 le nombre d'unités. Par conséquent, ce fichier csv est dit "le résultat de l'apprentissage avec le 0ème réseau neuronal à 10 unités de la couche 2".
!ls ../output
[out]:
result_00_2_10.csv result_04_2_200.csv result_08_3_150.csv result_12_4_100.csv
result_01_2_50.csv result_05_3_10.csv result_09_3_200.csv result_13_4_150.csv
result_02_2_100.csv result_06_3_50.csv result_10_4_10.csv result_14_4_200.csv
result_03_2_150.csv result_07_3_100.csv result_11_4_50.csv score.csv
score_df = pd.read_csv('../output/score.csv')
score_df = score_df.drop('Unnamed: 0', axis=1)
score_df
Vérifions dans quelles conditions la valeur du score R ^ 2 est bonne. En regardant les résultats, le 9, le réseau neuronal à 3 couches de 200 unités de result_09_3_200.csv donne les meilleurs résultats. (Peut changer selon les paramètres) Vous pouvez voir qu'il ne s'agit pas simplement d'avoir une couche profonde.
index | sin_mse | cos_mse | r^2_score |
---|---|---|---|
0 | 0.118307 | 0.272191 | 0.551913 |
1 | 0.071344 | 0.174416 | 0.717997 |
2 | 0.101467 | 0.269444 | 0.574389 |
3 | 0.053282 | 0.022353 | 0.913211 |
4 | 0.374317 | 0.242327 | 0.292416 |
5 | 0.127534 | 0.274327 | 0.538875 |
6 | 0.061558 | 0.163282 | 0.742001 |
7 | 0.195692 | 0.262261 | 0.474512 |
8 | 0.034099 | 0.010542 | 0.948776 |
9 | 0.006197 | 0.004922 | 0.987241 |
10 | 0.512035 | 0.361053 | -0.001846 |
11 | 0.116843 | 0.099484 | 0.751770 |
12 | 0.013951 | 0.029560 | 0.950072 |
13 | 0.009213 | 0.009595 | 0.978419 |
14 | 0.005862 | 0.006255 | 0.986096 |
tmp = pd.read_csv('../output/result_09_3_200.csv')
tmp = tmp.drop('Unnamed: 0', axis=1)
tmp
(étiquette) est l'étiquette correcte et (prédiction) est la valeur prédite du réseau neuronal. Vous pouvez voir que vous pouvez prédire une valeur relativement proche.
x | sin(label) | sin(prediction) | cos(label) | cos(prediction) |
---|---|---|---|---|
0 | 271.800382 | -0.999506 | -0.912688 | 0.031417 |
1 | 133.334658 | 0.727358 | 0.722477 | -0.686258 |
2 | 136.451163 | 0.688973 | 0.656727 | -0.724787 |
3 | 187.429195 | -0.129301 | -0.182335 | -0.991605 |
4 | 229.748855 | -0.763220 | -0.801409 | -0.646139 |
... | ... | ... | ... | ... |
files = glob.glob('../output/result*.csv')
files.sort()
csvs = []
t = []
for i in range(1, 16):
t.append(files[i-1])
if i%5 == 0:
csvs.append(t)
t = []
Sin
fig, axes = plt.subplots(3, 5, figsize=(15, 10))
fig.subplots_adjust(hspace=0.3, wspace=0.3)
for i in range(3):
for j in range(5):
tmp = pd.read_csv(csvs[i][j])
axes[i, j].scatter(tmp.loc[:, 'x'], tmp.loc[:, 'sin(label)'], c='b')
axes[i, j].scatter(tmp.loc[:, 'x'], tmp.loc[:, 'sin(prediction)'], c='r', alpha=0.5)
axes[i, j].set_title('layer:{}, unit:{}'.format(csvs[i][j][20], csvs[i][j][22:-4]))
plt.xlim(-5, 365)
cos
fig, axes = plt.subplots(3, 5, figsize=(15, 10))
fig.subplots_adjust(hspace=0.3, wspace=0.3)
for i in range(3):
for j in range(5):
tmp = pd.read_csv(csvs[i][j])
axes[i, j].scatter(tmp.loc[:, 'x'], tmp.loc[:, 'cos(label)'], c='b')
axes[i, j].scatter(tmp.loc[:, 'x'], tmp.loc[:, 'cos(prediction)'], c='r', alpha=0.5)
axes[i, j].set_title('layer:{}, unit:{}'.format(csvs[i][j][20], csvs[i][j][22:-4]))
plt.xlim(-5, 365)
C'est amusant de voir en un coup d'œil comment le réseau de neurones a prédit lorsque vous le visualisez. C'est la fin de "Je n'ai pas de GPU, mais je vais essayer le Deep Learning". Je vous remercie pour votre travail acharné.
Recommended Posts