0
点赞
收藏
分享

微信扫一扫

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

一、概念

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

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

TensorFlow2学习八、多层感知机实现_全连接

2. 单层感知器示例

TensorFlow2学习八、多层感知机实现_全连接_02

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

TensorFlow2学习八、多层感知机实现_激活函数_03
多层感知机层与层之间是全连接的。

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)

TensorFlow2学习八、多层感知机实现_全连接_04

  • 上面全连接层 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())

TensorFlow2学习八、多层感知机实现_激活函数_05


举报

相关推荐

0 条评论