用Python手把手教你实现一个多层感知机(MLP)——从理论到代码实战
神经网络已经成为现代机器学习的基石,而多层感知机(MLP)作为最基础的前馈神经网络,是每个想深入AI领域的开发者必须掌握的模型。不同于直接调用现成的深度学习框架,本文将带你从零开始,用Python和Theano库一步步构建MLP,让你真正理解神经网络的运作机制。
1. 理解MLP的核心原理
MLP由三个关键部分组成:输入层、隐藏层和输出层。每一层都由多个神经元构成,层与层之间采用全连接方式。这种结构赋予了MLP强大的非线性建模能力。
神经元的核心计算过程可以分解为两个步骤:
- 线性变换:
z = W·X + b - 非线性激活:
a = f(z)
其中W是权重矩阵,b是偏置向量,f是激活函数。这种结构使得MLP能够逼近任何复杂的非线性函数。
常用的激活函数包括:
| 函数名称 | 数学表达式 | 特点 |
|---|---|---|
| Sigmoid | 1/(1+e^-x) | 输出范围(0,1),适合二分类 |
| Tanh | (e^x-e^-x)/(e^x+e^-x) | 输出范围(-1,1),中心对称 |
| ReLU | max(0,x) | 计算简单,缓解梯度消失 |
在构建MLP时,我们需要特别注意权重初始化。一个经验法则是:
- 对于Tanh:使用Xavier初始化,范围在[-√(6/(n_in+n_out)), √(6/(n_in+n_out))]
- 对于Sigmoid:将上述范围乘以4
# Xavier初始化的Python实现
import numpy as np
def xavier_init(n_in, n_out, activation='tanh'):
range_val = np.sqrt(6.0 / (n_in + n_out))
if activation == 'sigmoid':
range_val *= 4
return np.random.uniform(-range_val, range_val, size=(n_in, n_out))
2. 构建隐藏层:神经网络的动力源
隐藏层是MLP处理信息的核心部件。我们将创建一个HiddenLayer类,封装所有隐藏层的计算逻辑。
import theano
import theano.tensor as T
import numpy as np
class HiddenLayer(object):
def __init__(self, rng, input, n_in, n_out, W=None, b=None, activation=T.tanh):
"""
rng: 随机数生成器
input: 输入数据,形状为(n_examples, n_in)
n_in: 输入维度
n_out: 隐藏层神经元数量
W: 可选的预训练权重
b: 可选的预训练偏置
activation: 激活函数,默认为tanh
"""
self.input = input
# 权重初始化
if W is None:
W_values = np.asarray(
rng.uniform(
low=-np.sqrt(6. / (n_in + n_out)),
high=np.sqrt(6. / (n_in + n_out)),
size=(n_in, n_out)
),
dtype=theano.config.floatX
)
if activation == T.nnet.sigmoid:
W_values *= 4
W = theano.shared(value=W_values, name='W', borrow=True)
# 偏置初始化
if b is None:
b_values = np.zeros((n_out,), dtype=theano.config.floatX)
b = theano.shared(value=b_values, name='b', borrow=True)
self.W = W
self.b = b
# 计算层输出
lin_output = T.dot(input, self.W) + self.b
self.output = (
lin_output if activation is None
else activation(lin_output)
)
# 层的参数
self.params = [self.W, self.b]
在实际项目中,隐藏层的设计有几个关键考虑因素:
- 神经元数量:太少会导致欠拟合,太多可能过拟合。可以从输入层大小的1.5倍开始尝试
- 激活函数选择:ReLU通常是不错的默认选择,但在浅层网络中Tanh也可能

——从理论到代码实战&spm=1001.2101.3001.5002&articleId=154892529&d=1&t=3&u=e71d625af3e0430fb3b84dc3502ea578)
3万+

被折叠的 条评论
为什么被折叠?



