编写和训练神经网络模型
我们来做一个 我们假设神经网络算法中只有一个节点,而且只有一个输出。
import 相关工具包
import numpy as np
import tensorflow as tf
from tensorflow import keras
训练数据如下:
x_train = np.array([1.0, 2.0, 3.0, 4.0, 5.0], dtype=float)
y_tarin = np.array([3.0, 5.0, 7.0, 9.0, 11.0], dtype=float)
其实很容易发现,这是特意构造的一组数据,输入和输出数据之间是线性关系。
我们通过一个最简单的案例,来熟悉一下tensorflow的基本写法。
定义神经网络模型
model = tf.keras.Sequential([keras.layers.Dense(units=1, input_shape = [1])])
我们通过sequential来定义神经网络的结构: sequential 是序列的意思。它表示是layer的序列,也就是网络层。 sequential的参数是一个数组。数组的每一项就是一个layer。
也可以有另一种写法:
model = tf.keras.Sequential()
model.add(kears.layers.Dense(unit-1, input_shape = [1])
这里先定义了一个Sequential对象,但是没有添加具体的layer。而是通过add方法添加。
编译神经网络
我们上一步定义好了神经网络的模型。模型在训练的时候有两个关键点: 1,数据经过模型处理后,如何判断结果的准确性?这里我们需要一个损失函数来衡量该结果了。也就是loss。 2,如果结果不准确,模型如何调整自己的参数呢?这里就需要有一个优化器了。也就是optimizer。
体现在代码中如下:
model.compile(optimizer='sgd', loss='mean_squared_error')
这里优化器使用的是sgd,也就是随机梯度下降。 损失函数用的是 mean_squared_error,也就是均方差。
具体有哪些损失函数和优化器,之后可以再详细介绍。
训练神经网络
model.fit(x_train, y_train, epochs=1000)
结果如下:
Epoch 1/1000
1/1 [==============================] - 0s 133ms/step - loss: 34.4833
Epoch 2/1000
1/1 [==============================] - 0s 998us/step - loss: 27.4619
Epoch 3/1000
1/1 [==============================] - 0s 998us/step - loss: 21.9311
Epoch 4/1000
1/1 [==============================] - 0s 2ms/step - loss: 17.5730
Epoch 5/1000
1/1 [==============================] - 0s 2ms/step - loss: 14.1377
Epoch 6/1000
1/1 [==============================] - 0s 2ms/step - loss: 11.4285
Epoch 7/1000
1/1 [==============================] - 0s 2ms/step - loss: 9.2908
Epoch 8/1000
1/1 [==============================] - 0s 998us/step - loss: 7.6029
Epoch 9/1000
1/1 [==============================] - 0s 2ms/step - loss: 6.2688
Epoch 10/1000
1/1 [==============================] - 0s 2ms/step - loss: 5.2133
Epoch 11/1000
1/1 [==============================] - 0s 2ms/step - loss: 4.3772
.
.
.
Epoch 997/1000
1/1 [==============================] - 0s 997us/step - loss: 1.8421e-09
Epoch 998/1000
1/1 [==============================] - 0s 2ms/step - loss: 1.8046e-09
Epoch 999/1000
1/1 [==============================] - 0s 3ms/step - loss: 1.7623e-09
Epoch 1000/1000
1/1 [==============================] - 0s 2ms/step - loss: 1.7328e-09
最后我门看到loss已经非常小了。看来训练营完成。
那么我们来预测一下几个结果吧。
测试集
x_test = np.array([5.0, 3.0, 2.0, 4.0, 0.0], dtype=float)
print(model.predict(x_test))
结果如下:
[[11.000036 ]
[ 6.9999986]
[ 4.99998 ]
[ 9.000017 ]
[ 0.9999426]]
其实和我们的预定义的数据规律保持一致,基本上都符合 y = 2*x + 1。
疑问
为什么最后的结果中,预测的结果都不是整数呢,而且是非常接近整数的浮点数。
这是因为模型在训练的时候,尽管我们训练了1000轮,但是仍然没有得最理想的参数,但是梯度下降算法已经然我们找到了一个非常优秀的解了。
另一方面来想,完全符合 y = 2 * x + 1的规律也未必是好事,因为这有可能发生了过拟合。