学习笔记-深度学习-了解核心Keras API

内容是对《Python深度学习》的摘录、理解、代码实践和遇到的问题。

层:深度学习的基础模块

神经网络的基本数据结构是层。层是一个数据处理模块,它接收一个或多个张量作为输入,输出一个或多个张量。有些层是无状态的,但大多数层具有状态,即层的权重。权重是利用随机梯度下降更新的一个或多个张量,其中包含神经网络学到的知识。

不同的张量格式(不同类型的数据)用不同的层来处理

简单的向量数据存储在形状为(samples, features)的2阶张量中,通常用密集链接层 densely connected layer(也叫全连接层fully connected layer密集层 dense layer)处理,对应于Keras的Dense类。

序列数据存储在形状为(samples, timesteps, features)的3阶张量中,通常用循环层 recurrent layer来处理,比如LSTM层或一维卷积层 Conv1D。

图像数据存储在4阶张量中,通常用二维卷积层 Conv2D来处理。

在Keras中构建深度学习模型,就是将相互兼容的层拼接在一起,建立有用的数据变化流程。

Keras的Layer基类

Layer是封装了状态(权重)和计算(一次向前传播)的对象。权重通常在build()中定义(也可以在构造函数__init__()中创建),计算则在call()中定义。

本部分还给出了简化版Dense层的实现代码和将call()和build()分开实现的原因(为了及时创建状态),提到了为了简化实现层的兼容性而采取的自动推断形状(动态构建层)等等知识。由于看不太懂暂且略过。

从层到模型

深度学习模型是由层构成的图,在Keras中就是Model类。

到目前为止接触过的只有Moldel的一个子类Sequential模型,它是层的简单堆叠,将单一输入映射为单一输出。

还有许多其他类型的更复杂的网络拓扑结构,如双分支 two-branch网络、多头multihead网络、残差连接等,之后会接触到。

模型的拓扑结构定义了一个假设空间,机器学习就是在预先定义的可能性空间内,利用反馈信号的指引,寻找特定输入数据的有用的表示。要从数据中学习,必须先对其进行假设,这些假设定义了可学习的内容。因此,假设空间的结构(模型架构)是非常重要的。它编码了我们对问题所做的假设,即模型的先验知识。举例来说,处理一个二分类问题时,如果采用的模型是由一个没有激活Dense层组成的(只进行纯仿射变换),那么潜台词就是已经默认这个两个类别是线性可分的。

编译步骤:配置学习过程

确定了模型架构后,还需要选定一下3个参数:

  • 损失函数(目标函数):在训练过程中需要将其最小化。它衡量的是当前任务是否成功。
  • 优化器:决定如何基于损失函数对神经网络进行更新。它执行的是随机梯度下降SGD的某个变体。
  • 指标:衡量成功的标准,在训练和验证过程中需要对其进行监控,如分类精度。与损失不同,训练不会直接基于这些指标做优化,因此该指标不需要是可微的。

选定了损失函数、优化器和指标,就可以使用内置方法compile()和fit()开始训练模型。

compile()

compile()方法的作用是配置训练过程,它接收的参数是optimizer(指定优化器)、loss(指定损失函数)和metrics(指定指标列表)

fit()

fit()方法执行训练循环,有以下关键参数:

       要训练的数据(输入和目标):这些数据通常以NumPy数组或TensotFlow Dataset对象的形式传入。

       训练轮数:训练循环应该在传入的数据上迭代多少次。

       每轮小批量梯度下降中使用的批量大小:在一次权重更新中,计算梯度所要考虑的训练样本的数量。

监控验证数据上的损失和指标

机器学习的目标是得到总体上表现良好的模型,特别是在模型没见过的数据上。想要查看模型在新数据上的性能,标准做法是保留训练数据的一个子集作为验证数据 validation data,不在这部分数据上训练模型,只用它来计算损失值和指标值。

实现方法是在fit()中使用validation_data参数,会在每一轮的最后输出在验证数据上的损失值和指标值(下面例子中的val_loss和val_binary_accuracy)

History = model.fit(train_images, train_labels, epochs=5, batch_size=128)

 

History = model.fit(train_images, train_labels, epochs=5, batch_size=128, validation_data=(test_images, test_labels))

 如果想在训练完成后计算验证损失和指标,可以用evaluate()方法。

evaluate()将对传入的数据进行批量迭代(批量大小为batch_size),并返回一个标量列表,其中第一个元素是验证损失,第二个元素是验证指标。如果模型没有指标,则只返回验证损失(不再是列表)。

需要注意直接写这么写可能会报错:

loss_and_metrics = model.evaluate(test_images, test_labels, batch_size=128)

Error polling for event status: failed to query event: CUDA_ERROR_ILLEGAL_ADDRESS: an illegal memory access was encountered

解决方法:

with tensorflow.device('/cpu:0'):

    loss_and_metrics = model.evaluate(test_images, test_labels, batch_size=128)

tf.one_hot()函数Windows GPU版本报错Error polling for event status: failed to query event: CUDA_ERROR_ILLEGAL_INSTRUCTION;Unexpected Event status: 1 - initial_h - 博客园 (cnblogs.com)

推断:在训练后使用模型

训练好了模型,可以使用它来对新的数据进行预测,这叫做推断 inference

方法1:

predictions = model(new_inputs)     # 接收一个NumPy数组或TensorFlow张量,返回一个TensorFlow张量

但是这种方法会一次性处理new_inputs中的所有输入,如果其中包含大量数据,这种方式可能需要超大内存,可能无法实行。

方法2:

使用predict()方法。它将小批量地迭代数据,并返回预测值组成的NumPy数组。与方法1不同,它还可以处理TensorFlow Dataset对象。

predictions = model.predict(new_inputs, batch_size=128)     # 接收一个NumPy数组或Dataset对象,返回一个NumPy数组

以MNIST数据集的训练为例实践

import tensorflow

import tensorflow_core.python.keras.losses

from tensorflow import keras

from tensorflow.keras import layers

from tensorflow.keras import losses

from tensorflow.keras.datasets import mnist

from tensorflow.python.keras.optimizers import rmsprop_v2



#   加载数据集并处理图像数据

(train_images, train_labels), (test_images, test_labels) = mnist.load_data()

train_images = train_images.reshape((60000, 28 * 28))

train_images = train_images.astype("float32") / 255

test_images = test_images.reshape((10000, 28 * 28))

test_images = test_images.astype("float32") / 255



#   利用层构建出模型

model = keras.Sequential([

    layers.Dense(512, activation="relu"),

    layers.Dense(10, activation="softmax")

])



#   配置训练过程

model.compile(optimizer=rmsprop_v2.RMSProp(learning_rate=0.01),

              loss=losses.SparseCategoricalCrossentropy(),

              # 注意写成loss=losses.sparse_categorical_crossentropy()会报错缺少参数

              metrics=[keras.metrics.BinaryAccuracy()])



#   执行训练循环

History = model.fit(train_images, train_labels, epochs=5, batch_size=128)



#   监控验证数据上的损失和指标

with tensorflow.device('/cpu:0'):

    loss_and_metrics = model.evaluate(test_images, test_labels, batch_size=128)

print(loss_and_metrics)



#   利用训练好的model预测test_images中的图像值,并输出前十个与标签比较(可以看出准确率很高)

predictions = model.predict(test_images, batch_size=128)     # 接收一个NumPy数组或Dataset对象,返回一个NumPy数组

for i in range(10):

    print(f'预测值为:{predictions[i].argmax()}')

    print(f'标签为:{test_labels[i]}')
 

遇到的问题:

TypeError: The added layer must be an instance of class Layer. Found: <tensorflow.python.keras.layers.core.Dense object at 0x0000017EBD3CEFC8>

keras 报错:TypeError: The added layer must be an instance of class Layer_翻滚的小@强的博客-CSDN博客

问题描述: 利用keras的Sequential堆叠layer时出现了TypeError: The added layer must be an instance of class Layer

解决方案: 检查keras的导入,如果出现使用tensorflow. keras方式引用和keras引用混合就会出现这个问题。

AttributeError: module 'tensorflow_core.keras.optimizers' has no attribute 'rmsprop'

解决 AttributeError: module ‘keras.optimizers‘ has no attribute ‘RMSprop‘ 和‘Adam‘ 报错问题_晓亮.的博客-CSDN博客

原因分析:发现优化器的调用方式发生了改变。

解决方案:

from tensorflow.python.keras.optimizers import rmsprop_v2

使用

optimizer =rmsprop_v2.rmsprop(learning_rate=1e-4)

而不是

optimizer = rmsprop(lr=1e-4) 或 optimizer = RMSprop(lr=1e-4)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值