Керас Плотный слой Выходная форма - PullRequest
3 голосов
/ 02 мая 2020

Я не могу понять логику c за получением выходной формы первого скрытого слоя. Я взял несколько произвольных примеров следующим образом:

Пример 1:

model.add(Dense(units=4,activation='linear',input_shape=(784,)))  
model.add(Dense(units=10,activation='softmax'))
model.summary()

Model: "sequential_4"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_7 (Dense)              (None, 4)                 3140      
_________________________________________________________________
dense_8 (Dense)              (None, 10)                50        
=================================================================
Total params: 3,190
Trainable params: 3,190
Non-trainable params: 0

Пример 2:

model.add(Dense(units=4,activation='linear',input_shape=(784,1)))   
model.add(Dense(units=10,activation='softmax'))
model.summary()
Model: "sequential_6"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_11 (Dense)             (None, 784, 4)            8         
_________________________________________________________________
dense_12 (Dense)             (None, 784, 10)           50        
=================================================================
Total params: 58
Trainable params: 58
Non-trainable params: 0

Пример 3:

model.add(Dense(units=4,activation='linear',input_shape=(32,28)))    
model.add(Dense(units=10,activation='softmax'))
model.summary()
Model: "sequential_8"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_15 (Dense)             (None, 32, 4)             116       
_________________________________________________________________
dense_16 (Dense)             (None, 32, 10)            50        
=================================================================
Total params: 166
Trainable params: 166
Non-trainable params: 0

Пример 4:

model.add(Dense(units=4,activation='linear',input_shape=(32,28,1)))    
model.add(Dense(units=10,activation='softmax'))
model.summary()
Model: "sequential_9"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_17 (Dense)             (None, 32, 28, 4)         8         
_________________________________________________________________
dense_18 (Dense)             (None, 32, 28, 10)        50        
=================================================================
Total params: 58
Trainable params: 58
Non-trainable params: 0

Пожалуйста, помогите мне понять логи c.

Кроме того, я думаю, что звания input_shape=(784,) и input_shape=(784,1) одинаковы тогда почему их Output Shape отличается?

Ответы [ 6 ]

2 голосов
/ 02 мая 2020

Логика c очень проста: плотный слой наносится независимо на последнее измерение предыдущего слоя. Следовательно, ввод формы (d1, ..., dn, d) через плотный слой с m единицами приводит к выводу формы (d1, ..., dn, m), а слой имеет параметры d*m+m (m смещения).

Примечание что одни и те же веса применяются независимо, поэтому ваш пример 4 работает следующим образом:

for i in range(32):
    for j in range(28):
        output[i, j, :] = input[i, j, :] @ layer.weights + layer.bias

Где @ - матричное умножение. input[i, j] - это вектор формы (1,), layer.weights имеет размер (1,4), а layer.bias - это вектор (1,).

Это также объясняет, почему (784,) и (784,1) дают разные результаты: их последние размеры разные, 784 и 1.

1 голос
/ 02 мая 2020

По Керасу

Dense layer is applied on the last axis independently. [1]

https://github.com/keras-team/keras/issues/10736#issuecomment -406589140

Первый пример:

input_shape=(784,)
model.add(Dense(units=4,activation='linear',input_shape=(784,)))

Это говорит о том, что вход имеет только 784 строки. И первый слой модели имеет 4 единицы. Каждый блок в плотном слое связан со всеми 784 рядами.

Именно поэтому

Output shape=  (None, 4) 

Ни один не представляет batch_size, который здесь не известен.

Второй пример

Здесь вводится тензор ранга 2

input_shape=(784,1)
Units = 4

Так что теперь ввод составляет 784 строки и 1 столбец. Теперь каждая единица плотного слоя связана с 1 элементом из каждого из 784 строк. Форма вывода = (Нет, 784, 4)
Нет для размера партии.

Третий пример

 input_shape=(32,28)

Теперь каждая единица плотного слоя подключена к 28 элементов от каждого из 32 рядов. Итак,

output_shape=(None,32,4)

Последний пример

model.add(Dense(units=4,activation='linear',input_shape=(32,28,1)))   

снова плотный слой наносится на последнюю ось и выходная форма становится

Output Shape =(None,32,28,4)

Примечание

ранг равен 1 при (784,) запятая не представляет другое измерение. ранг 2 при (784,1)

Диаграмма в stackcoverflow может помочь вам в дальнейшем.

1 голос
/ 02 мая 2020

keras - API высокого уровня, который заботится о многих абстракциях. Следующий пример может помочь вам лучше понять. Это наиболее близкий исходный эквивалент тензорного потока абстракции keras в вашем вопросе:

import tensorflow as tf
from pprint import pprint


for shape in [(None,784,), (None, 784,1), (None, 32,28), (None, 32,28,1)]:
    shapes_list = []

    input_layer_1 = tf.compat.v1.placeholder(dtype=tf.float32, shape=shape, name=None)
    shapes_list.append(input_layer_1.shape)
    d1 = tf.compat.v1.layers.dense(
        inputs=input_layer_1, units=4, activation=None, use_bias=True, kernel_initializer=None,
        bias_initializer=tf.zeros_initializer(), kernel_regularizer=None,
        bias_regularizer=None, activity_regularizer=None, kernel_constraint=None,
        bias_constraint=None, trainable=True, name=None, reuse=None
    )
    shapes_list.append(d1.shape)
    d2 = tf.compat.v1.layers.dense(
        inputs=d1, units=10, activation=tf.compat.v1.nn.softmax, use_bias=True, kernel_initializer=None,
        bias_initializer=tf.zeros_initializer(), kernel_regularizer=None,
        bias_regularizer=None, activity_regularizer=None, kernel_constraint=None,
        bias_constraint=None, trainable=True, name=None, reuse=None
    )
    shapes_list.append(d2.shape)
    print('++++++++++++++++++++++++++')
    pprint(shapes_list)
    print('++++++++++++++++++++++++++')

Функция Dense используется для создания плотно связанного слоя или Perceptron .

Согласно вашему фрагменту кода, вы создали многослойный персептрон (с функцией линейной активации f (x) = x) со скрытым слоем 1, имеющим 4 нейрона, и выходным слоем, настроенным для 10 классов / метки должны быть предсказаны.

Количество нейронов в каждом слое определяется аргументом единиц . И форма каждого нейрона в layer_L определяется выходом предыдущего layer_L-1 .

, если вход для плотного слоя равен (BATCH_SIZE, N, l), тогда форма вывода будет (BATCH_SIZE, N, value_passed_to_argument_units_in_Dense)

, а если ввод (BATCH_SIZE, N, M, l), то вывод будет (BATCH_SIZE, N, M, value_passed_to_argument_units_in_Dense) и т. д.

ПРИМЕЧАНИЕ:

это происходит только в случае Dense нейрона, потому что он не изменяет промежуточные измерения между batch_size и last_channel.

однако в случае других нейронов, таких как Conv2D -> (Max / При объединении промежуточные измерения могут (в зависимости от переданных аргументов) также измениться, потому что эти нейроны также действуют на эти измерения.

1 голос
/ 02 мая 2020

Форма вывода слоя зависит от типа используемого слоя. Например, выходная форма слоя Dense основана на units, определенной в слое, где выходная форма слоя Conv зависит от filters.

Еще одна вещь, которую нужно запомнить, по умолчанию, Последнее измерение любого входа рассматривается как номер канала. В процессе оценки выходной формы количество каналов заменяется на units, определенное в слое. Для одномерного ввода, такого как input_shape=(784,), важно использовать , в конце.

Пример 1 (одномерный), пример 2 (2-мерный, канал = 1), пример 3 (2 мерный, канал = 28) и пример 4 (трехмерный, канал = 1). Как упомянуто выше, последнее измерение заменено на units, определенное в слое Dense.

Более подробная информация об измерении, оси, канале, input_dim et c очень четко упоминается в этом stackoverflow ответ.

1 голос
/ 02 мая 2020

Согласно официальной документации Keras, для плотного слоя, когда вы вводите как input_shape=(input_units,), модальное значение принимает в качестве входных массивов форму (*, input_units) и выводит массивы формы (*, output_units) [в вашем случае input_shape=(784,) обрабатывается как input shape=(*, 784), а вывод - output_shape=(*,4)]

В общем случае для входного размера (batch_size, ..., input_dim) модальное значение дает размер (batch_size, ..., units).

Поэтому, когда вы задаете входные данные как input_shape=(784,), модальное значение принимается как входные массивы формы (*, 784), где * - размер пакета, а 784 - как input_dim, что дает выходную форму как (*, 4).

. Когда ввод (784,1), модал принимает его как (*, 784, 1), где * - размер пакета, 784 - ... и 1 - input_dim => (batch_size, ..., input_dim) и выводится как (*, 784, 4) = > (batch_size, ..., units).

То же самое относится к input_shape=(32,28)=>(*,32,28), дающему вывод (*,32,4) и для ввода с input_shape=(32,28,1)=>(*,32,28,1), где снова * - размер пакета, 32,28 - ... и 1 является input_dim => (batch_size, ..., input_dim)

О том, что означает None, пожалуйста, отметьте Что означает значение «None» в модели. КЕРАС?

1 голос
/ 02 мая 2020

Плотный слой требует ввода как (batch_size, input_size), большую часть времени мы пропускаем batch_size и определяем его во время обучения.

, если ваша форма ввода одномерна, в вашем первом случае (784, ) модель будет принимать в качестве входных массивов формы (~, 784) и выходных массивов формы (~, 4). По умолчанию будет добавлено смещение, равное 4 (начиная с 4 единиц). Таким образом, общие параметры будут

parameters -> 784*4 + 4 = 3140

, если ваша входная форма двумерная, во втором случае (784,1) модель примет как входные массивы формы (784,1) и выходной массив формы (None, 784,4). None - размер пакета. По умолчанию будет добавлено смещение, равное 4 (начиная с 4 единиц). Таким образом, общие параметры будут

parameters -> 4(output units) + 4(bias) = 8
...