TensorFlow2.0 自定义损失函数

目录

头文件

1、数据集加载与处理

2、自定义深度神经网络模型

3、自损失函数

函数式

类式

实验结果


 

头文件:

import numpy as np
import tensorflow as tf

from tensorflow.keras.layers import Dense, Flatten, Conv2D, MaxPool2D
from tensorflow.keras import Model

1、数据集加载与处理

def load_dataset():
    mnist = np.load("mnist.npz")
    return mnist['x_train']/255.0, mnist['y_train'], mnist['x_test']/255.0, mnist['y_test']

x_train, y_train, x_test, y_test = load_dataset()

print (np.shape(x_train))

x_train = x_train[..., tf.newaxis]
x_test = x_test[..., tf.newaxis]

y_train = tf.one_hot(y_train, depth=10)
y_test = tf.one_hot(y_test, depth=10)

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

2、自定义深度神经网络模型

class MyModel(Model):
    def __init__(self, num_classes=10):
        super(MyModel, self).__init__(name='my_model')
        self.num_classes = num_classes

        self.conv1 = Conv2D(20, 3, activation='relu')
        self.pool1 = MaxPool2D(pool_size=(2, 2))
        self.conv2 = Conv2D(24, 3, activation='relu')
        self.pool2 = MaxPool2D(pool_size=(2, 2))
        self.flatten = Flatten()
        self.d1 = Dense(128, activation='relu')
        self.d2 = Dense(10)

    @tf.function(input_signature=[tf.TensorSpec([None, 28, 28, 1], tf.float32, name='inputs')])
    def call(self, inputs):
        x = self.conv1(inputs)
        x = self.pool1(x)
        x = self.conv2(x)
        x = self.pool2(x)
        x = self.flatten(x)
        x = self.d1(x)
        return self.d2(x)

3、自损失函数

函数式

def FocalLoss(gamma=2.0, alpha=0.25):
    def focal_loss_fixed(y_true, y_pred):
        y_pred = tf.nn.softmax(y_pred, axis=-1)
        eps = tf.keras.backend.epsilon()
        y_pred = tf.clip_by_value(y_pred, eps, 1.0)
        y_true = tf.cast(y_true, tf.float32)

        loss = -y_true * tf.math.pow(1 - y_pred, gamma) * tf.math.log(y_pred)
        loss = tf.reduce_sum(loss, axis=1)
        return loss
    return focal_loss_fixed

类式

class FocalLoss(tf.keras.losses.Loss):
    def __init__(self, gamma=2.0, alpha=0.25):
        super(FocalLoss, self).__init__()
        self.gamma = gamma
        self.alpha = alpha

    def call(self, y_true, y_pred):
        y_pred = tf.nn.softmax(y_pred, axis=-1)
        eps = tf.keras.backend.epsilon()
        y_pred = tf.clip_by_value(y_pred, eps, 1.0)
        y_true = tf.cast(y_true, tf.float32)

        loss = -y_true*tf.math.pow(1-y_pred, self.gamma)*tf.math.log(y_pred)
        loss = tf.reduce_sum(loss, axis=1)
        return loss

4、训练模型

def training_model():
    model = MyModel()
    #定义损失函数
    loss_obj = FocalLoss()
    optimizer = tf.keras.optimizers.Adam()

    train_loss = tf.keras.metrics.Mean(name='train_loss')
    train_acc = tf.keras.metrics.CategoricalAccuracy(name='train_acc')
    test_loss = tf.keras.metrics.Mean(name='test_loss')
    test_acc = tf.keras.metrics.CategoricalAccuracy(name='test_acc')

    def train_step(images, labels):
        with tf.GradientTape() as tape:
            predictions = model(images)
            loss = loss_obj(labels, predictions)

        gradients = tape.gradient(loss, model.trainable_variables)  # 反向求导
        optimizer.apply_gradients(zip(gradients, model.trainable_variables))  # 参数更新

        # train_loss(loss)
        # train_acc(labels, predictions)

    def test_step(images, labels):
        predictions = model(images)
        t_loss = loss_obj(labels, predictions)

        test_loss(t_loss)
        test_acc(labels, predictions)

    Epochs = 50
    for epoch in range(Epochs):
        # 在下一次epoch开始时,重置评估指标
        train_loss.reset_states()
        train_acc.reset_states()
        test_loss.reset_states()
        test_acc.reset_states()

        for images, labels in train_ds:
            train_step(images, labels)

        for images, labels in test_ds:
            test_step(images, labels)

        template = 'Epoch {}, Loss: {}, Acc: {}, TestAcc: {}'
        print (template.format(epoch+1, train_loss.result(), train_acc.result()*100, test_acc.result()*100))

实验结果:

Epoch 1, Loss: 0.0, Acc: 0.0, TestAcc: 97.64999389648438
Epoch 2, Loss: 0.0, Acc: 0.0, TestAcc: 98.5199966430664
...
...
# 有关Train数据集的ACC和Loss被我注释掉了,所以这里是0.0

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页