TensorFlow 2 ——基础神经网络和卷积神经网络

目录

  • 基础神经网络
  • 卷积神经网络

基础神经网络

首先是处理训练数据。导入或者随机定义训练的数据 和 ,这里我们使用 NumPy 随机定义训练的数据:

import numpy as np
import tensorflow as tf

x_data = np.linspace(-1, 1, 300)[:, np.newaxis]    # 生成 x
noise = np.random.normal(0, 0.05, x_data.shape)    # 生成 noise
y_data = np.square(x_data) - 0.5 + noise           # 生成 y

x_data = x_data.reshape([-1, 1])    # 将 x 转换为维度为 (300, 1) 的矩阵

接下来,需要定义神经层,我们定义一个使用 relu 激活函数的全连接层。自定义层需要继承·tf.keras.layers.Layer 类,并重写 _init_() 、 build()call() 三个方法。

class LinearLayer(tf.keras.layers.Layer):    # 继承 tf.keras.layers.Layer 类
    def __init__(self, units):    # units 是输出张量的维度
        super().__init__()
        self.units = units

    def build(self, input_shape):
        self.w = self.add_weight(name='w',
            shape=[input_shape[-1], self.units], initializer=tf.zeros_initializer())    # 权重 w,初始化为 0,shape 为 [input_shape[-1], units]
        self.b = self.add_weight(name='b',
            shape=[self.units], initializer=tf.zeros_initializer())    # 偏置 b,初始化为 0,shape 为 [units]

    def call(self, inputs):
        y_pred = tf.nn.relu(tf.matmul(inputs,self.w) + self.b)    # y = relu(x * w + b)
        return y_pred

接下来,需要定义模型,我们要定义一个两层神经网络,模型包含一个隐藏层和一个输出层。我们可以通过继承tf.keras.Model来定义自己的模型,并需要重写 _init_() (构造函数,初始化)和 call(input) (模型调用)两个方法

class MyModel(tf.keras.Model):    # 继承 tf.keras.Model 类
    def __init__(self):
        super().__init__()
        self.layer1 = LinearLayer(units=10)             # 自定义的全连接层
        self.layer2 = tf.keras.layers.Dense(units=1)    # tensorflow 的 Dense 层

    def call(self, inputs):
        x = self.layer1(inputs)    # 添加隐藏层
        output = self.layer2(x)    # 添加输出层
        return output

实例化我们定义的模型,并且设置优化器:

model = MyModel()    # 实例化模型
optimizer = tf.keras.optimizers.Adam(learning_rate=0.1)    # 设置优化器为 Adam 优化器,学习率为 0.1

开始训练:

from sklearn.utils import shuffle

epoches = 10    # 设置迭代次数

for epoch in range(epoches):
    
    trainX, trainY =x_data[0:250], y_data[0:250]    # 取前 250 个数据为训练集
    
    with tf.GradientTape() as tape:    # 自动求导记录器
        y_pred = model(trainX)
        loss = tf.reduce_mean(tf.square(y_pred - trainY))    # 使用均方损失
        
    grads = tape.gradient(loss, model.variables)    # 使用 model.variables 这一属性直接获得模型中的所有变量
    optimizer.apply_gradients(grads_and_vars=zip(grads, model.variables))
    
    testX, testY = x_data[250:300], y_data[250:300]    # 取后 50 个数据为训练集
    y_pred_test = model(testX)
    loss_test = tf.reduce_mean(tf.square(y_pred_test - testY))
    
    x_data, y_data = shuffle(x_data, y_data)    # 打乱数据

我们在模型函数里加上 Dropout防止过拟合:

class MyModelDrop(tf.keras.Model):
    def __init__(self):
        super().__init__()
        self.layer1 = LinearLayer(units=10)
        self.layer2 = tf.keras.layers.Dropout(rate=0.5)    # 添加 Dropout,参数 rate 用于指定 drop 的比例
        # 隐含节点 dropout 率等于 0.5 的时候效果最好,即 rate = 0.5,
        # 原因是 0.5 的时候 dropout 随机生成的网络结构最多。
        self.layer3 = tf.keras.layers.Dense(units=1)
        

    def call(self, inputs):
        x = self.layer1(inputs)
        x = self.layer2(x)
        output = self.layer3(x)
        return output

同样我们可以运行添加了 Dropout 的模型:

model = MyModelDrop()    # 实例化模型
optimizer = tf.keras.optimizers.Adam(learning_rate=0.1)

epoches = 10
for epoch in range(epoches):
    
    trainX, trainY =x_data[0:250], y_data[0:250]
    with tf.GradientTape() as tape:
        y_pred = model(trainX)
        loss = tf.reduce_mean(tf.square(y_pred - trainY))
    grads = tape.gradient(loss, model.variables)
    optimizer.apply_gradients(grads_and_vars=zip(grads, model.variables))
    
    testX, testY = x_data[250:300], y_data[250:300]
    y_pred_test = model(testX)
    loss_test = tf.reduce_mean(tf.square(y_pred_test - testY))
    
    x_data, y_data = shuffle(x_data, y_data)

由于数据和网络比较简单,所以加了 dropout 后效果差别不大。

卷积神经网络

有了神经网络,我们就可以对输入的信息进行特征提取,但是图像包含的信息量巨大,一般的神经网络并不能准确的提取图像的特征,这时候就要用到卷积神经网络。
首先是数据预处理过程,我们使用 scikit-learn 提供的数据集,并完成形状处理:

from sklearn.datasets import load_digits  # sklearn 为我们提供的手写数字数据集

# 数据预处理
digits = load_digits()
X_data = digits.data.astype(np.float32)
y_data = digits.target.astype(np.float32).reshape(-1, 1)

X_data.shape, y_data.shape

接下来,对数据进行标准化处理,可以提升模型的训练效果:

# 数据的标准化(normalization)是将数据按比例缩放,
# 使之落入一个小的特定区间。这样去除数据的单位限制,
# 将其转化为无量纲的纯数值,便于不同单位或量级的指标能够进行比较和加权。
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X = scaler.fit_transform(X_data)
X = X.reshape(-1, 8, 8, 1)
y = OneHotEncoder(categories='auto').fit_transform(
    y_data).todense()  # one-hot 编码

X.shape, y.shape

用 Keras 的 Sequential API 来构建模型:

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Conv2D(
    filters=10,              # 卷积层神经元(卷积核)数目
    kernel_size=[3, 3],      # 卷积核大小
    strides=(1, 1),          # 步长
    padding='same',          # padding策略(vaild 或 same)
    activation=tf.nn.relu,   # 激活函数
    input_shape=(8, 8, 1)    # 指出输入的形状 (samples,rows,cols,channels),只指出后三维,第一维度按 batch_size 自动指定
))
model.add(tf.keras.layers.MaxPool2D(
    pool_size=[3, 3],      # 池窗口大小
    strides=2,             # 步长
    padding='same'
))
model.add(tf.keras.layers.Conv2D(filters=5, kernel_size=[3, 3], strides=(2, 2), padding='same'))
model.add(tf.keras.layers.BatchNormalization())
model.add(tf.keras.layers.Activation('relu'))
model.add(tf.keras.layers.MaxPool2D(pool_size=[3, 3], strides=2, padding='same'))
model.add(tf.keras.layers.Reshape(target_shape=(1*1*5,)))
model.add(tf.keras.layers.Dense(units=50, activation=tf.nn.relu))
model.add(tf.keras.layers.Dense(units=10))
model.add(tf.keras.layers.Softmax())
model.summary()

构建好了模型,下面需要通过 tf.keras.Model 的 compile 方法配置训练过程:

model.compile(
    optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),    # 设置优化器,这里使用 Adam 优化器,设置学习率为 0.001
    loss=tf.keras.losses.categorical_crossentropy,              # 设置损失函数,这里使用交叉熵损失
    metrics=[tf.keras.metrics.categorical_accuracy]             # 设置评估指标,用于检查 y_ture 中最大值对应的 index 与 y_pred 中最大值对应的 index 是否相等
)

batch_size = 32  # 设定 batch_size 为 32
epochs = 50  # 迭代 50 个周期
model.fit(X, y, epochs=epochs, batch_size=batch_size)

你可能感兴趣的:(Tensorflow,卷积,神经网络,tensorflow,深度学习)