从零开始玩转TensorFlow:小明的机器学习故事 4
探索深度学习
1 场景故事:小明的灵感
前不久,小明一直在用传统的机器学习方法(如线性回归、逻辑回归)来预测学校篮球比赛的胜负。虽然在朋友们看来已经很不错了,但小明发现一个问题:当比赛数据越来越多、球队的特征越来越复杂时,模型的准确率提升得很慢。
有一天,小明在学校图书馆翻看杂志时,看到这样一句话:“就像人的大脑有上百亿神经元,神经网络能够学习复杂的信息映射,从而取得卓越的表现。”他瞬间来了灵感:“或许我也可以用‘深度学习’来让我的预测模型变得更聪明!”
接下来,小明就开始了他对神经网络的探索之旅。
2 什么是神经网络,为什么它能提高准确率?
为了搞清楚神经网络到底是什么,小明先上网搜了一堆资料。零基础的他发现常见的解释有点深奥,于是他试着用更简单的例子来理解:
-
神经元就像分拣员
在物流中心,分拣员会接收到不同的包裹(输入),给它们贴上标签或挑选对应的目的地。计算机里的“神经元”也类似:它先把输入进行加权求和,再用激活函数来决定“要把信息传给下一层多少”。 -
多层堆叠就像流水线
如果物流中心只有一个分拣员(单层神经网络),它能处理的复杂度有限。但如果有多道工序,一层层分拣、再包装、再检查,最后才分配到最合适的区域,就可以更灵活地处理各种奇奇怪怪的包裹。- 第一层:对原始信息(特征)做初步处理,例如判断包裹的大小、重量、形状等。
- 第二层:在上一层的基础上,再进行更细的区分,比如区分易碎品、食品、衣物等。
- 第三层:最后做出整体判断,输出结果。
-
为什么更准?
- 自动特征学习:在传统方法中,小明常常需要自己设计许多特征,比如球队场上投篮命中率、场下士气等。但神经网络会自动从数据里发现特征的组合关系,省去了很多人工设计的过程。
- 非线性表达能力:当输入和输出之间的关系非常复杂时,单纯的线性模型往往抓不住重点;而神经网络加了激活函数,可以更灵活地捕捉隐藏规律。
小结1:
- 神经网络源于对大脑神经结构的抽象,可以自动学习复杂的特征映射。
- 深度学习之所以“深”,在于它有多层结构,每一层都能对输入进行更高层次的抽象。
- 当你发现传统模型无法进一步提高准确率时,尝试神经网络或许会有惊喜。
3 用tf.keras构建神经网络:动手做才是王道
看完概念后,小明决定开干!他打开了自己电脑上的Jupyter Notebook,并且安装好了TensorFlow。为了让你也一起上手,小明准备了以下步骤:
3.1 安装并导入库
- 安装TensorFlow(若尚未安装)
pip install tensorflow
- 导入依赖
import tensorflow as tf from tensorflow import keras from tensorflow.keras import layers import numpy as np
3.2 准备“篮球预测”模拟数据
小明目前还没有收集到足够真实的数据,所以他先用随机数来模拟一份小数据集。真实项目中,你可以将此处替换为自己整理好的数据表格或CSV文件。
# 假设有1000场比赛,每场比赛有10个数值特征(例如投篮命中率、篮板球、助攻数等)
x_data = np.random.rand(1000, 10)
# 假设标签是比赛结果:1 = 胜利, 0 = 失败
y_data = np.random.randint(2, size=(1000, 1))
3.3 构建神经网络模型
这里我们用最简单的Sequential
方式堆叠几层全连接网络(Dense层):
model = keras.Sequential([
layers.Dense(16, activation='relu', input_shape=(10,)), # 第一层:16个神经元
layers.Dense(8, activation='relu'), # 第二层:8个神经元
layers.Dense(1, activation='sigmoid') # 输出层:1个神经元,用于预测胜利的概率
])
- 第一层用到
input_shape=(10,)
表示我们的输入特征有10个维度。 - 激活函数:
relu
:当输入大于0时输出本身,否则输出0。能加快收敛,并缓解梯度消失问题。sigmoid
:将输出映射到(0,1)之间,适合二分类或概率输出。
小结2:
- 使用多层网络时,每一层都可以学习到不同层次的信息:初步判断、进一步提取特征、综合判断。
tf.keras.Sequential
能让我们像搭积木一样快速搭建模型。
3.4 编译模型
模型只是“纸上谈兵”,需要告诉它如何学习、学什么、以及如何评估才能真正开始训练:
model.compile(
optimizer='adam', # Adam算法能自动适配学习率
loss='binary_crossentropy', # 二分类常用交叉熵做损失函数
metrics=['accuracy'] # 训练时会同时追踪准确率
)
- optimizer(优化器):决定如何根据损失调整模型参数。常见的还有SGD、RMSProp等。
- loss(损失函数):衡量预测和真实结果的差距,相当于“学习的方向标”。
- metrics(评价指标):让你直观地了解训练效果,比如准确率。
3.5 训练模型
现在,就可以进行“真正的学习”了。小明像教练一样,把训练数据交给网络,让它一遍又一遍地学习(epoch 轮数):
history = model.fit(
x_data, y_data,
epochs=10, # 训练10轮
batch_size=32, # 每批32条数据,计算一次梯度更新
validation_split=0.2 # 训练数据中有80%用于训练,20%用于验证
)
epochs=10
:代表训练集会被完整地“看”10次。一般会根据模型收敛情况来调节这个数值。batch_size=32
:代表每次用32条数据来计算梯度,能在一定程度上稳定训练过程。validation_split=0.2
:在训练时自动分出20%的数据给验证集,以评估模型有没有过拟合。
提示:在实际项目中,一般会有单独的训练集、验证集、测试集,以确保训练效果更可靠。
3.6 评估与预测
训练完成后,你可以查看模型在整个数据集上的最终表现:
loss, accuracy = model.evaluate(x_data, y_data)
print(f"Final Loss: {loss:.4f}, Final Accuracy: {accuracy:.4f}")
对于新来的比赛数据,也可以进行预测:
new_data = np.random.rand(5, 10) # 5场比赛,10个特征
predictions = model.predict(new_data)
print("Predictions (probability of winning):")
print(predictions)
- 如果想把概率转成具体的预测结果,可用
(predictions > 0.5).astype(int)
。
小结3:
- 训练过程中,验证集的损失和准确率能帮助你判断是否发生过拟合。
- 评估模型时,除了准确率,还可以多角度使用其它指标(如Precision、Recall、F1 Score等)。
- 训练完毕后,模型就像一个学了“篮球预测知识”的学生,可以用来预测新比赛。
4 阶段性总结:你已经离高手更近一步
-
概念理解:
- 神经网络是模仿大脑神经元的结构,层数越深,表达能力越强。
- 深度学习用激活函数、网络层叠等手段来捕捉复杂的数据模式,从而在很多场合表现更佳。
-
实践流程:
- 搭建网络:先定义层数和每层神经元个数及其激活函数。
- 编译模型:告诉模型用什么方式优化参数、评估损失。
- 训练评估:选择合适的超参数(epoch、batch_size),观察训练曲线与验证曲线。
-
常见困惑:
- 为什么要多层? 多层网络能自动学习到更深层次特征,从而提高泛化能力。
- 学习率怎么选? 如果学习率过高,可能导致训练难以收敛;过低,训练速度过慢。Adam 能自动调节,但也需要适度调整其它超参数。
- 一定要大数据么? 大数据确实能帮助神经网络取得更好效果,但也并非完全必要。在数据不足时,可考虑数据增强或迁移学习等方法。
阶段性成就感:
恭喜你!在这一节里,你已经从对神经网络的零散概念,一步步走到了成功搭建并训练一个简单神经网络。在深度学习的世界里,能够跑通一个完整的案例是迈出的最关键一步。今后,你可以尝试更真实、更大规模的数据集,或者继续学习CNN、RNN等不同结构,让模型的能力越来越强大。
5.5 小明的新发现
在经历了这次深度学习的“初次尝试”后,小明惊喜地发现,哪怕在模拟数据上,他的神经网络也能取得不错的准确率。他想:“当我收集到真实的比赛数据,也许准确率能更加惊艳!”
满怀期待,小明开始进一步研究卷积神经网络(CNN),准备在图像数据和比赛视频中寻找更多秘密……欲知后事如何,还请继续阅读下一节的“卷积神经网络”吧!
通过以上的故事叙述和详细举例,我们希望让零基础读者对神经网络及其在TensorFlow中的实现有一个更直观的概念。实践中最重要的就是亲手操作,只有跑通、调试、观察结果,才能不断积累经验、提升深度学习技能。祝你在这条学习之路上一路收获满满!