0. 参数的指定
- learning_rate:
η=0.01 λ2⇒ℓ2 :0.0001
λ1⇒ℓ1 :0.00(这种其实仅要求的是ℓ2 约束)
- n_epochs(迭代的次数):1000
- batch_size = 20
- n_hidden = 500(n_in = 28*28=784)
1. 面向对象类设计
LogisticRegression(基于 softmax 的输出)
class LogisticRegression(object):
def __init__(self, inpt, n_in, n_out):
对于神经网络的一个隐层(HiddenLayer)而言,如果需将其封装为一个类的话,需要在构造函数中传递进哪些参数。
- 连接层间的权值矩阵(当然也有 bias vector)必不可少,
W,b
- 权值矩阵(bias vector)的初始化方式,需要这也需要有一个随机数生成器(rng);
- 当然针对不同的激励函数,也存在不同的启发式的权值矩阵的初始化方式;
- 初始化矩阵显然最直接需要的就是,矩阵的 size,因此也需要传递 n_in, n_out 的大小,n_out 也对应着
b 的规模;
- 权值矩阵(bias vector)的初始化方式,需要这也需要有一个随机数生成器(rng);
- 激励函数的种类(activation function)
class HiddenLayer(object):
def __init__(self, rng, inpt, n_in, n_out, W=None, b=None, activation=T.tanh):
有了 LogisticRegression(作为输出层)以及隐层的定义,我们便可以来定义 MLP 了,
class MLP(object):
# 只有两层的网络
def __init__(self, rng, inpt, n_in, n_hidden, n_out):
self.HiddenLayer(rng=rng, inpt=inpt, n_in=n_in, n_out=n_hidden, activation=T.tang)
self.logRegressLayer(rng=rng, inpt=self.HiddenLayer.output, n_in=n_hidden, n_out=n_out)
2. Teano 下的 L1/L2 正则
比如对于一个双层的神经网络而言(自然也就存在两个权值矩阵)
self.L1 = abs(self.W1).sum() + abs(self.W2).sum()
self.L2_sqr = (self.W1**2).sum() + (self.W2**2).sum()
3. MLP 模型的训练
index = T.lscalar() # 指定 minibatch 的 index
X = T.matrix('X')
y = T.ivector('y')
cost = clf.nll(y) + l1_reg*clf.L1 + l2_reg*clf.L2_sqr
test_model = theano.function(
inputs=[index],
output=clf.errors(y),
givens={
X: testset_x[index*batch_size:(index+1)*batch_size],
y: testset_y[index*batch_size:(index+1)*batch_size]
}
)
valid_mode = theano.function(
inputs=[index],
output=clf.errors(y),
givens={
X: validset_x[index*batch_size:(index+1)*batch_size],
y: validset_y[index*batch_size:(index+1)*batch_size]
}
)
gparams = [T.grad(cost=cost, wrt=para) for para in clf.params]
updates = [param-learning_rate*g_param for param, g_param in zip(clf.params, params)]
train_model = theano.function(
inputs=[index],
output=cost,
updates=updates,
givens={
X: trainset_x[index*batch_size:(index+1)*batch_size],
y: trainset_y[index*batch_size:(index+1)*batch_size]
}
)