Нейронная сеть указана с tf.layers, вставляя нежелательные операции изменения формы

Эта простая нейронная сеть определена в Python:

input_layer = tf.placeholder(tf.float32, shape=[1, 1, 8000, 1], name='input_layer')

# Convolutional Layer
conv = tf.layers.conv2d(
        inputs=input_layer,
        filters=32,
        kernel_size=[1,11],
        padding="same",
        strides=1,
        activation=tf.nn.relu)

# Output layer
logits = tf.layers.dense(inputs=conv, units=5, name='logit')

В результате получается следующая топология графа:

0 input_layer Placeholder
1 conv2d/kernel/Initializer/random_uniform/shape Const
2 conv2d/kernel/Initializer/random_uniform/min Const
3 conv2d/kernel/Initializer/random_uniform/max Const
4 conv2d/kernel/Initializer/random_uniform/RandomUniform RandomUniform
└─── Input0 ─ conv2d/kernel/Initializer/random_uniform/shape
5 conv2d/kernel/Initializer/random_uniform/sub Sub
└─── Input0 ─ conv2d/kernel/Initializer/random_uniform/max
└─── Input1 ─ conv2d/kernel/Initializer/random_uniform/min
6 conv2d/kernel/Initializer/random_uniform/mul Mul
└─── Input0 ─ conv2d/kernel/Initializer/random_uniform/RandomUniform
└─── Input1 ─ conv2d/kernel/Initializer/random_uniform/sub
7 conv2d/kernel/Initializer/random_uniform Add
└─── Input0 ─ conv2d/kernel/Initializer/random_uniform/mul
└─── Input1 ─ conv2d/kernel/Initializer/random_uniform/min
8 conv2d/kernel VariableV2
9 conv2d/kernel/Assign Assign
└─── Input0 ─ conv2d/kernel
└─── Input1 ─ conv2d/kernel/Initializer/random_uniform
10 conv2d/kernel/read Identity
└─── Input0 ─ conv2d/kernel
11 conv2d/bias/Initializer/zeros Const
12 conv2d/bias VariableV2
13 conv2d/bias/Assign Assign
└─── Input0 ─ conv2d/bias
└─── Input1 ─ conv2d/bias/Initializer/zeros
14 conv2d/bias/read Identity
└─── Input0 ─ conv2d/bias
15 conv2d/convolution/Shape Const
16 conv2d/convolution/dilation_rate Const
17 conv2d/convolution Conv2D
└─── Input0 ─ input_layer
└─── Input1 ─ conv2d/kernel/read
18 conv2d/BiasAdd BiasAdd
└─── Input0 ─ conv2d/convolution
└─── Input1 ─ conv2d/bias/read
19 conv2d/Relu Relu
└─── Input0 ─ conv2d/BiasAdd
20 logit/kernel/Initializer/random_uniform/shape Const
21 logit/kernel/Initializer/random_uniform/min Const
22 logit/kernel/Initializer/random_uniform/max Const
23 logit/kernel/Initializer/random_uniform/RandomUniform RandomUniform
└─── Input0 ─ logit/kernel/Initializer/random_uniform/shape
24 logit/kernel/Initializer/random_uniform/sub Sub
└─── Input0 ─ logit/kernel/Initializer/random_uniform/max
└─── Input1 ─ logit/kernel/Initializer/random_uniform/min
25 logit/kernel/Initializer/random_uniform/mul Mul
└─── Input0 ─ logit/kernel/Initializer/random_uniform/RandomUniform
└─── Input1 ─ logit/kernel/Initializer/random_uniform/sub
26 logit/kernel/Initializer/random_uniform Add
└─── Input0 ─ logit/kernel/Initializer/random_uniform/mul
└─── Input1 ─ logit/kernel/Initializer/random_uniform/min
27 logit/kernel VariableV2
28 logit/kernel/Assign Assign
└─── Input0 ─ logit/kernel
└─── Input1 ─ logit/kernel/Initializer/random_uniform
29 logit/kernel/read Identity
└─── Input0 ─ logit/kernel
30 logit/bias/Initializer/zeros Const
31 logit/bias VariableV2
32 logit/bias/Assign Assign
└─── Input0 ─ logit/bias
└─── Input1 ─ logit/bias/Initializer/zeros
33 logit/bias/read Identity
└─── Input0 ─ logit/bias
34 logit/Tensordot/transpose/perm Const
35 logit/Tensordot/transpose Transpose
└─── Input0 ─ conv2d/Relu
└─── Input1 ─ logit/Tensordot/transpose/perm
36 logit/Tensordot/Reshape/shape Const
37 logit/Tensordot/Reshape Reshape
└─── Input0 ─ logit/Tensordot/transpose
└─── Input1 ─ logit/Tensordot/Reshape/shape
38 logit/Tensordot/transpose_1/perm Const
39 logit/Tensordot/transpose_1 Transpose
└─── Input0 ─ logit/kernel/read
└─── Input1 ─ logit/Tensordot/transpose_1/perm
40 logit/Tensordot/Reshape_1/shape Const
41 logit/Tensordot/Reshape_1 Reshape
└─── Input0 ─ logit/Tensordot/transpose_1
└─── Input1 ─ logit/Tensordot/Reshape_1/shape
42 logit/Tensordot/MatMul MatMul
└─── Input0 ─ logit/Tensordot/Reshape
└─── Input1 ─ logit/Tensordot/Reshape_1
43 logit/Tensordot/shape Const
44 logit/Tensordot Reshape
└─── Input0 ─ logit/Tensordot/MatMul
└─── Input1 ─ logit/Tensordot/shape
45 logit/BiasAdd BiasAdd
└─── Input0 ─ logit/Tensordot
└─── Input1 ─ logit/bias/read

Какова цель операций изменения формы между узлами 36 и 44? Я работаю с механизмом нейронной обработки Snapdragon (SNPE), который не разрешает операции изменения формы. Есть ли способ выразить эту модель без изменения формы?

2 ответа

Решение

Все из этого reshape операции добавляются tf.tensordot, который используется tf.layers.dense для многомерных входов (в вашем случае 4D). Из его документации:

Примечание: если тензор входных данных имеет ранг больше 2, то он выравнивается до умножения исходной матрицы на ядро.

Ссылка на исходный код.

Если изменение формы нежелательно в вашей среде, попробуйте определить веса и смещения вручную и применить dot продукт через tf.matmul,

SNPE поддерживает reshape в v1.8.0

Другие вопросы по тегам