esittely
Oletetaan, että haluat Keras-mallisi käyttäytyvän tietyllä tavalla harjoittelun, arvioinnin tai ennustamisen aikana. Saatat esimerkiksi haluta tallentaa mallisi joka harjoittelujaksolla. Yksi tapa tehdä tämä on takaisinsoittojen käyttö.
Yleensä takaisinkutsut ovat toimintoja, joita kutsutaan, kun jokin tapahtuma tapahtuu, ja ne välitetään argumentteina muille funktioille. Keran tapauksessa ne ovat työkalu mallin käyttäytymisen mukauttamiseen – olipa kyse sitten harjoittelusta, arvioinnista tai päättelystä. Jotkut sovellukset ovat kirjaamista, mallin pysyvyyttä, varhaista pysäyttämistä tai oppimisnopeuden muuttamista. Tämä tehdään välittämällä takaisinsoittoluettelo argumenteiksi keras.Model.fit()
,keras.Model.evaluate()
or keras.Model.predict()
.
Joitakin yleisiä takaisinsoittojen käyttötapauksia ovat oppimisnopeuden muuttaminen, kirjaaminen, seuranta ja koulutuksen varhainen lopettaminen. Kerasissa on useita sisäänrakennettuja yksityiskohtaisia takaisinsoittoja
dokumentaatiossa.
Jotkin tarkemmat sovellukset saattavat kuitenkin vaatia mukautetun takaisinsoiton. Esimerkiksi, Oppimisnopeuden lämmittely kosinivaimennuksella pitoajan jälkeen ei ole tällä hetkellä sisäänrakennettu, mutta sitä käytetään laajasti ja se on otettu käyttöön ajastimena.
Takaisinsoittoluokka ja sen menetelmät
Kerasilla on erityinen takaisinsoittoluokka, keras.callbacks.Callback
, menetelmillä, joita voidaan kutsua koulutuksen, testauksen ja päättelyn aikana globaalilla, erä- tai aikakausitasolla. Jotta luoda mukautettuja takaisinsoittoja, meidän on luotava alaluokka ja ohitettava nämä menetelmät.
- keras.callbacks.Callback
luokassa on kolmenlaisia menetelmiä:
- globaalit menetelmät: kutsutaan alussa tai lopussa
fit()
,evaluate()
japredict()
. - erätason menetelmät: kutsutaan erän käsittelyn alussa tai lopussa.
- epoch-tason menetelmät: kutsutaan harjoituserän alussa tai lopussa.
Huomautus: Jokaisella menetelmällä on pääsy saneluun, jota kutsutaan logs
. Avaimet ja arvot logs
ovat kontekstuaalisia – ne riippuvat tapahtumasta, joka kutsuu menetelmää. Lisäksi meillä on pääsy malliin kunkin menetelmän kautta self.model
määrite.
Katsotaanpa kolmea mukautettua takaisinsoittoesimerkkiä – yksi koulutusta, yksi arviointia ja yksi ennustamista varten. Jokainen tulostaa jokaisessa vaiheessa, mitä mallimme tekee ja mitä lokeja meillä on pääsy. Tämä auttaa ymmärtämään, mitä mukautetuilla takaisinkutsuilla voi tehdä kussakin vaiheessa.
Aloitetaan määrittelemällä lelumalli:
import tensorflow as tf
from tensorflow import keras
import numpy as np
model = keras.Sequential()
model.add(keras.layers.Dense(10, input_dim = 1, activation='relu'))
model.add(keras.layers.Dense(10, activation='relu'))
model.add(keras.layers.Dense(1))
model.compile(
optimizer=keras.optimizers.RMSprop(learning_rate=0.1),
loss = "mean_squared_error",
metrics = ["mean_absolute_error"]
)
x = np.random.uniform(low = 0, high = 10, size = 1000)
y = x**2
x_train, x_test = (x[:900],x[900:])
y_train, y_test = (y[:900],y[900:])
Mukautetun koulutuksen takaisinsoitto
Ensimmäinen takaisinsoittomme on soitettava harjoituksen aikana. Otetaan alaluokka Callback
luokka:
class TrainingCallback(keras.callbacks.Callback):
def __init__(self):
self.tabulation = {"train":"", 'batch': " "*8, 'epoch':" "*4}
def on_train_begin(self, logs=None):
tab = self.tabulation['train']
print(f"{tab}Training!")
print(f"{tab}available logs: {logs}")
def on_train_batch_begin(self, batch, logs=None):
tab = self.tabulation['batch']
print(f"{tab}Batch {batch}")
print(f"{tab}available logs: {logs}")
def on_train_batch_end(self, batch, logs=None):
tab = self.tabulation['batch']
print(f"{tab}End of Batch {batch}")
print(f"{tab}available logs: {logs}")
def on_epoch_begin(self, epoch, logs=None):
tab = self.tabulation['epoch']
print(f"{tab}Epoch {epoch} of training")
print(f"{tab}available logs: {logs}")
def on_epoch_end(self, epoch, logs=None):
tab = self.tabulation['epoch']
print(f"{tab}End of Epoch {epoch} of training")
print(f"{tab}available logs: {logs}")
def on_train_end(self, logs=None):
tab = self.tabulation['train']
print(f"{tab}Finishing training!")
print(f"{tab}available logs: {logs}")
Jos jotakin näistä menetelmistä ei ohiteta – oletustoiminta jatkuu entiseen tapaan. Esimerkissämme tulostetaan vain käytettävissä olevat lokit ja taso, jolla takaisinsoittoa käytetään, asianmukaisella sisennyksellä.
Katsotaanpa ulostuloja:
model.fit(
x_train,
y_train,
batch_size=500,
epochs=2,
verbose=0,
callbacks=[TrainingCallback()],
)
Training!
available logs: {}
Epoch 0 of training
available logs: {}
Batch 0
available logs: {}
End of Batch 0
available logs: {'loss': 2172.373291015625, 'mean_absolute_error': 34.79669952392578}
Batch 1
available logs: {}
End of Batch 1
available logs: {'loss': 2030.1309814453125, 'mean_absolute_error': 33.30256271362305}
End of Epoch 0 of training
available logs: {'loss': 2030.1309814453125, 'mean_absolute_error': 33.30256271362305}
Epoch 1 of training
available logs: {}
Batch 0
available logs: {}
End of Batch 0
available logs: {'loss': 1746.2772216796875, 'mean_absolute_error': 30.268001556396484}
Batch 1
available logs: {}
End of Batch 1
available logs: {'loss': 1467.36376953125, 'mean_absolute_error': 27.10252571105957}
End of Epoch 1 of training
available logs: {'loss': 1467.36376953125, 'mean_absolute_error': 27.10252571105957}
Finishing training!
available logs: {'loss': 1467.36376953125, 'mean_absolute_error': 27.10252571105957}
Huomaa, että voimme seurata jokaisessa vaiheessa, mitä malli tekee ja mihin mittareihin meillä on pääsy. Jokaisen erän ja aikakauden lopussa meillä on pääsy näytteen sisäiseen häviöfunktioon ja mallimme mittareihin.
Mukautetun arvioinnin takaisinsoitto
Nyt soitetaan Model.evaluate()
menetelmä. Näemme, että erän lopussa meillä on pääsy menetysfunktioon ja senhetkisiin mittareihin, ja arvioinnin lopussa meillä on pääsy kokonaishäviöön ja mittareihin:
class TestingCallback(keras.callbacks.Callback):
def __init__(self):
self.tabulation = {"test":"", 'batch': " "*8}
def on_test_begin(self, logs=None):
tab = self.tabulation['test']
print(f'{tab}Evaluating!')
print(f'{tab}available logs: {logs}')
def on_test_end(self, logs=None):
tab = self.tabulation['test']
print(f'{tab}Finishing evaluation!')
print(f'{tab}available logs: {logs}')
def on_test_batch_begin(self, batch, logs=None):
tab = self.tabulation['batch']
print(f"{tab}Batch {batch}")
print(f"{tab}available logs: {logs}")
def on_test_batch_end(self, batch, logs=None):
tab = self.tabulation['batch']
print(f"{tab}End of batch {batch}")
print(f"{tab}available logs: {logs}")
res = model.evaluate(
x_test, y_test, batch_size=100, verbose=0, callbacks=[TestingCallback()]
)
Evaluating!
available logs: {}
Batch 0
available logs: {}
End of batch 0
available logs: {'loss': 382.2723083496094, 'mean_absolute_error': 14.069927215576172}
Finishing evaluation!
available logs: {'loss': 382.2723083496094, 'mean_absolute_error': 14.069927215576172}
Mukautettu ennakoiva takaisinsoitto
Lopuksi soitetaan Model.predict()
menetelmä. Huomaa, että jokaisen erän lopussa meillä on pääsy mallimme ennustettuihin ulostuloihin:
class PredictionCallback(keras.callbacks.Callback):
def __init__(self):
self.tabulation = {"prediction":"", 'batch': " "*8}
def on_predict_begin(self, logs=None):
tab = self.tabulation['prediction']
print(f"{tab}Predicting!")
print(f"{tab}available logs: {logs}")
def on_predict_end(self, logs=None):
tab = self.tabulation['prediction']
print(f"{tab}End of Prediction!")
print(f"{tab}available logs: {logs}")
def on_predict_batch_begin(self, batch, logs=None):
tab = self.tabulation['batch']
print(f"{tab}batch {batch}")
print(f"{tab}available logs: {logs}")
def on_predict_batch_end(self, batch, logs=None):
tab = self.tabulation['batch']
print(f"{tab}End of batch {batch}")
print(f"{tab}available logs:n {logs}")
res = model.predict(x_test[:10],
verbose = 0,
callbacks=[PredictionCallback()])
Tutustu käytännönläheiseen, käytännölliseen Gitin oppimisoppaaseemme, jossa on parhaat käytännöt, alan hyväksymät standardit ja mukana tuleva huijauslehti. Lopeta Git-komentojen googlailu ja oikeastaan oppia se!
Predicting!
available logs: {}
batch 0
available logs: {}
End of batch 0
available logs:
{'outputs': array([[ 7.743822],
[27.748264],
[33.082104],
[26.530678],
[27.939169],
[18.414223],
[42.610645],
[36.69335 ],
[13.096557],
[37.120853]], dtype=float32)}
End of Prediction!
available logs: {}
Näiden avulla voit mukauttaa käyttäytymistä, määrittää seurantaa tai muuten muuttaa koulutus-, arviointi- tai päättelyprosesseja. Vaihtoehto alilähetykselle on käyttää LambdaCallback
.
LambaCallbackin käyttö
Yksi Kerasin sisäänrakennetuista takaisinkutsuista on LambdaCallback
luokkaa. Tämä takaisinsoitto hyväksyy toiminnon, joka määrittää, miten se käyttäytyy ja mitä se tekee! Tietyssä mielessä sen avulla voit käyttää mitä tahansa mielivaltaista toimintoa takaisinsoittona, jolloin voit luoda mukautettuja takaisinsoittoja.
Luokassa on valinnaiset parametrit:
-on_epoch_begin
on_epoch_end
on_batch_begin
on_batch_end
on_train_begin
on_train_end
Jokainen parametri hyväksyy toiminto jota kutsutaan vastaavassa mallitapahtumassa. Esimerkki: soitetaan takaisin sähköpostin lähettämiseksi, kun malli on lopettanut harjoittelun:
import smtplib
from email.message import EmailMessage
def send_email(logs):
msg = EmailMessage()
content = f"""The model has finished training."""
for key, value in logs.items():
content = content + f"n{key}:{value:.2f}"
msg.set_content(content)
msg['Subject'] = f'Training report'
msg['From'] = '[email protected]'
msg['To'] = 'receiver-email'
s = smtplib.SMTP('smtp.gmail.com', 587)
s.starttls()
s.login("[email protected]", "your-gmail-app-password")
s.send_message(msg)
s.quit()
lambda_send_email = lambda logs : send_email(logs)
email_callback = keras.callbacks.LambdaCallback(on_train_end = lambda_send_email)
model.fit(
x_train,
y_train,
batch_size=100,
epochs=1,
verbose=0,
callbacks=[email_callback],
)
Voit tehdä mukautetun takaisinsoittomme käyttämällä LambdaCallback
, meidän on vain toteutettava funktio, jota haluamme kutsua, kääri se muotoon a lambda
toiminto ja välitä seLambdaCallback
luokka parametrina.
Takaisinsoitto mallikoulutuksen visualisointiin
Tässä osiossa annamme esimerkin mukautetusta takaisinkutsusta, joka saa animaation mallimme suorituskyvystä paranemaan harjoittelun aikana. Tätä varten tallennamme lokien arvot jokaisen erän loppuun. Sitten harjoitussilmukan lopussa luomme animaation käyttämällä matplotlib
.
Visualisoinnin parantamiseksi häviö ja mittarit piirretään log-asteikossa:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.animation import FuncAnimation
from IPython import display
class TrainingAnimationCallback(keras.callbacks.Callback):
def __init__(self, duration = 40, fps = 1000/25):
self.duration = duration
self.fps = fps
self.logs_history = []
def set_plot(self):
self.figure = plt.figure()
plt.xticks(
range(0,self.params['steps']*self.params['epochs'], self.params['steps']),
range(0,self.params['epochs']))
plt.xlabel('Epoch')
plt.ylabel('Loss & Metrics ($Log_{10}$ scale)')
self.plot = {}
for metric in self.model.metrics_names:
self.plot[metric], = plt.plot([],[], label = metric)
max_y = [max(log.values()) for log in self.logs_history]
self.title = plt.title(f'batches:0')
plt.xlim(0,len(self.logs_history))
plt.ylim(0,max(max_y))
plt.legend(loc='upper right')
def animation_function(self,frame):
batch = frame % self.params['steps']
self.title.set_text(f'batch:{batch}')
x = list(range(frame))
for metric in self.model.metrics_names:
y = [log[metric] for log in self.logs_history[:frame]]
self.plot[metric].set_data(x,y)
def on_train_batch_end(self, batch, logs=None):
logarithm_transform = lambda item: (item[0], np.log(item[1]))
logs = dict(map(logarithm_transform,logs.items()))
self.logs_history.append(logs)
def on_train_end(self, logs=None):
self.set_plot()
num_frames = int(self.duration*self.fps)
num_batches = self.params['steps']*self.params['epochs']
selected_batches = range(0, num_batches , num_batches//num_frames )
interval = 1000*(1/self.fps)
anim_created = FuncAnimation(self.figure,
self.animation_function,
frames=selected_batches,
interval=interval)
video = anim_created.to_html5_video()
html = display.HTML(video)
display.display(html)
plt.close()
Käytämme samaa mallia kuin ennenkin, mutta lisää koulutusnäytteitä:
import tensorflow as tf
from tensorflow import keras
import numpy as np
model = keras.Sequential()
model.add(keras.layers.Dense(10, input_dim = 1, activation='relu'))
model.add(keras.layers.Dense(10, activation='relu'))
model.add(keras.layers.Dense(1))
model.compile(
optimizer=keras.optimizers.RMSprop(learning_rate=0.1),
loss = "mean_squared_error",
metrics = ["mean_absolute_error"]
)
def create_sample(sample_size, train_test_proportion = 0.9):
x = np.random.uniform(low = 0, high = 10, size = sample_size)
y = x**2
train_test_split = int(sample_size*train_test_proportion)
x_train, x_test = (x[:train_test_split],x[train_test_split:])
y_train, y_test = (y[:train_test_split],y[train_test_split:])
return (x_train,x_test,y_train,y_test)
x_train,x_test,y_train,y_test = create_sample(35200)
model.fit(
x_train,
y_train,
batch_size=32,
epochs=2,
verbose=0,
callbacks=[TrainingAnimationCallback()],
)
Tuotteemme on animaatio mittareista ja häviöfunktiosta, kun ne muuttuvat koulutusprosessin aikana:
Selaimesi ei tue HTML-videoita.
Yhteenveto
Tässä oppaassa olemme tutustuneet mukautettujen takaisinsoittojen käyttöön Kerasissa.
Mukautettujen takaisinsoittojen toteuttamiseen on kaksi vaihtoehtoa – alaluokituksen kautta keras.callbacks.Callback
luokkaa tai käyttämällä keras.callbacks.LambdaCallback
luokka.
Olemme nähneet yhden käytännön esimerkin käytöstä LambdaCallback
sähköpostin lähettämiseen koulutussilmukan lopussa ja yksi esimerkki alaluokituksesta Callback
luokka, joka luo animaation harjoitussilmukasta.
Althoug Kerasissa on monia sisäänrakennettuja takaisinsoittoja, joten mukautetun takaisinkutsun toteuttaminen voi olla hyödyllistä tarkemmissa sovelluksissa.