四、模型训练和评估

1. 模型配置

配置模型优化器、损失函数、评估器

model.compile(
    optimizer="rmsprop", 
    loss="sparse_categorical_crossentropy",
    metrics=["sparse_categorical_accuracy"],
	)

2. 内建方法

训练时对样本和类别加权

  • 模型训练:Model.fit()
  • 模型评估:Model.evaluate()
  • 模型预测: Model.predict()

2.1 模型训练

自定义回调函数

print("Fit model on training data")
history = model.fit(
    x_train,
    y_train,
    batch_size=64,
    epochs=2,
    # We pass some validation for monitoring validation loss and metrics at the end of each epoch
    validation_data=(x_val, y_val), 
)
# 打印模型每epoch模型的loss 和acc
history.history

2.2 评估模型

# 在测试集上评估模型
results = model.evaluate(x_test, y_test, batch_size=128)
print("test loss, test acc:", results)

# Generate predictions (probabilities -- the output of the last layer)
# on new data using `predict`
predictions = model.predict(x_test[:3])
print("predictions shape:", predictions.shape)

3. 自定义损失函数

深度学习论文中常见loss函数汇总

两种方法实现自定义loss function:自定义损失函数,需要对输入的label做one-hot编码。自定义Loss与metrics

  1. def loss_func(y_true,y_pred):

  2. 需要传入除y_true,y_pred额外的参数,这是需要继承 tf.keras.losses.Loss 类,使用两个方法:

  • __init__(self): accept parameters to pass during the call of your loss function
  • call(self, y_true, y_pred): use the targets (y_true) and the model predictions
    (y_pred) to compute the model’s loss
# 方法一
def custom_mean_squared_error(y_true, y_pred):
    return tf.math.reduce_mean(tf.square(y_true - y_pred))

#keras中定义loss,返回的是batch_size长度的tensor, 而不是像tensorflow中那样是一个scalar
model.compile(optimizer=keras.optimizers.Adam(), loss=custom_mean_squared_error)


y_train_one_hot = tf.one_hot(y_train, depth=10)   # We need to one-hot encode the labels to use MSE
model.fit(x_train, y_train_one_hot, batch_size=64, epochs=1)

# 方法二
class CustomMSE(keras.losses.Loss):
    def __init__(self, regularization_factor=0.1, name="custom_mse"):
        super().__init__(name=name)
        self.regularization_factor = regularization_factor

    def call(self, y_true, y_pred):
        mse = tf.math.reduce_mean(tf.square(y_true - y_pred))
        reg = tf.math.reduce_mean(tf.square(0.5 - y_pred))
        return mse + reg * self.regularization_factor

model.compile(optimizer=keras.optimizers.Adam(), loss=CustomMSE())

y_train_one_hot = tf.one_hot(y_train, depth=10)
model.fit(x_train, y_train_one_hot, batch_size=64, epochs=1)

4. 自定义训练过程

4.1 构建模型

import tensorflow  as tf
from tensorflow.keras.layers import Dense,Flatten,Conv2D
from tensorflow.keras import Model


train_ds=tf.data.Dataset.from_tensor_slices(
    (x_train,y_train)).shuffle(1000).batch(32)               
test_ds=tf.data.Dataset.from_tensor_slices((x_test,y_test)).batch(32)

通过继承Model构建模型

class Mymodel(Model):
    def __init__(self):
        super(Mymodel,self).__init__()
        self.conv1=Conv2D(32,3,activation='relu')
        self.flatten=Flatten()             # 在中间层不用写参数input_shape,模型能自动判定输入到该层的形状
        self.d1=Dense(128,activation='relu')
        self.d2=Dense(10)
    def call(self,x):
        x=self.conv1(x)
        x=self.flatten(x)
        x=self.d1(x)
        output=self.d2(x)
        return output


# 选择optimizer和loss function
loss_object=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
optimizer=tf.keras.optimizers.Adam()

Select metrics to measure the loss and the accuracy of the model. These metrics accumulate the values over epochs and then print the overall result.

train_loss=tf.keras.metrics.Mean(name='train_loss')
train_accuracy=tf.keras.metrics.SparseCategoricalAccuracy(name='train_accuracy')

test_loss=tf.keras.metrics.Mean(name='test_loss')
test_accuracy=tf.keras.metrics.SparseCategoricalAccuracy(name='test_accuracy')

4.2 使用tf.GradientTape 训练模型

@tf.function
def train_step(images,labels):
    with tf.GradientTape() as tape:   # 前向传播
        predictions=model(images,training=True) #  模型预测样本
        loss=loss_object(labels,predictions) # 计算损失函数
    # 求梯度
    gradients=tape.gradient(loss,model.trainable_variables) # 求偏导
    optimizer.apply_gradients(zip(gradients,model.trainable_variables))
    
    # 计算sample平均损失函数
    train_loss(loss) 
    #计算模型准确率
    train_accuracy(labels,predictions)

测试集校验模型效果

@tf.function
def test_step(images,labels):
    predictions=model(images,training=False)
    t_loss=loss_object(labels,predictions)  # 计算损失值
    
    # 求平均损失值
    test_loss(t_loss)
    test_accuracy(labels,predictions)

4.3 开始训练模型

EPOCHS=5

for epoch in range(EPOCHS):
    # 在下一个epoch开始前重置metrics
    train_loss.reset_states()
    train_accuracy.reset_states()
    test_loss.reset_states()
    test_accuracy.reset_states()
    
    for images,labels in train_ds:   # 训练模型,记录损失函数、和准确率
        train_step(images,labels)
    for test_images,test_labels in test_ds:
        test_step(test_images,test_labels)
    
    print(
        f'EPoch {epoch+1}, '
        f'Loss: {train_loss.result()}, '
        f'Accuracy: {train_accuracy.result()*100}, '
        f'Test Loss: {test_loss.result()}, '
        f'Test Accuracy: {test_accuracy.result()*100}'
    )

5. 案例

  1. FM原理与自定义实现
  2. DeepFM原理与自定义实现
  3. DSSM 理论与实践
  4. 共享层 or 模型
  5. Wide & Deep
  6. tf.nn.embedding_lookup && tf.nn.embedding_lookup_sparse
  7. 训练中出现 Nan 值
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值