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)
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
TensorFlow是一个被广泛应用于机器学习和深度学习的开源框架,它提供了丰富的工具和库来构建和训练神经网络模型。其中,CNN(卷神经网络)是一种特别适用于图像处理任务的神经网络结构,而VGGNet19是其中一个经典的CNN模型。 在进行图像风格转化任务时,我们可以利用VGGNet19来实现。图像风格转化是一种将一张图像的内容与另一张图像的风格相结合的技术,常用于艺术创作和图像处理领域。在这个实战项目中,我们可以使用Jupyter Notebook来编写并运行我们的代码。 首先,我们需要准备两张输入图片,一张作为内容图像,一张作为风格图像。然后,我们可以使用VGGNet19模型来提取内容图像和风格图像的特征表示。接着,我们需要定义一个损失函数,该损失函数可以度量内容图像与生成图像之间的内容差异,以及风格图像与生成图像之间的风格差异。最后,我们可以使用梯度下降等优化算法来最小化损失函数,从而生成新的图像,使得它既保留了内容图像的内容特征,又融合了风格图像的风格特征。 在Jupyter Notebook中,我们可以逐步编写和调试这些代码,并及时查看生成的图像效果。通过这个实战项目,我们不仅能够深入理解CNN模型和图像风格转化的原理,还能够掌握如何使用TensorFlow和Jupyter Notebook进行实际的深度学习任务。这将为我们在图像处理和艺术创作领域带来更多的应用和创新可能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

凡心curry

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

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

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

打赏作者

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

抵扣说明:

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

余额充值