TensorFlow2.0使用keras訓(xùn)練模型的實(shí)現(xiàn)
1.一般的模型構(gòu)造、訓(xùn)練、測試流程
# 模型構(gòu)造 inputs = keras.Input(shape=(784,), name='mnist_input') h1 = layers.Dense(64, activation='relu')(inputs) h1 = layers.Dense(64, activation='relu')(h1) outputs = layers.Dense(10, activation='softmax')(h1) model = keras.Model(inputs, outputs) # keras.utils.plot_model(model, 'net001.png', show_shapes=True) model.compile(optimizer=keras.optimizers.RMSprop(), loss=keras.losses.SparseCategoricalCrossentropy(), metrics=[keras.metrics.SparseCategoricalAccuracy()]) # 載入數(shù)據(jù) (x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data() x_train = x_train.reshape(60000, 784).astype('float32') /255 x_test = x_test.reshape(10000, 784).astype('float32') /255 x_val = x_train[-10000:] y_val = y_train[-10000:] x_train = x_train[:-10000] y_train = y_train[:-10000] # 訓(xùn)練模型 history = model.fit(x_train, y_train, batch_size=64, epochs=3, validation_data=(x_val, y_val)) print('history:') print(history.history) result = model.evaluate(x_test, y_test, batch_size=128) print('evaluate:') print(result) pred = model.predict(x_test[:2]) print('predict:') print(pred)
2.自定義損失和指標(biāo)
自定義指標(biāo)只需繼承Metric類, 并重寫一下函數(shù)
_init_(self),初始化。
update_state(self,y_true,y_pred,sample_weight = None),它使用目標(biāo)y_true和模型預(yù)測y_pred來更新狀態(tài)變量。
result(self),它使用狀態(tài)變量來計(jì)算最終結(jié)果。
reset_states(self),重新初始化度量的狀態(tài)。
# 這是一個(gè)簡單的示例,顯示如何實(shí)現(xiàn)CatgoricalTruePositives指標(biāo),該指標(biāo)計(jì)算正確分類為屬于給定類的樣本數(shù)量 class CatgoricalTruePostives(keras.metrics.Metric): def __init__(self, name='binary_true_postives', **kwargs): super(CatgoricalTruePostives, self).__init__(name=name, **kwargs) self.true_postives = self.add_weight(name='tp', initializer='zeros') def update_state(self, y_true, y_pred, sample_weight=None): y_pred = tf.argmax(y_pred) y_true = tf.equal(tf.cast(y_pred, tf.int32), tf.cast(y_true, tf.int32)) y_true = tf.cast(y_true, tf.float32) if sample_weight is not None: sample_weight = tf.cast(sample_weight, tf.float32) y_true = tf.multiply(sample_weight, y_true) return self.true_postives.assign_add(tf.reduce_sum(y_true)) def result(self): return tf.identity(self.true_postives) def reset_states(self): self.true_postives.assign(0.) model.compile(optimizer=keras.optimizers.RMSprop(1e-3), loss=keras.losses.SparseCategoricalCrossentropy(), metrics=[CatgoricalTruePostives()]) model.fit(x_train, y_train, batch_size=64, epochs=3)
# 以定義網(wǎng)絡(luò)層的方式添加網(wǎng)絡(luò)loss class ActivityRegularizationLayer(layers.Layer): def call(self, inputs): self.add_loss(tf.reduce_sum(inputs) * 0.1) return inputs inputs = keras.Input(shape=(784,), name='mnist_input') h1 = layers.Dense(64, activation='relu')(inputs) h1 = ActivityRegularizationLayer()(h1) h1 = layers.Dense(64, activation='relu')(h1) outputs = layers.Dense(10, activation='softmax')(h1) model = keras.Model(inputs, outputs) # keras.utils.plot_model(model, 'net001.png', show_shapes=True) model.compile(optimizer=keras.optimizers.RMSprop(), loss=keras.losses.SparseCategoricalCrossentropy(), metrics=[keras.metrics.SparseCategoricalAccuracy()]) model.fit(x_train, y_train, batch_size=32, epochs=1)
# 也可以以定義網(wǎng)絡(luò)層的方式添加要統(tǒng)計(jì)的metric class MetricLoggingLayer(layers.Layer): def call(self, inputs): self.add_metric(keras.backend.std(inputs), name='std_of_activation', aggregation='mean') return inputs inputs = keras.Input(shape=(784,), name='mnist_input') h1 = layers.Dense(64, activation='relu')(inputs) h1 = MetricLoggingLayer()(h1) h1 = layers.Dense(64, activation='relu')(h1) outputs = layers.Dense(10, activation='softmax')(h1) model = keras.Model(inputs, outputs) # keras.utils.plot_model(model, 'net001.png', show_shapes=True) model.compile(optimizer=keras.optimizers.RMSprop(), loss=keras.losses.SparseCategoricalCrossentropy(), metrics=[keras.metrics.SparseCategoricalAccuracy()]) model.fit(x_train, y_train, batch_size=32, epochs=1)
# 也可以直接在model上面加 # 也可以以定義網(wǎng)絡(luò)層的方式添加要統(tǒng)計(jì)的metric class MetricLoggingLayer(layers.Layer): def call(self, inputs): self.add_metric(keras.backend.std(inputs), name='std_of_activation', aggregation='mean') return inputs inputs = keras.Input(shape=(784,), name='mnist_input') h1 = layers.Dense(64, activation='relu')(inputs) h2 = layers.Dense(64, activation='relu')(h1) outputs = layers.Dense(10, activation='softmax')(h2) model = keras.Model(inputs, outputs) model.add_metric(keras.backend.std(inputs), name='std_of_activation', aggregation='mean') model.add_loss(tf.reduce_sum(h1)*0.1) # keras.utils.plot_model(model, 'net001.png', show_shapes=True) model.compile(optimizer=keras.optimizers.RMSprop(), loss=keras.losses.SparseCategoricalCrossentropy(), metrics=[keras.metrics.SparseCategoricalAccuracy()]) model.fit(x_train, y_train, batch_size=32, epochs=1)
處理使用validation_data傳入測試數(shù)據(jù),還可以使用validation_split劃分驗(yàn)證數(shù)據(jù)
ps:validation_split只能在用numpy數(shù)據(jù)訓(xùn)練的情況下使用
model.fit(x_train, y_train, batch_size=32, epochs=1, validation_split=0.2)
3.使用tf.data構(gòu)造數(shù)據(jù)
def get_compiled_model(): inputs = keras.Input(shape=(784,), name='mnist_input') h1 = layers.Dense(64, activation='relu')(inputs) h2 = layers.Dense(64, activation='relu')(h1) outputs = layers.Dense(10, activation='softmax')(h2) model = keras.Model(inputs, outputs) model.compile(optimizer=keras.optimizers.RMSprop(), loss=keras.losses.SparseCategoricalCrossentropy(), metrics=[keras.metrics.SparseCategoricalAccuracy()]) return model model = get_compiled_model() train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)) train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64) val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val)) val_dataset = val_dataset.batch(64) # model.fit(train_dataset, epochs=3) # steps_per_epoch 每個(gè)epoch只訓(xùn)練幾步 # validation_steps 每次驗(yàn)證,驗(yàn)證幾步 model.fit(train_dataset, epochs=3, steps_per_epoch=100, validation_data=val_dataset, validation_steps=3)
4.樣本權(quán)重和類權(quán)重
“樣本權(quán)重”數(shù)組是一個(gè)數(shù)字?jǐn)?shù)組,用于指定批處理中每個(gè)樣本在計(jì)算總損失時(shí)應(yīng)具有多少權(quán)重。 它通常用于不平衡的分類問題(這個(gè)想法是為了給予很少見的類更多的權(quán)重)。 當(dāng)使用的權(quán)重是1和0時(shí),該數(shù)組可以用作損失函數(shù)的掩碼(完全丟棄某些樣本對(duì)總損失的貢獻(xiàn))。
“類權(quán)重”dict是同一概念的更具體的實(shí)例:它將類索引映射到應(yīng)該用于屬于該類的樣本的樣本權(quán)重。 例如,如果類“0”比數(shù)據(jù)中的類“1”少兩倍,則可以使用class_weight = {0:1.,1:0.5}。
# 增加第5類的權(quán)重 import numpy as np # 樣本權(quán)重 model = get_compiled_model() class_weight = {i:1.0 for i in range(10)} class_weight[5] = 2.0 print(class_weight) model.fit(x_train, y_train, class_weight=class_weight, batch_size=64, epochs=4) # 類權(quán)重 model = get_compiled_model() sample_weight = np.ones(shape=(len(y_train),)) sample_weight[y_train == 5] = 2.0 model.fit(x_train, y_train, sample_weight=sample_weight, batch_size=64, epochs=4)
# tf.data數(shù)據(jù) model = get_compiled_model() sample_weight = np.ones(shape=(len(y_train),)) sample_weight[y_train == 5] = 2.0 train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train, sample_weight)) train_dataset = train_dataset.shuffle(buffer_size=1024).batch(64) val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val)) val_dataset = val_dataset.batch(64) model.fit(train_dataset, epochs=3, )
5.多輸入多輸出模型
image_input = keras.Input(shape=(32, 32, 3), name='img_input') timeseries_input = keras.Input(shape=(None, 10), name='ts_input') x1 = layers.Conv2D(3, 3)(image_input) x1 = layers.GlobalMaxPooling2D()(x1) x2 = layers.Conv1D(3, 3)(timeseries_input) x2 = layers.GlobalMaxPooling1D()(x2) x = layers.concatenate([x1, x2]) score_output = layers.Dense(1, name='score_output')(x) class_output = layers.Dense(5, activation='softmax', name='class_output')(x) model = keras.Model(inputs=[image_input, timeseries_input], outputs=[score_output, class_output]) keras.utils.plot_model(model, 'multi_input_output_model.png' , show_shapes=True)
# 可以為模型指定不同的loss和metrics model.compile( optimizer=keras.optimizers.RMSprop(1e-3), loss=[keras.losses.MeanSquaredError(), keras.losses.CategoricalCrossentropy()]) # 還可以指定loss的權(quán)重 model.compile( optimizer=keras.optimizers.RMSprop(1e-3), loss={'score_output': keras.losses.MeanSquaredError(), 'class_output': keras.losses.CategoricalCrossentropy()}, metrics={'score_output': [keras.metrics.MeanAbsolutePercentageError(), keras.metrics.MeanAbsoluteError()], 'class_output': [keras.metrics.CategoricalAccuracy()]}, loss_weight={'score_output': 2., 'class_output': 1.}) # 可以把不需要傳播的loss置0 model.compile( optimizer=keras.optimizers.RMSprop(1e-3), loss=[None, keras.losses.CategoricalCrossentropy()]) # Or dict loss version model.compile( optimizer=keras.optimizers.RMSprop(1e-3), loss={'class_output': keras.losses.CategoricalCrossentropy()})
6.使用回 調(diào)
Keras中的回調(diào)是在訓(xùn)練期間(在epoch開始時(shí),batch結(jié)束時(shí),epoch結(jié)束時(shí)等)在不同點(diǎn)調(diào)用的對(duì)象,可用于實(shí)現(xiàn)以下行為:
- 在培訓(xùn)期間的不同時(shí)間點(diǎn)進(jìn)行驗(yàn)證(超出內(nèi)置的每個(gè)時(shí)期驗(yàn)證)
- 定期檢查模型或超過某個(gè)精度閾值
- 在訓(xùn)練似乎平穩(wěn)時(shí)改變模型的學(xué)習(xí)率
- 在訓(xùn)練似乎平穩(wěn)時(shí)對(duì)頂層進(jìn)行微調(diào)
- 在培訓(xùn)結(jié)束或超出某個(gè)性能閾值時(shí)發(fā)送電子郵件或即時(shí)消息通知等等。
可使用的內(nèi)置回調(diào)有
- ModelCheckpoint:定期保存模型。
- EarlyStopping:當(dāng)訓(xùn)練不再改進(jìn)驗(yàn)證指標(biāo)時(shí)停止培訓(xùn)。
- TensorBoard:定期編寫可在TensorBoard中顯示的模型日志(更多細(xì)節(jié)見“可視化”)。
- CSVLogger:將丟失和指標(biāo)數(shù)據(jù)流式傳輸?shù)紺SV文件。
- 等等
6.1回調(diào)使用
model = get_compiled_model() callbacks = [ keras.callbacks.EarlyStopping( # Stop training when `val_loss` is no longer improving monitor='val_loss', # "no longer improving" being defined as "no better than 1e-2 less" min_delta=1e-2, # "no longer improving" being further defined as "for at least 2 epochs" patience=2, verbose=1) ] model.fit(x_train, y_train, epochs=20, batch_size=64, callbacks=callbacks, validation_split=0.2)
# checkpoint模型回調(diào) model = get_compiled_model() check_callback = keras.callbacks.ModelCheckpoint( filepath='mymodel_{epoch}.h5', save_best_only=True, monitor='val_loss', verbose=1 ) model.fit(x_train, y_train, epochs=3, batch_size=64, callbacks=[check_callback], validation_split=0.2)
# 動(dòng)態(tài)調(diào)整學(xué)習(xí)率 initial_learning_rate = 0.1 lr_schedule = keras.optimizers.schedules.ExponentialDecay( initial_learning_rate, decay_steps=10000, decay_rate=0.96, staircase=True ) optimizer = keras.optimizers.RMSprop(learning_rate=lr_schedule)
# 使用tensorboard tensorboard_cbk = keras.callbacks.TensorBoard(log_dir='./full_path_to_your_logs') model.fit(x_train, y_train, epochs=5, batch_size=64, callbacks=[tensorboard_cbk], validation_split=0.2)
6.2創(chuàng)建自己的回調(diào)方法
class LossHistory(keras.callbacks.Callback): def on_train_begin(self, logs): self.losses = [] def on_epoch_end(self, batch, logs): self.losses.append(logs.get('loss')) print('\nloss:',self.losses[-1]) model = get_compiled_model() callbacks = [ LossHistory() ] model.fit(x_train, y_train, epochs=3, batch_size=64, callbacks=callbacks, validation_split=0.2)
7.自己構(gòu)造訓(xùn)練和驗(yàn)證循環(huán)
# Get the model. inputs = keras.Input(shape=(784,), name='digits') x = layers.Dense(64, activation='relu', name='dense_1')(inputs) x = layers.Dense(64, activation='relu', name='dense_2')(x) outputs = layers.Dense(10, activation='softmax', name='predictions')(x) model = keras.Model(inputs=inputs, outputs=outputs) # Instantiate an optimizer. optimizer = keras.optimizers.SGD(learning_rate=1e-3) # Instantiate a loss function. loss_fn = keras.losses.SparseCategoricalCrossentropy() # Prepare the training dataset. batch_size = 64 train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)) train_dataset = train_dataset.shuffle(buffer_size=1024).batch(batch_size) # 自己構(gòu)造循環(huán) for epoch in range(3): print('epoch: ', epoch) for step, (x_batch_train, y_batch_train) in enumerate(train_dataset): # 開一個(gè)gradient tape, 計(jì)算梯度 with tf.GradientTape() as tape: logits = model(x_batch_train) loss_value = loss_fn(y_batch_train, logits) grads = tape.gradient(loss_value, model.trainable_variables) optimizer.apply_gradients(zip(grads, model.trainable_variables)) if step % 200 == 0: print('Training loss (for one batch) at step %s: %s' % (step, float(loss_value))) print('Seen so far: %s samples' % ((step + 1) * 64))
# 訓(xùn)練并驗(yàn)證 # Get model inputs = keras.Input(shape=(784,), name='digits') x = layers.Dense(64, activation='relu', name='dense_1')(inputs) x = layers.Dense(64, activation='relu', name='dense_2')(x) outputs = layers.Dense(10, activation='softmax', name='predictions')(x) model = keras.Model(inputs=inputs, outputs=outputs) # Instantiate an optimizer to train the model. optimizer = keras.optimizers.SGD(learning_rate=1e-3) # Instantiate a loss function. loss_fn = keras.losses.SparseCategoricalCrossentropy() # Prepare the metrics. train_acc_metric = keras.metrics.SparseCategoricalAccuracy() val_acc_metric = keras.metrics.SparseCategoricalAccuracy() # Prepare the training dataset. batch_size = 64 train_dataset = tf.data.Dataset.from_tensor_slices((x_train, y_train)) train_dataset = train_dataset.shuffle(buffer_size=1024).batch(batch_size) # Prepare the validation dataset. val_dataset = tf.data.Dataset.from_tensor_slices((x_val, y_val)) val_dataset = val_dataset.batch(64) # Iterate over epochs. for epoch in range(3): print('Start of epoch %d' % (epoch,)) # Iterate over the batches of the dataset. for step, (x_batch_train, y_batch_train) in enumerate(train_dataset): with tf.GradientTape() as tape: logits = model(x_batch_train) loss_value = loss_fn(y_batch_train, logits) grads = tape.gradient(loss_value, model.trainable_variables) optimizer.apply_gradients(zip(grads, model.trainable_variables)) # Update training metric. train_acc_metric(y_batch_train, logits) # Log every 200 batches. if step % 200 == 0: print('Training loss (for one batch) at step %s: %s' % (step, float(loss_value))) print('Seen so far: %s samples' % ((step + 1) * 64)) # Display metrics at the end of each epoch. train_acc = train_acc_metric.result() print('Training acc over epoch: %s' % (float(train_acc),)) # Reset training metrics at the end of each epoch train_acc_metric.reset_states() # Run a validation loop at the end of each epoch. for x_batch_val, y_batch_val in val_dataset: val_logits = model(x_batch_val) # Update val metrics val_acc_metric(y_batch_val, val_logits) val_acc = val_acc_metric.result() val_acc_metric.reset_states() print('Validation acc: %s' % (float(val_acc),))
## 添加自己構(gòu)造的loss, 每次只能看到最新一次訓(xùn)練增加的loss class ActivityRegularizationLayer(layers.Layer): def call(self, inputs): self.add_loss(1e-2 * tf.reduce_sum(inputs)) return inputs inputs = keras.Input(shape=(784,), name='digits') x = layers.Dense(64, activation='relu', name='dense_1')(inputs) # Insert activity regularization as a layer x = ActivityRegularizationLayer()(x) x = layers.Dense(64, activation='relu', name='dense_2')(x) outputs = layers.Dense(10, activation='softmax', name='predictions')(x) model = keras.Model(inputs=inputs, outputs=outputs) logits = model(x_train[:64]) print(model.losses) logits = model(x_train[:64]) logits = model(x_train[64: 128]) logits = model(x_train[128: 192]) print(model.losses)
# 將loss添加進(jìn)求導(dǎo)中 optimizer = keras.optimizers.SGD(learning_rate=1e-3) for epoch in range(3): print('Start of epoch %d' % (epoch,)) for step, (x_batch_train, y_batch_train) in enumerate(train_dataset): with tf.GradientTape() as tape: logits = model(x_batch_train) loss_value = loss_fn(y_batch_train, logits) # Add extra losses created during this forward pass: loss_value += sum(model.losses) grads = tape.gradient(loss_value, model.trainable_variables) optimizer.apply_gradients(zip(grads, model.trainable_variables)) # Log every 200 batches. if step % 200 == 0: print('Training loss (for one batch) at step %s: %s' % (step, float(loss_value))) print('Seen so far: %s samples' % ((step + 1) * 64))
到此這篇關(guān)于TensorFlow2.0使用keras訓(xùn)練模型的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)TensorFlow2.0 keras訓(xùn)練模型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python如何根據(jù)字幕文件自動(dòng)給視頻添加字幕效果
視頻中字幕的重要性不用多說了,下面這篇文章主要給大家介紹了關(guān)于Python如何根據(jù)字幕文件自動(dòng)給視頻添加字幕效果的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-02-02Python實(shí)現(xiàn)將字典內(nèi)容寫入json文件
這篇文章主要為大家詳細(xì)介紹了如何利用Python語言實(shí)現(xiàn)將字典內(nèi)容寫入json文件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-08-08使用pandas或numpy處理數(shù)據(jù)中的空值(np.isnan()/pd.isnull())
這篇文章主要介紹了使用pandas或numpy處理數(shù)據(jù)中的空值(np.isnan()/pd.isnull()),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05使用 Python 實(shí)現(xiàn)文件遞歸遍歷的三種方式
這篇文章主要介紹了使用 Python 實(shí)現(xiàn)文件遞歸遍歷的三種方式,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-07-07python 對(duì)多個(gè)csv文件分別進(jìn)行處理的方法
今天小編就為大家分享一篇python 對(duì)多個(gè)csv文件分別進(jìn)行處理的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-01-01