使用TensorFlow实现神经网络

使用TensorFlow实现神经网络

深度学习在这十年中一直在上升,其应用是如此广泛和惊人,几乎很难相信它的进步只有几年的时间。深度学习的核心是支配其架构的一个基本 “单元”,是的,它就是神经网络。

一个神经网络架构由一些神经元或激活单元组成,我们称之为激活单元,这个单元回路的功能是寻找数据中的潜在关系。而且数学上已经证明,神经网络可以找到任何种类的关系/功能,无论其复杂性如何,只要它足够深入/优化,这就是它的潜力所在。

现在让我们来学习使用TensorFlow实现一个神经网络

安装Tensorflow

Tensorflow是一个由谷歌创建并开放源代码的库/平台。它是深度学习应用中使用最多的库。现在,创建神经网络可能不是TensorFlow库的主要功能,但它经常被用于这一目的。所以在继续之前,让我们安装并导入TensorFlow模块。

使用pip/conda命令在你的系统中安装TensorFlow

# terminal/zsh/cmd command
# pip
pip install tensorflow --upgrade

# conda
conda install -c conda-forge tensorflow
%tensorflow_version 2.x

下载并阅读数据

你可以使用任何你想要的数据集,这里我使用了Kaggle的红葡萄酒质量数据集。这是一个分类问题,当然,你可以学习将这个概念应用于其他问题。首先,在你的工作目录中下载数据集。现在数据已经下载完毕,让我们把数据加载成数据框。

import numpy as np
import pandas as pd
 
# be sure to change the file path
# if you have the dataset in another
# directly than the working folder
df = pd.read_csv('winequality-red.csv')
 
df.head()

输出:

使用TensorFlow实现神经网络

数据预处理/分割成训练/验证/测试集

有多种方法来分割数据,你可以定义自定义函数或使用时间戳(如果有的话),或者使用预定义的函数,如scikit-learn中的train_test_split。

在这里,我们用样本函数获取了75%的数据来创建训练集,然后用其余的数据来创建验证集。你也可以而且应该创建一个测试集,但在这里我们有一个非常小的数据集,我们在这里的主要重点是熟悉这个过程并训练一个神经网络,对吗?

现在我们来划分我们的数据集。

import tensorflow as tf
 
# 75% of the data is selected
train_df = df.sample(frac=0.75, random_state=4)
 
# it drops the training data
# from the original dataframe
val_df = df.drop(train_df.index)

需要注意的是,神经网络通常在同一范围内的数据上表现更好。例如,如果你有不同的列,在一列中,你的数值范围是1-10,但在另一列中,它的范围是100-1000,建议首先将所有的列扩展到同一范围,以获得更好的性能。

现在,最简单的方法是:

值-(列的最小值)/(列的范围)。

# calling to (0,1) range
max_val = train_df.max(axis= 0)
min_val = train_df.min(axis= 0)
 
range = max_val - min_val
train_df = (train_df - min_val)/(range)
 
val_df =  (val_df- min_val)/range

既然我们已经完成了数据的缩放,并创建了训练和验证数据集,让我们把它分成特征,即输入和目标,因为这就是我们要把它传递给模型的方式。

# now let's separate the targets and labels
X_train = train_df.drop('quality',axis=1)
X_val = val_df.drop('quality',axis=1)
y_train = train_df['quality']
y_val = val_df['quality']
 
# We'll need to pass the shape
# of features/inputs as an argument
# in our model, so let's define a variable
# to save it.
input_shape = [X_train.shape[1]]
 
input_shape

输出:

[11]

这意味着我们将把11个特征作为输入传给我们的神经网络的第一层。

创建模型神经网络

Keras模块建立在TensorFlow之上,为我们提供了创建各种神经网络架构的所有功能。我们将使用Keras中的Sequential类来建立我们的模型。首先,你可以尝试使用线性模型,因为神经网络基本上遵循与回归相同的 “数学”,你可以使用神经网络创建一个线性模型,如下所示。

创建一个线性模型

model = tf.keras.Sequential([
tf.keras.layers.Dense(units=1,input_shape=input_shape)])
 
# after you create your model it's
# always a good habit to print out it's summary
model.summary()

输出:

使用TensorFlow实现神经网络

但这基本上是一个线性模型,如果你的数据集更复杂一些,特征之间的关系更多样化,你想要一个非线性模型怎么办?你需要什么呢?答案是激活函数。这就是神经网络真正开始发光的地方。在这篇文章中,我们无法深入了解激活函数,但基本上,这些函数为我们的模型添加/引入了非线性,你越是使用它们,我们的模型就能找到更复杂的模式。

创建一个多层次的神经网络

我们将创建一个3层网络,包括1个输入层,1个有64个单元的隐藏层1,和1个输出层。我们将在隐藏层中使用’relu’激活函数。我们将使用Keras模块中的序列方法,它经常被用来创建多层神经网络。在Keras中,我们有不同类型的神经网络层和/或转换层,你可以用来建立各种类型的神经网络,但在这里,我们只使用了3个密集层(在keras.layer中)和relu激活函数。

model = tf.keras.Sequential([
 
    tf.keras.layers.Dense(units=64, activation='relu',
                          input_shape=input_shape),
    tf.keras.layers.Dense(units=64, activation='relu'),
    tf.keras.layers.Dense(units=1)
])
model.summary()

输出:

使用TensorFlow实现神经网络

在Keras中,当你创建了你的模型之后,你需要为它 “编译 “其他的参数,就像下面所示。这有点像我们为我们的模型设置所有的参数。

# adam optimizer works pretty well for
# all kinds of problems and is a good starting point
model.compile(optimizer='adam', 
               
              # MAE error is good for
              # numerical predictions
              loss='mae') 

所以我们使用了adam优化器,也告诉模型计算mae(平均绝对误差)损失。

训练模型

既然我们已经完成了创建和实例化我们的模型,现在是时候训练它了。我们将使用fit方法来训练我们的模型。这个方法把特征和目标作为目标,我们也可以把验证数据传给它,它将自动在验证中尝试你的模型,并注意损失指标。我们还提供了batch_size,它的作用是将我们的数据分成小批,并在每个epoch中送入我们的模型进行训练,当你有大的数据集时,这非常有帮助,因为它减少了机器上的RAM和CPU消耗。

现在在这里我们只训练了15个epochs的模型,因为我们在这里的目的是熟悉这个过程,而不是准确性本身,但是你必须增加或减少你机器上的epochs数量。有一些优化方法你可以使用,比如早期停止,当模型开始过度拟合时,会自动停止训练,所以你也可以尝试使用这些方法,如果你想阅读相关内容,我在底部提供了一个链接。

losses = model.fit(X_train, y_train,
 
                   validation_data=(X_val, y_val),
                    
                   # it will use 'batch_size' number
                   # of examples per example
                   batch_size=256,
                   epochs=15,  # total epoch
 
                   )

输出:

使用TensorFlow实现神经网络

这里我们只训练了15个历时,但你肯定应该训练更多,并尝试改变模型本身。

生成预测并分析准确性

由于我们已经完成了训练过程,让我们实际尝试用它来预测 “葡萄酒质量”。为了进行预测,我们将使用模型对象的预测功能。让我们只给出三个例子作为输入,并尝试预测这三个例子的葡萄酒质量。

# this will pass the first 3 rows of features
# of our data as input to make predictions
model.predict(X_val.iloc[0:3, :])

输出:

array([[0.40581337],
      [0.5295989 ],
      [0.3883106 ]], dtype=float32)

现在,让我们将我们的预测与目标值进行比较。

y_val.iloc[0:3]

输出:

0     0.4
9     0.4
12    0.4
Name: quality, dtype: float64

正如我们所看到的,我们的预测非常接近真实值,即在所有三种情况下都是0.4。你可以定义另一个函数将预测值转换为整数,以预测1到10级的质量,以便更好地理解,但这是一件微不足道的事情,主要的是让你理解这里描述的整个过程。

可视化训练与验证的损失

你可以分析损失,弄清楚它是否过度拟合或不容易,然后采取相应的措施。

loss_df = pd.DataFrame(losses.history)
 
# history stores the loss/val
# loss in each epoch
 
# loss_df is a dataframe which
# contains the losses so we can
# plot it to visualize our model training
loss_df.loc[:,['loss','val_loss']].plot()

输出:

使用TensorFlow实现神经网络

在分析你的模型的准确性/误差时要注意的关键点是:

很明显,你的损失函数不断减少,但对于验证数据集来说,情况可能不是这样的,在某些时候,你的模型会过度拟合数据,验证误差会开始增加而不是减少。所以,你可以在验证损失似乎在增加的那个历时点上停下来。你也可以尝试一些其他的优化算法,比如提前停止(Keras中的回调)。你可以在这里阅读相关内容。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程