n_train_batches = train_set_x.get_value(borrow=True).shape[0] // batch_size
n_valid_batches = valid_set_x.get_value(borrow=True).shape[0] // batch_size
n_test_batches = test_set_x.get_value(borrow=True).shape[0] // batch_size
以n_train_batches为例,train_set_x.get_value.shape[0]为训练样本集中样本的个数(shape[0]为矩阵的行数,即训练样本数,而shape[1]是训练样本的列数,即样本的属性个数),batch_size为一个mini-batch(取样集,网上无合适的翻译,但有人用了这个先这样命名吧)中有多少样本数,两者相除得到的结果为一次epoch(世代)需要训练几个mini-batch。
index = T.lscalar()
x = T.matrix('x')
y = T.ivector('y')
classifier = LogisticRegression(input=x, n_in=28 * 28, n_out=10)
cost = classifier.negative_log_likelihood(y)
index为mini-batch中的索引,代表一次epoch中的第几个mini-batch。x为一个矩阵,存储的一行数据为一张 28*28=784像素的图片,行数为训练样本的个数。y为标记向量,如[1,0,0,0,0,0,0,0,0,0]代表样例的数字为0,[0,0,1,0,0,0,0,0,0,0]代表样例的数字为2。利用LogisticsRegression实例化classifier对象,同时定义cost为classifier的损失函数。需要在训练中使得损失函数的数值cost最小(使用随机梯度下降法),即训练模型成功。
test_model = theano.function(
inputs=[index],
outputs=classifier.errors(y),
givens={
x: test_set_x[index * batch_size: (index + 1) * batch_size],
y: test_set_y[index * batch_size: (index + 1) * batch_size]
}
)
validate_model = theano.function(
inputs=[index],
outputs=classifier.errors(y),
givens={
x: valid_set_x[index * batch_size: (index + 1) * batch_size],
y: valid_set_y[index * batch_size: (index + 1) * batch_size]
}
)
输入是index,输出则是classifier对象中的errors方法的返回值,其中y作为errors方法的输入参数。其中的classifier接收x作为输入参数。givens关键字的作用是使用冒号后面的变量来替代冒号前面的变量,本例中,即使用测试数据中的第index批数据(一批有batch_size个)来替换x和y。test_model用中文来解释就是: 接收第index批测试数据的图像数据x和期望输出y作为输入,返回误差值的函数,函数theano.tensor.neq(self.y_pred, y)用于统计self.y_pred和y中不相等的样本的个数。
g_W = T.grad(cost=cost, wrt=classifier.W)
g_b = T.grad(cost=cost, wrt=classifier.b)
updates = [(classifier.W, classifier.W - learning_rate * g_W),
(classifier.b, classifier.b - learning_rate * g_b)]
updates是一个长度为2的list, 每个元素都是一组tuple, 在theano.function中, 每次调用对应函数, 使用tuple中的第二个元素来更新第一个元素。
train_model = theano.function(
inputs=[index],
outputs=cost,
updates=updates,
givens={
x: train_set_x[index * batch_size: (index + 1) * batch_size],
y: train_set_y[index * batch_size: (index + 1) * batch_size]
}
)
与test_model和validate_model类似,但是有所不同的是增加了updates参数,这个参数给定了每次调用train_model时对某些参数的修改(W和b)。同时outputs也变成了cost。在训练中需要使得损失函数最小。
self.W = theano.shared(
value=numpy.zeros(
(n_in, n_out),
dtype=theano.config.floatX
),
name='W',
borrow=True
)
shared函数将变量设置为全局变量,让变量的值可在多个函数中使用;
numpy.zeros是得到形状为(n_in, n_out)的二维零矩阵,n_in为行,n_out为列;
dtype类型需要设置成theano.config.floatX,这样GPU才能调用;
参数name:用于标识此参数的字符串:
import numpy, theano
np_array = numpy.zeros(2, dtype='float32')
s_default = theano.shared(np_array, name='s_default')
print ('s_default.name:',s_default.name)
输出:
s_default.name: s_default
参数borrow=True/False:对数据的改变会/不会影响到原始变量:
import numpy, theano
np_array = numpy.zeros(2, dtype='float32')
s_default = theano.shared(np_array)
s_false = theano.shared(np_array, borrow=False)
s_true = theano.shared(np_array, borrow=True)
np_array += 1
print('s_default:',s_default.get_value())
print('s_false:',s_false.get_value())
print('s_true:',s_true.get_value())
输出:
s_default: [ 0. 0.]
s_false: [ 0. 0.]
s_true: [ 1. 1.]