⼈⼯智能深度学习⼊门练习之(26)TensorFlow–例⼦:⼈⼯神经⽹络(ANN)⼈⼯神经⽹络(ANN)介绍
⽣物神经元
⼈脑有数⼗亿个神经元。神经元是⼈脑中相互连接的神经细胞,参与处理和传递化学信号和电信号。
uv镜头
以下是⽣物神经元的重要组成部分:
树突 – 从其他神经元接收信息的分⽀
细胞核 – 处理从树突接收到的信息
轴突 – ⼀种被神经元⽤来传递信息的⽣物电缆
突触 – 轴突和其他神经元树突之间的连接
⼈脑神经元处理信息的过程:多个信号到达树突,然后整合到细胞体中,如果积累的信号超过某个阈值,就会产⽣⼀个输出信号,由轴突传递。
⼈⼯神经元
⼈⼯神经元是⼀个基于⽣物神经元的数学模型,神经元接受多个输⼊信息,对它们进⾏加权求和,再经过⼀个激活函数处理,然后将这个结果输出。
⽣物神经元对照⼈⼯神经元
⽣物神经元⼈⼯神经元
细胞核节点 (加权求和 + 激活函数)
树突输⼊
轴突带权重的连接
突触输出
⼈⼯神经⽹络
⼈⼯神经⽹络,模仿哺乳动物⼤脑⽪层的神经系统,但规模要⼩得多。它由许多简单的处理单元(神经元)互联组成,这些处理单元(神经元)的作⽤类似于⽣物神经元,接受信息输⼊,处理后向下⼀层输出信息。
⼈⼯神经⽹络由多层神经元组成。层与层之间的神经元有连接,⽽层内之间的神经元没有连接。最左边的层叫做输⼊层,这层负责接收输⼊数据;最右边的层叫输出层,我们可以从这层获取神经⽹络输出数据。输⼊层和输出层之间的层叫做隐藏层。
⼈⼯神经⽹络的训练
给神经⽹络输⼊⼀批样本数据,神经⽹络会产⽣输出。⽐较神经⽹络的输出与样本中的正确结果,根据两者的差值,对神经⽹络的权重进⾏调整,使差值变⼩。重复这个过程,直到神经⽹络产⽣正确输出,从⽽确定神经⽹络的权重值完成训练。
训练好的神经⽹络就可以⽤来处理数据,给神经⽹络输⼊数据,给出正确的输出。
所以,所谓神经⽹络的训练过程,实际上就是确定神经元之间输⼊权重的过程。
如上图所⽰,具体训练过程如下:
胆小如鼠
1. 给神经⽹络输⼊⼀批样本数据,经过神经⽹络传输到输出层,这⼀步被称为前向传播。
2. 计算损失函数的值,损失函数的值表⽰预测结果(Prediction Y)和已知结果(True label Y)之间的差值。
四川冲菜3. 使⽤优化器(Optimizer,通常使⽤梯度下降算法与反向传播算法),调整权重值,使差值变⼩。
重复以上3个步骤训练权重,直到损失函数的值(差值)最⼩,确定最终的权重值,完成训练。
注意: 关于⼈⼯神经⽹络的详细内容,可参考我们的。
TensorFlow ⼈⼯神经⽹络例⼦
TensorFlow中,Estimator是⼀种可极⼤地简化机器学习编程的⾼阶API。Estimator 会封装下列操作:
训练
评估
预测
导出以供使⽤
开发⼈员可以使⽤TensorFlow预创建的 Estimator,也可以编写⾃定义 Estimator。所有 Estimator(⽆论是预创建的还是⾃定义)都是基于 tf.estimator.Estimator 类的类。
这⼀部分,我们将学习使⽤TensorFlow的⾼阶API Estimator中的DNNClassifier训练神经⽹络,DNNClassifier是⼀个神经⽹络分类器的实现。训练数据集我们将采⽤MNIST数据集。
MNIST(Modified National Institute of Standards and Technology databa)是⼀个⼿写数字的⼤型数据库,通常作为各种图像识别系统的训练数据集,该数据集包含了从0到9的⼿写数字的28×28像素图像的集合,现在已经成为英语数字训练的标准数据集。
该神经⽹络训练好后,功能是能够识别⼿写数字。
⽤TensorFlow训练神经⽹络并不复杂,我们将按以下步骤进⾏:
1. 导⼊数据
2. 转换数据
3. 构造张量
4. 构建模型蛾怎么读
5. 训练和评估模型
6. 改进模型
中秋节主题1. 导⼊数据
⾸先需要导⼊必要的库,除了TensorFlow,我们将使⽤:
numpy 计算、处理多维数组的python包
sklearn 机器学习相关的包,包含许多有⽤的函数
sklearn可⽤于导⼊MNIST数据集,预处理数据等。
import numpy as np
import tensorflow as tf
是⼀个分享机器学习数据和实验的公共存储库,每个⼈都可在上⾯分享、下载数据集。sklearn.datats包中的fetch_openml函数可以从openml存储库下载数据集。我们将使⽤该函数从下载MNIST数据集,下载会花⼏分钟时间。
MNIST数据集中包含了样本特征集mnist.data及样本标签mnist.target。
# 导⼊sklearn库中fetch_openml函数,下载MNIST数据集
from sklearn.datats import fetch_openml
mnist = fetch_openml('mnist_784')
print(mnist.keys())
print(mnist.data.shape)
print(mnist.target.shape)
使⽤train_test_split函数将数据集随机划分为训练⼦集和测试⼦集,并返回划分好的训练集测试集样本和训练集测试集标签。
del_lection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(mnist.data, mnist.target, test_size=0.2, random_state=42)
y_train = y_train.astype(int)
y_test = y_test.astype(int)
batch_size = len(X_train)
# 查看训练样本⼦集、训练样本标签⼦集、测试样本⼦集、测试样本标签⼦集的形状
print(X_train.shape, y_train.shape, X_test.shape, y_test.shape)
羊和狗属相合不合train_test_split函数的参数解释:
train_data:被划分的样本特征集
train_target:被划分的样本标签
test_size:如果是浮点数,在0-1之间,表⽰测试⼦集占⽐;如果是整数的话就是测试⼦集的样本数量
random_state:是随机数的种⼦
随机数种⼦
随机数的产⽣取决于种⼦,随机数和种⼦之间的关系遵从以下两个规则:
种⼦不同,产⽣不同的随机数;种⼦相同,即使实例不同也产⽣相同的随机数。
随机数种⼦,其实就是该组随机数的编号,在需要重复试验的时候,种⼦相同可以保证得到⼀组⼀样的随机数。⽐如你每次都填1,其他参数⼀样的情况下,得到的随机数组是⼀样的,但填0或不填,则每次都会不⼀样。
2. 数据预处理
在进⾏训练之前,需要对数据集作归⼀化处理,可以提⾼模型收敛速度和模型精度。我们将使⽤最⼩最⼤值标准化⽅法,该⽅法的公式是:
(X-min_x)/(max_x - min_x)
sklearn库中已经为此提供了⼀个函数: MinMaxScaler()
## 导⼊MinMaxScaler
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
# 训练样本⼦集
X_train_scaled = scaler.fit_transform(X_train.astype(np.float64))
# 测试样本⼦集
X_test_scaled = scaler.fit_transform(X_test.astype(np.float64))
3. 构造张量
构造输⼊特征列张量。TensorFlow中的特征列可以视为原始数据和 Estimator 之间的媒介。特征列功能强⼤,可以将各种原始数据转换为 Estimator 可以使⽤的格式。
feature_columns = [tf.feature_column.numeric_column('x', shape = X_train_scaled.shape[1:])]
4. 构建模型
该神经⽹络结构包含两个隐藏层,第⼀层为300个神经元,第⼆层为100个神经元。这些值都是经验值,你可以尝试调整这些值,看看它如何影响⽹络的准确性。
要构建模型,可以使⽤estimator.DNNClassifier。
estimator = tf.estimator.DNNClassifier(
feature_columns=feature_columns,
hidden_units=[300, 100],
n_class=10,
model_dir = './train/DNN')
参数
feature_columns: 定义要在⽹络中使⽤的特征列
hidden_units: 定义隐藏层的神经元数量
n_class: 定义要预测的分类数量,这⾥是0~9,是10个类
model_dir: 定义TensorBoard的路径
5. 训练和评估模型
可以使⽤numpy⽅法来训练和评估模型。
# 训练模型
train_input = tf.estimator.inputs.numpy_input_fn(
x={"x": X_train_scaled},
y=y_train,
batch_size=50,
shuffle=Fal,
num_epochs=None)
# 评估模型
eval_input = tf.estimator.inputs.numpy_input_fn(
x={"x": X_test_scaled},
y=y_test,
shuffle=Fal,
batch_size=X_test_scaled.shape[0],
num_epochs=1)
result = estimator.evaluate(eval_input, steps=None)
print(result)
输出
{'accuracy': 0.9720714, 'average_loss': 0.09608318, 'loss': 1345.1646, 'global_step': 4000}
可以看到,现在模型的准确率为97%。
6. 改进模型
为减少过拟合,添加正则化参数来改进模型。我们设置dropout率为0.3,使⽤Adam Grad优化器:tf.train.ProximalAdagradOptimizer, 设置以下参数:学习速率: learning_rate
L1正则化: l1_regularization_strength
L2正则化: l2_regularization_strength
estimator_imp = tf.estimator.DNNClassifier(
feature_columns = feature_columns,
hidden_units = [300, 100],
dropout = 0.3,
n_class = 10,
ain.ProximalAdagradOptimizer(
learning_rate=0.01,
l1_regularization_strength=0.01,
l2_regularization_strength=0.01
),
model_dir = './train/DNN1')
ain(input_fn = train_input, steps=1000)
result = estimator_imp.evaluate(eval_input, steps=None)
print(result)
输出
{'accuracy': 0.94292855, 'average_loss': 0.2078176, 'loss': 2909.4463, 'global_step': 1000}
完整代码:
pat.v1 as tf
import numpy as np
# 导⼊sklearn库中fetch_openml函数,下载MNIST数据集
from sklearn.datats import fetch_openml
mnist = fetch_openml('mnist_784')
print(mnist.keys())
print(mnist.data.shape)
print(mnist.target.shape)
del_lection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(mnist.data, mnist.target, test_size=0.2, random_state=42)
y_train = y_train.astype(int)
y_test = y_test.astype(int)
batch_size = len(X_train)
# 查看训练样本⼦集、训练样本标签⼦集、测试样本⼦集、测试样本标签⼦集的形状
print(X_train.shape, y_train.shape, X_test.shape, y_test.shape)
del_lection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(mnist.data, mnist.target, test_size=0.2, random_state=42)
y_train = y_train.astype(int)
y_test = y_test.astype(int)
batch_size = len(X_train)
# 查看训练样本⼦集、训练样本标签⼦集、测试样本⼦集、测试样本标签⼦集的形状
print(X_train.shape, y_train.shape, X_test.shape, y_test.shape)
## 导⼊MinMaxScaler
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
# 训练样本⼦集
X_train_scaled = scaler.fit_transform(X_train.astype(np.float64))
# 测试样本⼦集
X_test_scaled = scaler.fit_transform(X_test.astype(np.float64))
feature_columns = [tf.feature_column.numeric_column('x', shape = X_train_scaled.shape[1:])]
estimator = tf.estimator.DNNClassifier(
feature_columns=feature_columns,
hidden_units=[300, 100],
n_class=10,
model_dir = './train/DNN')
# 训练模型
train_input = tf.estimator.inputs.numpy_input_fn(
x={"x": X_train_scaled},
y=y_train,
batch_size=50,
shuffle=Fal,
num_epochs=None)
# 评估模型
eval_input = tf.estimator.inputs.numpy_input_fn(
x={"x": X_test_scaled},
y=y_test,
shuffle=Fal,
batch_size=X_test_scaled.shape[0],
num_epochs=1)
result = estimator.evaluate(eval_input, steps=None)
print(result)
estimator_imp = tf.estimator.DNNClassifier(
feature_columns = feature_columns,
hidden_units = [300, 100],
dropout = 0.3,
n_class = 10,
ain.ProximalAdagradOptimizer(
learning_rate=0.01,
l1_regularization_strength=0.01,
l2_regularization_strength=0.01
),
model_dir = './train/DNN1')
粉笔盒ain(input_fn = train_input, steps=1000)
result = estimator_imp.evaluate(eval_input, steps=None)
print(result)
执⾏结果:
{'accuracy': 0.94292855, 'average_loss': 0.2078176, 'loss': 2909.4463, 'global_step': 1000}五香蚕豆
减少过拟合的参数设置,并没有提⾼模型的精度,第⼀个模型的准确率为97%,⽽L2正则化模型的准确率为94%。你可以尝试使⽤不同的值,看看它如何影响准确度。⼩结
本篇教程中,我们学习了如何构建⼀个神经⽹络。神经⽹络需要:
隐藏层的数量
每个隐藏层内神经元的数量
激活函数
优化器
输出的分类数量
在TensorFlow中,你可以使⽤tf.estimator.DNNClassifier训练⼀个神经⽹络来解决分类问题,需要设置的参数如下:
feature_columns=feature_columns,
hidden_units=[300, 100]
n_class=10
model_dir
可以使⽤不同的优化器来改进模型。我们学习了如何使⽤Adam Grad优化器和学习率,并设置了防⽌过度拟合的控制参数。