新闻中心

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

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

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

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

X = np.vstack(df['Image'].values) / 255. # scale pixel values to [0, 1]

X = X.astype(np.float32)

if not test: # only FTRAIN has any target columns

y = df[df.columns[:-1]].values

y = (y - 48) / 48 # scale target coordinates to [-1, 1]

X, y = shuffle(X, y, random_state=42) # shuffle train data

y = y.astype(np.float32)

else:

y = None

return X, y

X, y = load()

print(X.shape == {}; X.min == {:.3f}; X.max == {:.3f}.format(

X.shape, X.min(), X.max()))

print(y.shape == {}; y.min == {:.3f}; y.max == {:.3f}.format(

y.shape, y.min(), y.max()))

你没有必要看懂这个函数的每一个细节。 但让我们看看上面的脚本输出:

$ python kfkd.py

left_eye_center_x 7034

left_eye_center_y 7034

right_eye_center_x 7032

right_eye_center_y 7032

left_eye_inner_corner_x 2266

left_eye_inner_corner_y 2266

left_eye_outer_corner_x 2263

left_eye_outer_corner_y 2263

right_eye_inner_corner_x 2264

right_eye_inner_corner_y 2264

mouth_right_corner_x 2267

mouth_right_corner_y 2267

mouth_center_top_lip_x 2272

mouth_center_top_lip_y 2272

mouth_center_bottom_lip_x 7014

mouth_center_bottom_lip_y 7014

Image 7044

dtype: int64

X.shape == (2140, 9216); X.min == 0.000; X.max == 1.000

y.shape == (2140, 30); y.min == -0.920; y.max == 0.996

首先,它打印出了CSV文件中所有列的列表以及每个列的可用值的数量。 因此,虽然我们有一个图像的训练数据中的所有行,我们对于mouth_right_corner_x只有个2,267的值等等。

load()返回一个元组(X,y),其中y是目标矩阵。 y的形状是n×m的,其中n是具有所有m个关键点的数据集中的样本数。 删除具有缺失值的所有行是这行代码的功能:

df = df.dropna() # drop all rows that have missing values in them

这个脚本输出的y.shape == (2140, 30)告诉我们,在数据集中只有2140个图像有着所有30个目标值。

一开始,我们将仅训练这2140个样本。 这使得我们比样本具有更多的输入大小(9,216); 过度拟合可能成为一个问题。当然,抛弃70%的训练数据也是一个坏主意。但是目前就这样,我们将在后面谈论。

第一个模型:一个单隐层

现在我们已经完成了加载数据的工作,让我们使用Lasagne并创建一个带有一个隐藏层的神经。 我们将从代码开始:

# add to kfkd.py

from lasagne import layers

from lasagne.updates import nesterov_momentum

from nolearn.lasagne import NeuralNet

net1 = NeuralNet(

layers=[ # three layers: one hidden layer

('input', layers.InputLayer),

('hidden', layers.DenseLayer),

('output', layers.DenseLayer),

],

# layer parameters:

input_shape=(None, 9216), # 96x96 input pixels per batch

hidden_num_units=100, # number of units in hidden layer

output_nonlinearity=None, # output layer uses identity function

output_num_units=30, # 30 target values

# optimization method:

update=nesterov_momentum,

update_learning_rate=0.01,

update_momentum=0.9,

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)

我们使用相当多的参数来初始化NeuralNet。让我们看看他们。首先是三层及其参数:

layers=[ # 三层神经:一个隐层

('input', layers.InputLayer),

('hidden', layers.DenseLayer),

('output', layers.DenseLayer),

],

# 层的参数:

input_shape=(None, 9216), # 每个批次96x96个输入样例

hidden_num_units=100, # 隐层中的单元数

output_nonlinearity=None, # 输出用的激活函数

output_num_units=30, # 30个目标值

这里我们定义输入层,隐藏层和输出层。在层参数中,我们命名并指定每个层的类型及其顺序。参数input_shape,hidden_??num_units,output_nonlinearity和output_num_units是特定层的参数。它们通过它们的前缀引用层,使得input_shape定义输入层的shape参数,hidden_??num_units定义隐藏层的num_units等等。(看起来有点奇怪,我们必须指定像这样的参数,但结果是它让我们对于受使用scikit-learn的管道和参数搜索功能拥有更好的兼容性。)

我们将input_shape的第一个维度设置为None。这转换为可变批量大小。如果你知道批量大小的话,也可以设置成固定值,如果为None,则是可变值。

我们将output_nonlinearity设置为None。因此,输出单元的激活仅仅是隐藏层中的激活的线性组合。

DenseLayer使用的默认非线性是rectifier,它其实就是返回max(0, x)。它是当今最受欢迎的激活功能选择。通过不明确设置hidden_??nonlinearity,我们选择rectifier作为我们隐藏层的激活函数。

神经的权重用具有巧妙选择的间隔的均匀分布来初始化。也就是说,Lasagne使用“Glorot-style”初始化来计算出这个间隔。

还有几个参数。 所有以update开头的参数用来表示更新方程(或最优化方法)的参数。 更新方程将在每个批次后更新我们网络的权重。 我们将使用涅斯捷罗夫动量梯度下降优化方法(nesterov_momentum gradient descent optimization method)来完成这项工作。Lasagne实现的其他方法有很多,如adagrad和rmsprop。我们选择nesterov_momentum,因为它已经证明对于大量的问题很好地工作。



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

评论


相关推荐

技术专区

关闭