在keras训练模型时,一般一个epoch结束以后才会显示在该epoch上的平均loss、acc、mae等指标。
模型代码如下
from keras.models import Sequential
from keras.layers.convolutional import Conv3D
from keras.layers.convolutional_recurrent import ConvLSTM2D
from keras.layers.normalization import BatchNormalization
from keras.utils import plot_model
import numpy as np
from keras import metrics
import matplotlib.pyplot as plt
# We create a layer which take as input movies of shape
# (n_frames, width, height, channels) and returns a movie
# of identical shape.
seq = Sequential()
seq.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
input_shape=(None, 40, 40, 1),
padding='same', return_sequences=True))
seq.add(BatchNormalization())
seq.add(ConvLSTM2D(filters=40, kernel_size=(3, 3),
padding='same', return_sequences=True))
seq.add(BatchNormalization())
seq.add(ConvLSTM2D(filters=1, kernel_size=(3, 3),
padding='same', return_sequences=True))
seq.compile(loss='binary_crossentropy', optimizer='adadelta', metrics=[metrics.mae, metrics.categorical_accuracy])
plot_model(seq, to_file='seq.png', show_layer_names=True, show_shapes=True)
# seq.summary()
def generate_movies(n_samples=1200, n_frames=15):
row = 80
col = 80
noisy_movies = np.zeros((n_samples, n_frames, row, col, 1), dtype=np.float)
shifted_movies = np.zeros((n_samples, n_frames, row, col, 1),
dtype=np.float)
for i in range(n_samples):
# Add 3 to 7 moving squares
n = np.random.randint(3, 8)
for j in range(n):
# Initial position
xstart = np.random.randint(20, 60)
ystart = np.random.randint(20, 60)
# Direction of motion
directionx = np.random.randint(0, 3) - 1
directiony = np.random.randint(0, 3) - 1
# Size of the square
w = np.random.randint(2, 4)
for t in range(n_frames):
x_shift = xstart + directionx * t
y_shift = ystart + directiony * t
noisy_movies[i, t, x_shift - w: x_shift + w,
y_shift - w: y_shift + w, 0] += 1
# Make it more robust by adding noise.
# The idea is that if during inference,
# the value of the pixel is not exactly one,
# we need to train the network to be robust and still
# consider it as a pixel belonging to a square.
if np.random.randint(0, 2):
noise_f = (-1)**np.random.randint(0, 2)
noisy_movies[i, t,
x_shift - w - 1: x_shift + w + 1,
y_shift - w - 1: y_shift + w + 1,
0] += noise_f * 0.1
# Shift the ground truth by 1
x_shift = xstart + directionx * (t + 1)
y_shift = ystart + directiony * (t + 1)
shifted_movies[i, t, x_shift - w: x_shift + w,
y_shift - w: y_shift + w, 0] += 1
# Cut to a 40x40 window
noisy_movies = noisy_movies[::, ::, 20:60, 20:60, ::]
shifted_movies = shifted_movies[::, ::, 20:60, 20:60, ::]
noisy_movies[noisy_movies >= 1] = 1
shifted_movies[shifted_movies >= 1] = 1
return noisy_movies, shifted_movies
# Train the network
noisy_movies, shifted_movies = generate_movies(n_samples=1200)
添加继承自 k e r a s . c a l l b a c k s . C a l l b a c k keras.callbacks.Callback keras.callbacks.Callback的类:
class LossHistory(keras.callbacks.Callback):
def on_train_begin(self, logs={}):
self.losses = []
self.mae = []
self.ca = []
print ()
print ('*'*10, 'batch begin', '*'*10)
print ("logs:", logs)
print ('*'*10, 'batch begin', '*'*10)
def on_batch_end(self, batch, logs={}):
self.losses.append(logs.get('loss'))
self.mae.append(logs.get('mean_absolute_error'))
self.ca.append(logs.get('categorical_accuracy'))
print ()
print ('*'*10, 'batch end', '*'*10)
print ("logs:", logs)
print ('*'*10, 'batch end', '*'*10)
# def on_epoch_begin(self,logs={}):
# self.val_losses = []
# self.val_mae = []
# def on_epoch_end(self, logs={}):
# self.val_losses.append(logs.get('val_loss'))
# self.val_mae.append(logs.get('val_mean_absolute_error'))
# self.val_ca.append(logs.get('val_categorical_accuracy'))
history = LossHistory()
如果使用下面代码进行简单的训练:
historyEpoch = seq.fit(noisy_movies[:15], shifted_movies[:15], batch_size=5, epochs=2, callbacks=[history], validation_split= 0.1)
输出结果为:
Train on 13 samples, validate on 2 samples
********** batch begin **********
logs: None
********** batch begin **********
Epoch 1/2
5/13 [==========>...................] - ETA: 13s - loss: 0.8663 - mean_absolute_error: 0.2967 - categorical_accuracy: 1.0000
********** batch end **********
logs: {'batch': 0, 'size': 5, 'loss': 0.86631656, 'mean_absolute_error': 0.29668817, 'categorical_accuracy': 1.0}
********** batch end **********
10/13 [======================>.......] - ETA: 3s - loss: 0.5942 - mean_absolute_error: 0.2795 - categorical_accuracy: 1.0000
********** batch end **********
logs: {'batch': 1, 'size': 5, 'loss': 0.32202613, 'mean_absolute_error': 0.27948833, 'categorical_accuracy': 1.0}
********** batch end **********
********** batch end **********
logs: {'batch': 2, 'size': 3, 'loss': 0.26741043, 'mean_absolute_error': 0.29003707, 'categorical_accuracy': 1.0}
********** batch end **********
13/13 [==============================] - 16s 1s/step - loss: 0.5188 - mean_absolute_error: 0.2900 - categorical_accuracy: 1.0000 - val_loss: 0.1700 - val_mean_absolute_error: 0.0426 - val_categorical_accuracy: 1.0000
Epoch 2/2
5/13 [==========>...................] - ETA: 7s - loss: 0.2456 - mean_absolute_error: 0.2516 - categorical_accuracy: 1.0000
********** batch end **********
logs: {'batch': 0, 'size': 5, 'loss': 0.24555318, 'mean_absolute_error': 0.25164387, 'categorical_accuracy': 1.0}
********** batch end **********
10/13 [======================>.......] - ETA: 2s - loss: 0.1849 - mean_absolute_error: 0.2533 - categorical_accuracy: 1.0000
********** batch end **********
logs: {'batch': 1, 'size': 5, 'loss': 0.1242722, 'mean_absolute_error': 0.25329992, 'categorical_accuracy': 1.0}
********** batch end **********
********** batch end **********
logs: {'batch': 2, 'size': 3, 'loss': 0.34640625, 'mean_absolute_error': 0.25142, 'categorical_accuracy': 1.0}
********** batch end **********
13/13 [==============================] - 12s 917ms/step - loss: 0.2222 - mean_absolute_error: 0.2514 - categorical_accuracy: 1.0000 - val_loss: 0.1548 - val_mean_absolute_error: 0.0434 - val_categorical_accuracy: 1.0000
继续输出histortEpoch.history:
histortEpoch.history
输出结果为:
{'val_loss': [0.16997461020946503, 0.15476879477500916],
'val_mean_absolute_error': [0.04261249303817749, 0.04339912533760071],
'val_categorical_accuracy': [1.0, 1.0],
'loss': [0.5187649795642266, 0.22218043414446023],
'mean_absolute_error': [0.29003707, 0.25142],
'categorical_accuracy': [1.0, 1.0]}
继续输出history.losses:
history.losses
输出结果为:
[0.86631656, 0.32202613, 0.26741043, 0.24555318, 0.1242722, 0.34640625]
其中的loss、mean_absolute_error、categorical_accuracy分别是训练第一轮、第二轮中的加权平均值(因为前两个 b a t c h _ s i z e = 5 batch\_size = 5 batch_size=5,最后一个 b a t c h _ s i z e = 3 batch\_size = 3 batch_size=3),val_loss、val_mean_absolute_error、val_categorical_accuracy的两个值分别是在第一轮迭代和第二轮迭代后,在测试集上测试出来的值。
加权计算过程如下:
0.5187649795642266 = 0.86631656 × 5 + 0.32202613 × 5 + 0.26741043 × 3 13 0.5187649795642266 = \frac{0.86631656\times5 + 0.32202613\times5+0.26741043\times3}{13} 0.5187649795642266=130.86631656×5+0.32202613×5+0.26741043×3
计算无误,验证成功