新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > 教程详解:用卷积神经网络检测脸部关键点(一)

教程详解:用卷积神经网络检测脸部关键点(一)

作者:时间:2018-08-03来源:网络收藏

本文引用地址:http://www.eepw.com.cn/article/201808/385311.htm

”’ optimization method: ””

update=nesterov_momentum,

update_learning_rate=0.01,

update_momentum=0.9,

update_learning_rate定义了梯度下降更新权重的步长。我们稍后讨论学习率和momentum参数,现在的话,这种健全的默认值已经足够了。

上图是不同的最优化方法的对比(animation by?Alec Radford)。星标位置为全局最优值。注意到不添加动量的随机梯度下降是收敛最慢的,我们在教程中从头到尾都是用Nesterov加速过的梯度下降。

在我们的NeuralNet的定义中,我们没有指定一个目标函数来实现最小化。这里使用的还有一个默认值:对于回归问题,它是均方误差(MSE)。

最后一组参数声明我们正在处理一个回归问题(而不是分类),400是我们愿意训练的时期数,并且我们想在训练期间通过设置verbose = 1:

regression=True, # flag to indicate we're dealing with regression problem

max_epochs=400, # we want to train this many epochs

verbose=1,

最后两行加载了数据,然后用数据训练了我们的第一个神经

X, y = load()

net1.fit(X, y)

运行这两行会输出一个表格,每次完成一代就输出一行。每一行里,我们可以看到当前的训练损失和验证损失(最小二乘损失),以及两者的比率。NeuroNet将会自动把输入数据X分成训练集和测试集,用20%的数据作验证。(比率可以通过参数eval_size=0.2调整)

$ python kfkd.py

...

InputLayer (None, 9216) produces 9216 outputs

DenseLayer (None, 100) produces 100 outputs

DenseLayer (None, 30) produces 30 outputs

Epoch | Train loss | Valid loss | Train / Val

--------|--------------|--------------|----------------

1 | 0.105418 | 0.031085 | 3.391261

2 | 0.020353 | 0.019294 | 1.054894

3 | 0.016118 | 0.016918 | 0.952734

4 | 0.014187 | 0.015550 | 0.912363

5 | 0.013329 | 0.014791 | 0.901199

...

200 | 0.003250 | 0.004150 | 0.783282

201 | 0.003242 | 0.004141 | 0.782850

202 | 0.003234 | 0.004133 | 0.782305

203 | 0.003225 | 0.004126 | 0.781746

204 | 0.003217 | 0.004118 | 0.781239

205 | 0.003209 | 0.004110 | 0.780738

...

395 | 0.002259 | 0.003269 | 0.690925

396 | 0.002256 | 0.003264 | 0.691164

397 | 0.002254 | 0.003264 | 0.690485

398 | 0.002249 | 0.003259 | 0.690303

399 | 0.002247 | 0.003260 | 0.689252

400 | 0.002244 | 0.003255 | 0.689606

在相对较快的上训练,我们能够在1分钟之内完成400个epoch的训练。注意测试损失会一直减小。(如果你训练得足够长时间,它将会有很小很小的改进)

现在我们有了一个很好的结果了么?我们看到测试误差是0.0032,和竞赛基准比试一下。记住我们将目标除以了48以将其缩放到-1到1之间,也就是说,要是想计算均方误差和排行榜的结果比较,必须把我们上面得到的0.003255还原到原来的尺度。

>>> import numpy as np

>>> np.sqrt(0.003255) * 48

2.7385251505144153

这个值应该可以代表我们的成绩了。当然,这得假设测试集合的数据和训练集合的数据符合相同的分布,但事实却并非如此。

测试

我们刚刚训练的net1对象已经保存了训练时打印在控制台桌面中的记录,我们可以获取这个记录通过train_history_相关属性,让我们画出这两个曲线。

train_loss = np.array([i[train_loss] for i in net1.train_history_])

valid_loss = np.array([i[valid_loss] for i in net1.train_history_])

pyplot.plot(train_loss, linewidth=3, label=train)

pyplot.plot(valid_loss, linewidth=3, label=valid)

pyplot.grid()

pyplot.legend()

pyplot.xlabel(epoch)

pyplot.ylabel(loss)

pyplot.ylim(1e-3, 1e-2)

pyplot.yscale(log)

pyplot.show()

我们能够看到我们的过拟合了,但是结果还不错。事实上,我们找不到验证错误开始上升的点,所以那种通常用来避免过拟合的early stopping方法在现在还没有什么用处。注意我们没有采用任何正则化手段,除了选择节点比较少的隐层——这可以让过拟合保持在可控范围内。

那么网络的预测结果是什么样的呢?让我们选择一些样例来看一看。

def plot_sample(x, y, axis):

img = x.reshape(96, 96)

axis.imshow(img, cmap='gray')

axis.scatter(y[0::2] * 48 + 48, y[1::2] * 48 + 48, marker='x', s=10)

X, _ = load(test=True)

y_pred = net1.predict(X)

fig = pyplot.figure(figsize=(6, 6))

fig.subplots_adjust(

left=0, right=1, bottom=0, top=1, hspace=0.05, wspace=0.05)

for i in range(16):

ax = fig.add_subplot(4, 4, i + 1, xticks=[], yticks=[])

plot_sample(X[i], y_pred[i], ax)

pyplot.show()

第一个模型预测的结果(从测试集抽出了16个样例)

预测结果看起来还不错,但是有点时候还是有一点偏。让我们试着做的更好一些。


上一页 1 2 3 下一页

关键词: 卷积神经 网络 GPU CPU

评论


相关推荐

技术专区

关闭