在当今的技术领域,"神经网络"、"深度学习"和"人工智能"等术语频繁出现。但它们究竟是什么?它们与机器学习有何不同?为何它们与大脑中的神经元相似?本文将回答这些基本问题,并构建一个基本的神经网络来执行线性回归。
大脑的基本单位被称为神经元,神经系统中大约有860亿个神经元,它们连接到10^14至10^15个突触。每个神经元接收来自突触的信号,并在处理信号后输出。这个概念被借鉴来构建神经网络。每个神经元执行输入和权重之间的点积,加上偏置,应用激活函数,并输出结果。当大量神经元一起工作产生大量输出时,就形成了一个神经层。最终,多个层组合形成一个神经网络。
当多个神经层相互结合时,就形成了一个网络,或者说有一些层的输出是其他层的输入。构建基本神经网络最常见的层类型是全连接层,其中相邻层是完全连接的,而单个层中的神经元不相互连接。在上图中,神经网络被用来将数据点分类为三个类别。
当谈论N层神经网络时,不计算输入层。因此,单层神经网络描述了一个没有隐藏层的网络(输入直接映射到输出)。在代码中,将使用一个单层神经网络,即没有隐藏层。
与神经网络中的所有层不同,输出层的神经元通常没有激活函数(或者可以认为它们具有线性恒等激活函数)。这是因为最后一个输出层通常用来表示类别分数(例如,在分类中),这些是任意实数值,或者是某种实值目标(例如,在回归中)。由于使用单层进行回归,没有任何激活函数。
人们通常使用两个指标来衡量神经网络的大小:神经元的数量,或者更常见的是参数的数量。
将使用三个基本库来构建这个模型:numpy、matplotlib和TensorFlow。Numpy为大型多维数组和矩阵提供支持,并附带大量高级数学函数。在案例中,将使用Numpy生成数据。Matplotlib是Python的绘图库,将使用Matplotlib中的图表来可视化最终结果。TensorFlow库特别关注深度神经网络的训练和推理。可以直接导入层和训练、测试函数,而不需要编写整个程序。
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
可以使用np.uniform()函数生成自己的数值数据。这里,使用两个输入变量xs和zs,添加一些噪声以随机分散数据点,最后定义目标变量为y=2*xs-3*zs+5+noise。数据集的大小是1000。
observations=1000
xs=np.random.uniform(-10,10,(observations,1))
zs=np.random.uniform(-10,10,(observations,1))
generated_inputs=np.column_stack((xs,zs))
noise=np.random.uniform(-10,10,(observations,1))
generated_target=2*xs-3*zs+5+noise
生成数据后,将其保存在.npz文件中,以便用于训练。
np.savez('TF_intro',input=generated_inputs,targets=generated_target)
training_data=np.load('TF_intro.npz')
目标是使最终权重尽可能接近实际权重,即[2,-3]。
这里,将使用TensorFlow密集层来构建模型,并从Keras导入随机梯度下降优化器。梯度是一个函数的斜率。它衡量一个变量随着另一个变量的变化而变化的程度。从数学上讲,梯度下降是一个凸函数,其出口是对其输入的一组参数的偏导数。梯度越大,斜率越陡。从初始值开始,梯度下降迭代运行,以找到给定成本函数的最小可能值的最优参数值。"随机"一词指的是一个随机的概率系统或过程。因此,在随机梯度下降中,每次迭代随机选择一些样本,而不是整个数据集。由于输入有2个变量,输入大小=2,输出大小=1。将学习率设置为0.02,既不太高也不太低,并将epoch值设置为100。
input_size=2
output_size=1
models = tf.keras.Sequential([
tf.keras.layers.Dense(output_size)
])
custom_optimizer=tf.keras.optimizers.SGD(learning_rate=0.02)
models.compile(optimizer=custom_optimizer,loss='mean_squared_error')
models.fit(training_data['input'],training_data['targets'],epochs=100,verbose=1)
可以打印预测的权重和偏置值,并将它们存储起来。
models.layers[0].get_weights()
这里,第一个数组代表权重,第二个数组代表偏置。可以清楚地观察到预测的权重值非常接近实际的权重值。
weights=models.layers[0].get_weights()[0]
bias=models.layers[0].get_weights()[1]
使用给定的权重和偏置进行预测后,最终得到的RMSE分数为0.02866,这是相当低的。RMSE定义为均方根误差。均方根误差取每个观测值和预测值之间的差异。RMSE公式如下:
out=training_data['targets'].round(1)
from sklearn.metrics import mean_squared_error
mean_squared_error(generated_target, out, squared=False)
plt.scatter(np.squeeze(models.predict_on_batch(training_data['input'])),np.squeeze(training_data['targets']),c='#88c999')
plt.xlabel('Input')
plt.ylabel('Predicted Output')
plt.show()