短视频开发 Wendy Java开发手册 ssh命令 image express testing rxjs yii2 openssl 后台网站模板 java三维数组 bootstrap模态框传参 lora开发 python代码示例 python异常 javaswitch java正则 java案例 java基础教学 java重写和重载的区别 java基础课程 java中的数据结构 java时间转换 java怎么输出数组 java字符串操作 java文件读取 opengl编程指南 win7loader java电子书下载 matlab2016a安装教程 js删除数组指定元素 1660ti 福昕阅读器绿色版 win10有几个版本 王者荣耀自动刷冒险 上传附件 司司网吧 ppt格式刷怎么用 js刷新当前页
当前位置: 首页 > 学习教程  > python

tf.keras快速入门——自定义损失函数(二)

2021/2/6 22:21:33 文章标签: 测试文章如有侵权请发送至邮箱809451989@qq.com投诉后文章立即删除

在上篇tf.keras快速入门——自定义损失函数(一)中提到了函数式和继承tf.keras.losses.Loss以实例化子类式的两种损失函数的自定义方式。但是,在文末我们也提到了,这两种方式其实还有存在很大的局限性,故而在本文中将讨…

    在上篇tf.keras快速入门——自定义损失函数(一)中提到了函数式和继承tf.keras.losses.Loss以实例化子类式的两种损失函数的自定义方式。但是,在文末我们也提到了,这两种方式其实还有存在很大的局限性,故而在本文中将讨论另一种更加灵活的自定义损失函数的方式。
在复杂度&学习率&损失函数一文中,实现了这个过程,这里还是粘贴一个简单的例子:
定义损失函数为一个分段函数。当预测值大于真实值,我们认为对我们模型不利,即:
f ( y ^ , y ) = { 3 ( y ^ − y )      y ^ ⩾ y y − y ^      y ^ ⩽ y f(\hat y, y) = \left\{ \begin{matrix} 3(\hat y - y) \ \ \ \ \hat y \geqslant y \\ y - \hat y \ \ \ \ \hat y \leqslant y \end{matrix} \right. f(y^,y)={3(y^y)    y^yyy^    y^y

import tensorflow as tf
x = tf.random.normal([20, 2], mean=2, stddev=1, dtype=tf.float32)
y = [item1 + 2 * item2 for item1, item2 in x]
w = tf.Variable(tf.random.normal([2, 1], mean=0, stddev=1))

epoch = 5000
lr = 0.002
for epoch in range(epoch):
    with tf.GradientTape() as tape:
        y_hat = tf.matmul(x, w)
        loss = tf.reduce_mean(tf.where(tf.greater(y_hat, y), 3*(y_hat - y), y-y_hat))
    w_grad = tape.gradient(loss, w)
    w.assign_sub(lr * w_grad)

print(w.numpy().T) # [[0.73728406 0.83368826]]

这里,我们还是以鸢尾花分类为例,这里对它进行改造。结合前面所讲的自定义ModelLayer等进行。

class MyLayer(tf.keras.layers.Layer):
    def __init__(self, _shape, activation='relu'):
        super(MyLayer, self).__init__()
        self._shape = _shape
        self.activation = activation
    
    def build(self, input_shape):
        self.kernel = self.add_weight("kernel", shape=(int(input_shape[-1]), self._shape),initializer='random_normal',trainable=True)
        self.bias=self.add_weight(shape=(self._shape,),initializer='random_normal',trainable=True)
        
    def call(self, inputs):
        out = tf.matmul(inputs, self.kernel) + self.bias
        if self.activation == 'relu':
            out = tf.nn.relu(out)
        if self.activation == 'softmax':
            out = tf.nn.softmax(out)
        return out                       
import matplotlib.pyplot as plt
%matplotlib inline
import tensorflow as tf
from sklearn.datasets import load_iris
# 训练集和测试集的划分
from sklearn.model_selection import train_test_split

x_data = load_iris().data  # 特征,【花萼长度,花萼宽度,花瓣长度,花瓣宽度】
y_data = load_iris().target # 分类
x_train, x_test, y_train, y_test = train_test_split(x_data, y_data, test_size=0.30, random_state=42)


class MyModel(tf.keras.Model):
    def __init__(self, hidden_shape, output_shape):
        super(MyModel, self).__init__()
        self.layer1 = tf.keras.layers.Dense(hidden_shape, activation='relu')
        self.layer2 = tf.keras.layers.Dense(output_shape, activation='softmax')
        
    def call(self, inputs):
        h1 = self.layer1(inputs)
        out = self.layer2(h1)
        return out

model = MyModel(hidden_shape=4, output_shape=3)

train_loss = tf.keras.metrics.Mean(name='train_loss')
train_acc = tf.keras.metrics.CategoricalAccuracy(name='train_acc')
    
def train():
    with tf.GradientTape() as tape:
        # 1. 前向传播计算y
        out = model(x_train)
        y_train_one_hot = tf.one_hot(y_train, depth=3)
        # 2. 定义Loss
        loss = tf.losses.categorical_crossentropy(y_train_one_hot, out)
    gradients = tape.gradient(loss, model.trainable_variables)  # 反向求导
    tf.optimizers.Adam().apply_gradients(zip(gradients, model.trainable_variables))  # 参数更新
    
    train_loss(loss)  # train_loss.update_state(loss)
    train_acc(y_train_one_hot, out) # train_acc.update_state(y_train_one_hot, out)


history = dict()
for epoch in range(300):
    train_loss.reset_states()
    train_acc.reset_states()
    train()
    try:
        history['epoch'].append(epoch+1)
    except:
        history['epoch'] = [epoch+1]
    try:
        history['loss'].append(train_loss.result())
    except:
        history['loss'] = [train_loss.result()]
    try:
        history['acc'].append(train_acc.result())
    except:
        history['acc'] = [train_acc.result()]
    
    template = 'Epoch {}, loss: {}, acc: {}'
    print (template.format(epoch+1, train_loss.result(), train_acc.result()))

    
for key in history.keys():
    if key != 'epoch':
        plt.plot(history['epoch'], history[key])

在这里插入图片描述
内容参考:TensorFlow2.0 自定义损失函数


本文链接: http://www.dtmao.cc/news_show_2000019.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?