espressif / esp-dl

Espressif deep-learning library for AIoT applications
MIT License
548 stars 118 forks source link

S3上如何实现全连接层。 #45

Closed xiao-mb closed 3 years ago

xiao-mb commented 3 years ago

库里没看到全连接层的接口,请问如何实现?

yehangyang commented 3 years ago

Hi @xiao-mb 后续我们会添加全连接层。

目前,用户可以暂时使用 Conv2D 代替 全连接层。因为 ESP-DL 目前主要支持特征图的形状为(H,W,C),所以我假设你的全连接层的输入来自 Conv2D 的输出。有以下两种情况:

方法一:如果 Conv2D 的输出形状为(1,1,C),那么你可以用以下方法实现全连接层:

  1. 全连接层的 filter 形状应该是 (输入维度,输出维度)。在将 filter 导出到 npy 时,先用 numpy 将 filter 扩充或者 reshape 成 (1, 1, 输入维度, 输出维度)。
  2. 配置 config.json 将这一层的 "operation" 设置为 "conv2d" 即可。
  3. 在写 Model 时,将该层定义为 Conv2D。其中 padding_type 可设定为 PADDING_VALID。

方法二:如果 Conv2D 的输出形状为(H,W,C),其中 H!=1,W!=1,情况相对复杂一些:

  1. 全连接层的 filter 形状应该是 (输入维度,输出维度)。在将 filter 导出到 npy 时,先用 numpy 将 filter 扩充或者 reshape 成 (1, 1, 输入维度, 输出维度)。
  2. 不必在 config.json 中配置这一层。
  3. 在写 Model 时,不用定义这一层。
  4. 在 Model.call(...) 中, 本应该调用全连接层的地方,首先复制一份前面一层的输出,再重新定义其形状,最后调用 nn::conv2d,伪码如下:
    Tensor fcn_input(preview_output, true);
    fcn_input.set_shape({1,1,H*W*C});// 相当于 flatten
    fcn_output = nn::conv2d(...);

注意:

  1. 方法二可以涵盖方法二的情况
  2. 保证全连接的输入不会参与 Concat2D
  3. 保证全连接的输入作为其他层的输入时,不会发生 padding 的情况
  4. 仅限全连接层为最后一层
xiao-mb commented 3 years ago

如果全连接层的输入来自GlobalAveragePool2D的输出,要如何操作?

yehangyang commented 3 years ago

同 “输入来自 Conv2D”