[PYTHON] Jouons avec les données Amedas - Partie 3

Ceci est une continuation de l'article précédent (https://qiita.com/tubarin/items/cd70989f3e1f387a90a8).

À partir des données Amedas, j'ai pu faire quelque chose comme une analyse de régression avec mon propre réseau neuronal pour le moment. Cette fois, je vais essayer la même chose en utilisant des keras. Cet article est comme un mémo des résultats de l'étude des keras.

La première chose que j'ai faite a été d'installer des keras. Les versions ne correspondaient pas, et je suis resté coincé avec une erreur, mais cela a fonctionné. Finalement, cela fonctionne avec les versions suivantes.

python:3.6.19 tensorflow:1.14.0 keras:2.2.0

Ensuite, j'ai étudié divers usages et créé un code à l'aide de keras. J'ai utilisé un objet appelé Sequential. Le site officiel de ici explique les spécifications détaillées, mais cela semble être utile.

Et je me suis référé à l'article suivant pour savoir comment l'utiliser. Exemple d'apprentissage en profondeur extrêmement simple par Keras

Selon cet article, vous pouvez créer un réseau de neurones avec le code simple suivant. (Pour x (1 couche) -> 32 couches-> y (1 couche))

from keras.models import Sequential
from keras.layers import Activation, Dense

#Créer un modèle d'apprentissage
model = Sequential()
#Couche entièrement connectée(1 couche->32 couches)
model.add(Dense(input_dim=1, output_dim=32, bias=True))
#Fonction d'activation(Fonction sigmoïde)
model.add(Activation("sigmoid"))

#Couche entièrement connectée(32 couches->1 couche)
model.add(Dense(output_dim=1))
#Compilez le modèle
model.compile(loss="mean_squared_error", optimizer="sgd", metrics=["accuracy"])
#Effectuer l'apprentissage
model.fit(x, y, nb_epoch=1000, batch_size=32)

Est-ce tout! ?? Merveilleux. Si vous définissez un peu le modèle du réseau neuronal et que vous le compilez ensuite, il semble que l'initialisation des différents paramètres et le programme d'apprentissage seront définis sans autorisation. Et il a semblé apprendre en mettant des données d'entraînement (entrée et réponse correcte) dans la méthode d'ajustement.

Alors, explorons celui pour l'analyse des données Amedas. Je vais mettre tout le code pour le moment, c'est inutilement long ...

import pandas as pd
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt

from keras.models import Sequential
from keras.layers import Activation, Dense


# deta making???
csv_input = pd.read_csv(filepath_or_buffer="data_out.csv",
                        encoding="ms932",
                        sep=",")

#Nombre d'éléments d'entrée (nombre de lignes)*Le nombre de colonnes) sera renvoyé.
print(csv_input.size)

#Renvoie l'objet DataFrame extrait uniquement pour la colonne spécifiée.
x = np.array(csv_input[["hour"]])
y = np.array(csv_input[["wind"]])

# num of records
N = len(x)

#Normalisation
x_max = np.max(x,axis=0)
x_min = np.min(x,axis=0)
y_max = np.max(y,axis=0)
y_min = np.min(y,axis=0)
x = (x - np.min(x,axis=0))/(np.max(x,axis=0) - np.min(x,axis=0))
y = (y - np.min(y,axis=0))/(np.max(y,axis=0) - np.min(y,axis=0))

#Créer un modèle d'apprentissage
model = Sequential()
#Couche entièrement connectée(1 couche->Couche XXX)
model.add(Dense(input_dim=1, output_dim=32, bias=True))
#Fonction d'activation(Fonction sigmoïde)
model.add(Activation("sigmoid"))

#Couche entièrement connectée(Couche XXX->1 couche)
model.add(Dense(output_dim=1))
#Compilez le modèle
model.compile(loss="mean_squared_error", optimizer="sgd", metrics=["accuracy"])
#Effectuer l'apprentissage
model.fit(x, y, nb_epoch=1000, batch_size=32)

#Tracé de la valeur réelle
plt.plot(x,y,marker='x',label="true")
#Calculer les résultats Keras avec inférence,afficher
y_predict = model.predict(x)
#Graphique des résultats du calcul Keras
plt.plot(x,y_predict,marker='x',label="predict")
#Affichage de la légende
plt.legend()

En regardant les résultats sur la console, les progrès sont bons.

(Omission)
23/23 [==============================] - 0s 0us/step - loss: 0.0563 - acc: 0.0435
Epoch 994/1000
23/23 [==============================] - 0s 435us/step - loss: 0.0563 - acc: 0.0435
Epoch 995/1000
23/23 [==============================] - 0s 0us/step - loss: 0.0563 - acc: 0.0435
Epoch 996/1000
23/23 [==============================] - 0s 0us/step - loss: 0.0563 - acc: 0.0435
Epoch 997/1000
23/23 [==============================] - 0s 0us/step - loss: 0.0563 - acc: 0.0435
Epoch 998/1000
23/23 [==============================] - 0s 0us/step - loss: 0.0563 - acc: 0.0435
Epoch 999/1000
23/23 [==============================] - 0s 0us/step - loss: 0.0563 - acc: 0.0435
Epoch 1000/1000
23/23 [==============================] - 0s 435us/step - loss: 0.0563 - acc: 0.0435

Il semble que cela fonctionne bien, mais si vous regardez le graphique résultant, ???

Figure 2020-04-30 203427.png

Hmmm, je me suis installé sur une simple courbe d'approximation comme je l'ai fait avant. J'ai essayé diverses choses comme jouer avec le nombre de couches intermédiaires, mais il n'y a pas eu de grand changement. En regardant les résultats précédents, il semblait que si les valeurs initiales des coefficients dans le réseau neuronal pouvaient être bien définies, il serait possible de capturer un peu plus les valeurs. Par conséquent, j'ai conçu une classe pour définir la valeur initiale du réseau neuronal. La partie calcul des coefficients utilise la précédente (plus de commentaires, etc.) C'est comme faire fonctionner une étape avec deux nœuds dans la couche intermédiaire.

# init infomation for keras layers or models
class InitInfo:
    
    # constractor
    #  x:input y:output
    def __init__(self,x,y):
        self.x = x
        self.y = y
        
    # calc coefficient of keras models(1st layer)
    # input  s:changing point in [0,1]
    #        sign:[1]raise,[0]down
    # return b:coefficient of bias
    #        w:coefficient of x
    # notice - it can make like step function using this return values(s,sign)
    def calc_b_w(self,s,sign):
    
        N = 1000 #Stockage temporaire
        # s = -b/w
        if sign > 0:
            b = -N
        else:
            b = N
        if s != 0:
            w = -b/s
        else:
            w = 1
        return b,w
    
    # calc coefficient of keras models(1st and 2nd layer)
    def calc_w_h(self):
    
        K = len(self.x)
        # coefficient of 1st layer(x,w)
        w_array = np.zeros([K*2,2])
        # coefficient of 2nd layer
        h_array = np.zeros([K*2,1])
        
        w_idx = 0
        for k in range(K):
            # x[k] , y[k]
            # make one step function
            # startX : calc raise point in [0,1]
            if k > 0:
                startX = self.x[k] +  (self.x[k-1] - self.x[k])/2
            else:
                startX = 0
    
            # endX : calc down point in [0,1]
            if k < K-1:
                endX = self.x[k] + (self.x[k+1] - self.x[k])/2
            else:
                endX = 1
    
            # calc b,w
            if k > 0:
                b,w = self.calc_b_w(startX,1)
            else:
                # init???
                b = 100
                w = 1
    
            # stepfunction 1stHalf
            #            __________
            # 0 ________|
            #        
            w_array[w_idx,0] = w
            w_array[w_idx,1] = b
            h_array[w_idx,0] = self.y[k]
            w_idx += 1
            
            # stepfunction 2ndHalf
            #        
            # 0 __________
            #             |________
            b,w = self.calc_b_w(endX,1)
            w_array[w_idx,0] = w
            w_array[w_idx,1] = b
            h_array[w_idx,0] = self.y[k]*-1
            
            # shape of 1st + 2nd is under wave
            #            _
            # 0 ________| |________
            #
            
            w_idx += 1
        
        # record param
        self.w = w_array
        self.h = h_array
        self.w_init = w_array[:,0]
        self.b_init = w_array[:,1]
        self.paramN = len(h_array)
        return
    
    # for bias coefficients setting
    def initB(self, shape, name=None):
        #L = np.prod(shape)
        #value = np.random.randn(L).reshape(shape)*5
        value = self.b_init
        value = value.reshape(shape)
        return K.variable(value, name=name)

    # for w coefficients (x) setting
    def initW(self, shape, name=None):
        #L = np.prod(shape)
        #value = np.random.random(shape)
        #value = np.random.randn(L).reshape(shape)*5
        value = self.w_init
        value = value.reshape(shape)
        return K.variable(value, name=name)
    
    # for h coefficients setting
    def initH(self, shape, name=None):
        #L = np.prod(shape)
        #value = np.random.randn(L).reshape(shape)*1
        value = self.h
        value = value.reshape(shape)
        return K.variable(value, name=name)

initB(self, shape, name=None): initW(self, shape, name=None): initH(self, shape, name=None): Les trois méthodes de sont destinées à être utilisées dans la fonction de réglage du coefficient de l'objet Dense. Certains commentaires sont faits lorsque les nombres aléatoires sont complètement insérés (à des fins de recherche et de débogage).

En prenant le nombre de nœuds dans la couche intermédiaire des membres de cet objet InitInfo, il semble que la partie d'apprentissage, etc. se déplacera si elle passe au code suivant.

# create InitInfo object
objInitInfo = InitInfo(x,y)
# calc init value of w and h(and bias)
objInitInfo.calc_w_h()

#Créer un modèle d'apprentissage
model = Sequential()
#Couche entièrement connectée(1 couche->Couche XXX)
model.add(Dense(input_dim=1, output_dim=objInitInfo.paramN,
                bias=True,
                kernel_initializer=objInitInfo.initW,
                bias_initializer=objInitInfo.initB))
#Fonction d'activation(Fonction sigmoïde)
model.add(Activation("sigmoid"))

#Couche entièrement connectée(Couche XXX->1 couche)
model.add(Dense(output_dim=1, kernel_initializer=objInitInfo.initH))
#Compilez le modèle
model.compile(loss="mean_squared_error", optimizer="sgd", metrics=["accuracy"])
#Effectuer l'apprentissage
model.fit(x, y, nb_epoch=1000, batch_size=32)

Pour le nom de l'option de réglage de la valeur initiale, etc., j'ai fait référence au site Web officiel de Keras. Je vais coller le code entier qui l'utilise ci-dessous.

sample_KerasNewral.py


import pandas as pd
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt

from keras.models import Sequential
from keras.layers import Activation, Dense
from keras import backend as K


# init infomation for keras layers or models
class InitInfo:
    
    # constractor
    #  x:input y:output
    def __init__(self,x,y):
        self.x = x
        self.y = y
        
    # calc coefficient of keras models(1st layer)
    # input  s:changing point in [0,1]
    #        sign:[1]raise,[0]down
    # return b:coefficient of bias
    #        w:coefficient of x
    # notice - it can make like step function using this return values(s,sign)
    def calc_b_w(self,s,sign):
    
        N = 1000 #Stockage temporaire
        # s = -b/w
        if sign > 0:
            b = -N
        else:
            b = N
        if s != 0:
            w = -b/s
        else:
            w = 1
        return b,w
    
    # calc coefficient of keras models(1st and 2nd layer)
    def calc_w_h(self):
    
        K = len(self.x)
        # coefficient of 1st layer(x,w)
        w_array = np.zeros([K*2,2])
        # coefficient of 2nd layer
        h_array = np.zeros([K*2,1])
        
        w_idx = 0
        for k in range(K):
            # x[k] , y[k]
            # make one step function
            # startX : calc raise point in [0,1]
            if k > 0:
                startX = self.x[k] +  (self.x[k-1] - self.x[k])/2
            else:
                startX = 0
    
            # endX : calc down point in [0,1]
            if k < K-1:
                endX = self.x[k] + (self.x[k+1] - self.x[k])/2
            else:
                endX = 1
    
            # calc b,w
            if k > 0:
                b,w = self.calc_b_w(startX,1)
            else:
                # init???
                b = 100
                w = 1
    
            # stepfunction 1stHalf
            #            __________
            # 0 ________|
            #        
            w_array[w_idx,0] = w
            w_array[w_idx,1] = b
            h_array[w_idx,0] = self.y[k]
            w_idx += 1
            
            # stepfunction 2ndHalf
            #        
            # 0 __________
            #             |________
            b,w = self.calc_b_w(endX,1)
            w_array[w_idx,0] = w
            w_array[w_idx,1] = b
            h_array[w_idx,0] = self.y[k]*-1
            
            # shape of 1st + 2nd is under wave
            #            _
            # 0 ________| |________
            #
            
            w_idx += 1
        
        # record param
        self.w = w_array
        self.h = h_array
        self.w_init = w_array[:,0]
        self.b_init = w_array[:,1]
        self.paramN = len(h_array)
        return
    
    # for bias coefficients setting
    def initB(self, shape, name=None):
        #L = np.prod(shape)
        #value = np.random.randn(L).reshape(shape)*5
        value = self.b_init
        value = value.reshape(shape)
        return K.variable(value, name=name)

    # for w coefficients (x) setting
    def initW(self, shape, name=None):
        #L = np.prod(shape)
        #value = np.random.random(shape)
        #value = np.random.randn(L).reshape(shape)*5
        value = self.w_init
        value = value.reshape(shape)
        return K.variable(value, name=name)
    
    # for h coefficients setting
    def initH(self, shape, name=None):
        #L = np.prod(shape)
        #value = np.random.randn(L).reshape(shape)*1
        value = self.h
        value = value.reshape(shape)
        return K.variable(value, name=name)

 
# deta making???
csv_input = pd.read_csv(filepath_or_buffer="data_out.csv",
                        encoding="ms932",
                        sep=",")

#Nombre d'éléments d'entrée (nombre de lignes)*Le nombre de colonnes) sera renvoyé.
print(csv_input.size)

#Renvoie l'objet DataFrame extrait uniquement pour la colonne spécifiée.
x = np.array(csv_input[["hour"]])
y = np.array(csv_input[["wind"]])

# num of records
N = len(x)

#Normalisation
x_max = np.max(x,axis=0)
x_min = np.min(x,axis=0)
y_max = np.max(y,axis=0)
y_min = np.min(y,axis=0)
x = (x - np.min(x,axis=0))/(np.max(x,axis=0) - np.min(x,axis=0))
y = (y - np.min(y,axis=0))/(np.max(y,axis=0) - np.min(y,axis=0))

# create InitInfo object
objInitInfo = InitInfo(x,y)
# calc init value of w and h(and bias)
objInitInfo.calc_w_h()

#Créer un modèle d'apprentissage
model = Sequential()
#Couche entièrement connectée(1 couche->Couche XXX)
model.add(Dense(input_dim=1, output_dim=objInitInfo.paramN,
                bias=True,
                kernel_initializer=objInitInfo.initW,
                bias_initializer=objInitInfo.initB))
#Fonction d'activation(Fonction sigmoïde)
model.add(Activation("sigmoid"))

#Couche entièrement connectée(Couche XXX->1 couche)
model.add(Dense(output_dim=1, kernel_initializer=objInitInfo.initH))
#Compilez le modèle
model.compile(loss="mean_squared_error", optimizer="sgd", metrics=["accuracy"])
#Effectuer l'apprentissage
model.fit(x, y, nb_epoch=1000, batch_size=32)

#Tracé de la valeur réelle
plt.plot(x,y,marker='x',label="true")
#Calculer les résultats Keras avec inférence,afficher
y_predict = model.predict(x)
#Graphique des résultats du calcul Keras
plt.plot(x,y_predict,marker='x',label="predict")
#Affichage de la légende
plt.legend()

En regardant le graphique des résultats ???

Figure 2020-04-30 204804.png

Ils correspondaient presque! Comme la dernière fois, je pense que c'est surappris, mais je voulais le faire, donc il semble que cela a fonctionné.

Lorsque la valeur initiale de h est complètement aléatoire (distribution normale) ???

Figure 2020-04-30 205037.png

Quand N = 1000, la convergence n'était pas très bonne, donc si je l'augmentais un peu, elle devenait comme ci-dessus. Ça fait du bien. D'un autre côté, si w et b sont définis sur des nombres complètement aléatoires, ???

Figure 2020-04-30 205237.png

Cela ressemble à une courbe grossière. La valeur initiale étant un nombre aléatoire, elle est susceptible de changer légèrement à chaque exécution.

Comme ça, même si vous utilisez des keras, vous pouvez sélectionner la valeur initiale assez librement, et il semble que le comportement change en conséquence. C'est un contenu intéressant.

Cette fois, je l'ai écrit comme un mémo du résultat de l'étude sur la façon d'utiliser les keras. Il y a encore diverses fonctionnalités amusantes telles que les rappels, donc je vais continuer à les regarder, et ensuite je vais regarder le système de classification.

Recommended Posts

Jouons avec les données Amedas - Partie 1
Jouons avec les données Amedas - Partie 4
Jouons avec les données Amedas - Partie 3
Jouons avec les données Amedas - Partie 2
Jouons avec la 4e dimension 4e
Jouez avec Prophet
[Introduction à WordCloud] Jouez avec le scraping ♬
Jouez avec PyTorch
Jouez avec 2016-Python
Jouez avec Pyramid
Jouez avec Fathom
Jeu à la main en Python (commençons avec AtCoder?)
[Piyopiyokai # 1] Jouons avec Lambda: création d'une fonction Lambda
Jouer avec Othello (Reversi)
[Jouons avec Python] Créer un livre de comptes de ménage
Jouons avec JNetHack 3.6.2 qui est plus facile à compiler!
[Piyopiyokai # 1] Jouons avec Lambda: créez un compte Twitter
[Piyopiyokai # 1] Jouons avec Lambda: création d'un script Python
Jouez avec les notifications push avec imap4lib
Jouez avec les partitions Linux
[Jouons avec Python] Traitement d'image en monochrome et points
Écrivons python avec cinema4d.
Faisons R-CNN avec Sklearn-theano
Construisons git-cat avec Python
Jouez avec le module MD de ASE
Jouez avec A3RT (texte suggéré)
[Jouons avec Python] Viser la génération automatique de phrases ~ Achèvement de la génération automatique de phrases ~
Téléchargeons des fichiers S3 avec CLI
Jouez avec une tortue avec des graphiques de tortue (partie 1)
Faisons une interface graphique avec python.
Jouez avec la série Poancare et SymPy
Apprenons Deep SEA avec Selene
Faisons une rupture de bloc avec wxPython
Faisons l'IA d'Othello avec Chainer-Part 1-
Jouer avec l'implémentation de l'interface utilisateur Pythonista [Action implementation]
Jouez avec le module de capteur PIR [DSUN-PIR]
Faisons du scraping d'images avec Python
Faisons un graphe avec python! !!
Faisons un spacon avec xCAT
Faisons l'IA d'Othello avec Chainer-Part 2-
Spark play avec WSL anaconda jupyter (2)
Reconnaissons les émotions avec Azure Face
Jouez avec Turtle sur Google Colab
Jouez avec les démons parce que c'est une section
Analysons la voix avec Python # 1 FFT
Jouons avec le jeu de données d'analyse d'entreprise "CoARiJ" créé par TIS ①
Créons un modèle de reconnaissance d'image avec vos propres données et jouons!
[Jouons avec Python] Viser la génération automatique de phrases ~ Effectuer une analyse morphologique ~
Jouons avec le jeu de données d'analyse d'entreprise "CoARiJ" créé par TIS ②