TensorFlow2学习八、多层感知机实现

一、概念

1. 多层感知机:MLP(Multilayer Perceptron)

人工神经网络领域通常被称为神经网络或多层感知机,可能是最有用的神经网络类型。
感知机是单个神经元模型,用以组成复杂神经网络。它于1958年由Frank Rosenblatt第一次引入。单层感知器可以用来区分线性可分的数据,并且一定可以在有限的迭代次数中收敛。

在这里插入图片描述

2. 单层感知器示例

在这里插入图片描述

3. 多层感知机除了输入与输出层,中间可以有多个隐层,其中最简单的MLP只含一个隐层,即三层的结构,:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dtfYoqGh-1574813108796)(/uploads/20191125/afbd85f7a4c6d51b1bee0802deb1891f.png "在这里输入图片标题")]
多层感知机层与层之间是全连接的。

4. 激活函数

隐藏层与输入层是全连接的,假设输入层用向量X表示,则隐藏层的输出就是 f (W1X+b1),W1是权重(也叫连接系数),b1是偏置,
函数f 可以是常用的sigmoid函数或者tanh函数(激活函数)。激活函数,是为了让神经元引入非线性因素,使神经网络可以任意逼近任何非线性函数。

激活函数需要具备以下几点性质:

  1. 连续并可导(允许少数点上不可导)的非线性函数。可导的激活函数可以直接利用数值优化的方法来学习网络参 数。
  2. 激活函数及其导函数要尽可能的简单,有利于提高网络计算效率。
  3. 激活函数的导函数的值域要在一个合适的区间内,不能太大也不能太小,否则会影响训练的效率和稳定性。

常用的激活函数有sigmod、Tanh等。

二、keras的模型和层

下面使用模型类的编写一个线性模型: y_pred = a * X + b:

import tensorflow as tf

X = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
y = tf.constant([[10.0], [20.0]])

# 定义一个模型
# 继承 tf.keras.Model 后,就同时可以使用父类的若干方法和属性
class Linear(tf.keras.Model):
    # 模型初始化
    def __init__(self):
        super().__init__()
        self.dense = tf.keras.layers.Dense(
            units=1,
            activation=None,
            kernel_initializer=tf.zeros_initializer(),
            bias_initializer=tf.zeros_initializer()
        )
    # 模型调用
    def call(self, input):
        output = self.dense(input)
        return output

# 实例化类
model = Linear()
optimizer = tf.keras.optimizers.SGD(learning_rate=0.01)
for i in range(100):
    with tf.GradientTape() as tape:
        # 调用模型 y_pred = model(X) 而不是显式写出 y_pred = a * X + b
        y_pred = model(X)
        # 均方误差损失函数
        loss = tf.reduce_mean(tf.square(y_pred - y))
    # 使用 model.variables 这一属性直接获得模型中的所有变量
    grads = tape.gradient(loss, model.variables)
    optimizer.apply_gradients(grads_and_vars=zip(grads, model.variables))
print(model.variables)

在这里插入图片描述

  • 上面全连接层 tf.keras.layers.Dense 封装了 output = activation(tf.matmul(input, kernel) + bias) 这一线性变换 + 激活函数的计算操作
  • kernel 和 bias 是层中可训练的变量。
    假设输入张量的形状为 input = [batch_size, input_dim] ,经过全连接层,输出张量的形状为 [batch_size, units] 的二维张量。

三、多层感知机

主要分为4个步骤:

  1. 获取数据集: tf.keras.datasets
  2. 构建模型:tf.keras.Model 和 tf.keras.layers
  3. 训练模型:tf.keras.losses 计算损失函数,并使用 tf.keras.optimizer 优化模型
  4. 评估模型:tf.keras.metrics 计算评估指标

下面示例数据还是mnist数字手写体。

1. 加载数据

import tensorflow as tf
import numpy as np

class MNISTLoader():
    def __init__(self):
        mnist = tf.keras.datasets.mnist
        (self.train_data, self.train_label), (self.test_data, self.test_label) = mnist.load_data()
        # MNIST中的图像默认为uint8(0-255的数字)
        # 以下代码将其归一化到0-1之间的浮点数,并在最后增加一维作为颜色通道
        self.train_data = np.expand_dims(
            self.train_data.astype(
                np.float32) / 255.0,
            axis=-1)  											# [60000, 28, 28, 1]
        self.test_data = np.expand_dims(
            self.test_data.astype(
                np.float32) / 255.0,
            axis=-1)   											# [10000, 28, 28, 1]
        self.train_label = self.train_label.astype(np.int32)    # [60000]
        self.test_label = self.test_label.astype(np.int32)      # [10000]
        self.num_train_data, self.num_test_data = self.train_data.shape[0], self.test_data.shape[0]

    def get_batch(self, batch_size):
        # 从数据集中随机取出batch_size个元素并返回
        index = np.random.randint(0, np.shape(self.train_data)[0], batch_size)
        return self.train_data[index, :], self.train_label[index]

2. 构建模型

class MLP(tf.keras.Model):
    def __init__(self):
        super().__init__()
        # Flatten层将除第一维(batch_size)以外的维度展平
        self.flatten = tf.keras.layers.Flatten()
        # 全连接层
        self.dense1 = tf.keras.layers.Dense(units=100, activation=tf.nn.relu)
        self.dense2 = tf.keras.layers.Dense(units=10)

    def call(self, inputs):         # [batch_size, 28, 28, 1]
        x = self.flatten(inputs)    # [batch_size, 784]
        x = self.dense1(x)          # [batch_size, 100]
        x = self.dense2(x)          # [batch_size, 10]
        output = tf.nn.softmax(x)
        return output

3. 模型训练

num_epochs = 5		# 训练轮数
batch_size = 50		# 批大小
learning_rate = 0.001	# 学习率
model = MLP()								# 实例化模型
data_loader = MNISTLoader()						# 数据载入
optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)
num_batches = int(data_loader.num_train_data // batch_size * num_epochs)
for batch_index in range(num_batches):
	# 随机取一批训练数据
        X, y = data_loader.get_batch(batch_size)
        with tf.GradientTape() as tape:
            # 计算模型预测值
            y_pred = model(X)
            # 计算损失函数
            loss = tf.keras.losses.sparse_categorical_crossentropy(y_true=y, y_pred=y_pred)
            loss = tf.reduce_mean(loss)
            print("batch %d: loss %f" % (batch_index, loss.numpy()))
        # 计算模型变量的导数
        grads = tape.gradient(loss, model.variables)
        # 优化器更新模型参数以减小损失函数
        optimizer.apply_gradients(grads_and_vars=zip(grads, model.variables))

4. 评估模型

# 评估器
sparse_categorical_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()
# 迭代轮数
num_batches = int(data_loader.num_test_data // batch_size)
for batch_index in range(num_batches):
    start_index, end_index = batch_index * batch_size, (batch_index + 1) * batch_size
    # 模型预测的结果
    y_pred = model.predict(data_loader.test_data[start_index: end_index])
    sparse_categorical_accuracy.update_state(
        y_true=data_loader.test_label[start_index: end_index], y_pred=y_pred)
print("test accuracy: %f" % sparse_categorical_accuracy.result())

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程圈子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值