深度学习_08_1_Keras高层API&自定义层or网络

08_1_Keras高层API&自定义层or网络

Keras.Metrics(Keras高层API)

Keras != tf.keras

主要使用以下功能:

  • datasets
  • layers
  • losses
  • metrics
  • optimizers

Outline

在机器学习中,经常要记录loss、accuracy。它们至少是step或epoch平均的值,这样才能比较好反映training的状态。

新建res = [],每一个batch加一次loss。[loss1,loss2,…],随后打印res.avg,这样可以看出前后两次打印整个model的变化情况,这个功能叫做meter(测量表),Metrics表示测量的意思。

  • Metrics
  • update_state
  • result().numpy()
  • reset_states

如何使用:

  1. 新建Metrics
  2. 给其中添加数据,loss1, loss2 …
  3. 得到结果
  4. 清零

Step1.Build a meter

新建准确度meter:metrics.Accuracy()

新建平均值:metrics.Mean()

在这里插入图片描述

Step2.Update data

往测量尺中添加数据

添加loss:loss_meter.update_state(loss)

添加acc:acc_meter.update_state(y,pred) #把真实的y和预测的y添加后会自动计算acc

在这里插入图片描述

Step3.Get Average data

loss_meter.result().numpy()

acc_meter.result().numpy()

在这里插入图片描述

Step4.Clear buffer

loss_meter.reset_states()

acc_meter.reset_states()

在这里插入图片描述

实战:

import  tensorflow as tf
from    tensorflow.keras import datasets, layers, optimizers, Sequential, metrics

def preprocess(x, y):
    x = tf.cast(x, dtype=tf.float32) / 255.
    y = tf.cast(y, dtype=tf.int32)
    return x,y

batchsz = 128
(x, y), (x_val, y_val) = datasets.mnist.load_data()
print('datasets:', x.shape, y.shape, x.min(), x.max())

db = tf.data.Dataset.from_tensor_slices((x,y))
db = db.map(preprocess).shuffle(60000).batch(batchsz).repeat(10)

ds_val = tf.data.Dataset.from_tensor_slices((x_val, y_val))
ds_val = ds_val.map(preprocess).batch(batchsz) 

network = Sequential([layers.Dense(256, activation='relu'),
                     layers.Dense(128, activation='relu'),
                     layers.Dense(64, activation='relu'),
                     layers.Dense(32, activation='relu'),
                     layers.Dense(10)])
network.build(input_shape=(None, 28*28))
network.summary()

optimizer = optimizers.Adam(lr=0.01)

####创建两个meter
acc_meter = metrics.Accuracy()
loss_meter = metrics.Mean()

for step, (x,y) in enumerate(db):
    with tf.GradientTape() as tape:
        # [b, 28, 28] => [b, 784]
        x = tf.reshape(x, (-1, 28*28))
        # [b, 784] => [b, 10]
        out = network(x)
        # [b] => [b, 10]
        y_onehot = tf.one_hot(y, depth=10) 
        # [b]
        loss = tf.reduce_mean(tf.losses.categorical_crossentropy(y_onehot, out, from_logits=True))
	    ####添加loss
        loss_meter.update_state(loss)

    grads = tape.gradient(loss, network.trainable_variables)
    optimizer.apply_gradients(zip(grads, network.trainable_variables))

    if step % 100 == 0:
	    ####求平均值
        print(step, 'loss:', loss_meter.result().numpy()) 
        ####清空meter
        loss_meter.reset_states()

    # evaluate
    if step % 500 == 0:
        ####两种方式,自己计算或者meter接口实现
        total, total_correct = 0., 0
        acc_meter.reset_states()

        for step, (x, y) in enumerate(ds_val): 
            # [b, 28, 28] => [b, 784]
            x = tf.reshape(x, (-1, 28*28))
            # [b, 784] => [b, 10]
            out = network(x) 

            # [b, 10] => [b] 
            pred = tf.argmax(out, axis=1) 
            pred = tf.cast(pred, dtype=tf.int32)
            # bool type 
            correct = tf.equal(pred, y)
            # bool tensor => int tensor => numpy
            ####累计正确值
            total_correct += tf.reduce_sum(tf.cast(correct, dtype=tf.int32)).numpy()
            ####累计总数
            total += x.shape[0]
		   ####meter接口实现
            acc_meter.update_state(y, pred)

        print(step, 'Evaluate Acc:', total_correct/total, acc_meter.result().numpy())

Compile&Fit(Keras高层API)

Outline

  • Compile
    • 类似装载的功能,指定training的loss的选择、优化器的选择、评估指标的选择
  • Fit
    • Compile后,通过Fit完成一系列标准的创建流程
  • Evaluate
    • 在test/evaluat dataset进行测试
  • Predict
    • 完成新的sample预测

之前标准的创建流程:

Individual loss and optimize(过去的loss、优化代码)

有些流程在不同深度学习代码是一样的,因此Keras提供了标准步骤的接口:Compile&fit

在这里插入图片描述

Now

指定优化器为Adam;loss为category loss;测试的指标为标准的accuracy

在这里插入图片描述

回顾老代码:

loss指定了;acc指定了;优化器指定了

还没指定:for x,y in db;网络forward的过程

在这里插入图片描述

之前的写法:

在这里插入图片描述

现在的写法:

还没有实现测试test。

在这里插入图片描述

Standard Progressbar(标准打印信息)

在这里插入图片描述


Individual evaluation(过去的测试代码)

衡量模型的性能。测试的epoch为1,测试需要指定测试集

在这里插入图片描述

Now

指定metrics、validation_data、validation_freq(每多少个epoch做一次validation)

在这里插入图片描述

Evaluation(输出)

前面2个是train loss/accuracy,后面2个是test loss/accuracy

在这里插入图片描述


Test

evaluate和fit中的validation是一样的,区别在fit的validation是training中间进行的,中间如果test-acc > 0.99 -> save -> break(early stopping)。

evaluate相当于一次测试,并且ds_val也可以用其他的测试集。

在这里插入图片描述

evaluate的输出:

在这里插入图片描述


Predict(预测)

network.predict(x)或network(x)

在这里插入图片描述

自定义网络

Outline

  • keras.Sequential
    • 容器,串联层
  • keras.layers.Layer
  • keras.Model

keras.Sequential

创建参数w和b:

  • network.build(input_shape=(None,28*28)) #一般这样,前期可打印-summary
  • 或直接network(x)

在这里插入图片描述

管理参数:

  • model.trainable_variables [w1,b1,w2,b2,…w5,b5]
  • model.call() call Dense1 Dense2,forward求更新偏导自动喂

在这里插入图片描述

Layer/Model

需要继承keras.layers.Layer/keras.Model

如果需要自定义层

​ 需要继承自Layer类,并且实现以下两个函数:

  1. __init__

  2. call

model(x)其实是调用了model.__call__() -> 调用call()方法

(其实Sequential也是继承自Model类)

Model类还有compile/fir/evaluate/predict接口

在这里插入图片描述

实现自定义层的例子:

标准的Dense层:layers.Dense(512),如果build([None,784]),则w:[784,512] b[512]

自己实现MyDense

  1. 继承自layers.Layer
  2. 实现__init__call

其中__init__中参数的名字’w’和’b’基本上没什么意义;w的[inp_dim,outp_dim]和我们用的相似;self.add_variable而不是简单的constant是为了让变量能够在模型中运算。

call中training参数表示你是在training还是test。

在这里插入图片描述

自定义网络

继承自keras.Model。图中的call的功能和Sequential类似,不过它内部还能加更多的操作(例如x=x-1)

在这里插入图片描述

实战:自定义层和网络

import  tensorflow as tf
from    tensorflow.keras import datasets, layers, optimizers, Sequential, metrics
from 	tensorflow import keras

def preprocess(x, y):
    """
    x is a simple image, not a batch
    """
    x = tf.cast(x, dtype=tf.float32) / 255.
    x = tf.reshape(x, [28*28])
    y = tf.cast(y, dtype=tf.int32)
    y = tf.one_hot(y, depth=10)
    return x,y

batchsz = 128
(x, y), (x_val, y_val) = datasets.mnist.load_data()
print('datasets:', x.shape, y.shape, x.min(), x.max())

db = tf.data.Dataset.from_tensor_slices((x,y))
db = db.map(preprocess).shuffle(60000).batch(batchsz)
ds_val = tf.data.Dataset.from_tensor_slices((x_val, y_val))
ds_val = ds_val.map(preprocess).batch(batchsz) 

sample = next(iter(db))
print(sample[0].shape, sample[1].shape)

network = Sequential([layers.Dense(256, activation='relu'),
                     layers.Dense(128, activation='relu'),
                     layers.Dense(64, activation='relu'),
                     layers.Dense(32, activation='relu'),
                     layers.Dense(10)])
network.build(input_shape=(None, 28*28))
network.summary()
####自己定义的层
class MyDense(layers.Layer):
	def __init__(self, inp_dim, outp_dim):
		super(MyDense, self).__init__()
		self.kernel = self.add_weight('w', [inp_dim, outp_dim])
		self.bias = self.add_weight('b', [outp_dim])
        
	def call(self, inputs, training=None):
		out = inputs @ self.kernel + self.bias
		return out 
####自己定义的模型
class MyModel(keras.Model):
	def __init__(self):
		super(MyModel, self).__init__()
		self.fc1 = MyDense(28*28, 256)
		self.fc2 = MyDense(256, 128)
		self.fc3 = MyDense(128, 64)
		self.fc4 = MyDense(64, 32)
		self.fc5 = MyDense(32, 10)

	def call(self, inputs, training=None):
		x = self.fc1(inputs)
		x = tf.nn.relu(x)
		x = self.fc2(x)
		x = tf.nn.relu(x)
		x = self.fc3(x)
		x = tf.nn.relu(x)
		x = self.fc4(x)
		x = tf.nn.relu(x)
		x = self.fc5(x) 
		return x
####新建自己的模型
network = MyModel()
#优化模型
network.compile(optimizer=optimizers.Adam(lr=0.01),
		loss=tf.losses.CategoricalCrossentropy(from_logits=True),
		metrics=['accuracy']
	)
#测试模型
network.fit(db, epochs=5, validation_data=ds_val,
              validation_freq=2)
 
network.evaluate(ds_val)

sample = next(iter(ds_val))
x = sample[0]
y = sample[1] # one-hot
pred = network.predict(x) # [b, 10]
# convert back to number 
y = tf.argmax(y, axis=1)
pred = tf.argmax(pred, axis=1)

print(pred)
print(y)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值