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, ???
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 ???
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) ???
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, ???
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